diff --git a/README.md b/README.md index 691497f05..e980efa91 100644 --- a/README.md +++ b/README.md @@ -188,3 +188,7 @@ Technical differences from Minecraft: * `API.md`: For Minetest modders who want to mod this game * `LEGAL.md`: Legal information * `CREDITS.md`: List of everyone who contributed + +## Menu music + +* horizonchris96 — 02_what_we_ll_build_next diff --git a/menu/theme.ogg b/menu/theme.ogg new file mode 100644 index 000000000..375d3ada0 Binary files /dev/null and b/menu/theme.ogg differ diff --git a/mods/CORE/mcl_bubble_column/LICENSE b/mods/CORE/mcl_bubble_column/LICENSE deleted file mode 100644 index f288702d2..000000000 --- a/mods/CORE/mcl_bubble_column/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/mods/CORE/mcl_bubble_column/README.md b/mods/CORE/mcl_bubble_column/README.md deleted file mode 100644 index f56d30145..000000000 --- a/mods/CORE/mcl_bubble_column/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# mcl_bubble_column by j45 - -https://github.com/Minetest-j45/mcl_bubble_column/ - -Adds whirlpools and upwards bubble columns to Mineclone2/5 - -A bubble column is a block generated by placing magma blocks or soul sand in water (source). - -Bubble columns push or pull entities and items in certain directions. diff --git a/mods/CORE/mcl_bubble_column/init.lua b/mods/CORE/mcl_bubble_column/init.lua deleted file mode 100644 index ed3bcc5b3..000000000 --- a/mods/CORE/mcl_bubble_column/init.lua +++ /dev/null @@ -1,195 +0,0 @@ -mcl_bubble_column = {} - -minetest.register_abm{ - label = "bubbleColumnUpStop", - nodenames = {"group:water"}, - interval = 0.05, - chance = 1, - action = function(pos) - local meta = minetest.get_meta(pos) - if meta:get_int("bubbly") == 1 then--bubble column - --check down if current needs to be deleted - local downpos = vector.add(pos, {x = 0, y = -1, z = 0}) - local downposnode = minetest.get_node(downpos) - local downmeta = minetest.get_meta(downpos) - if (downmeta:get_int("bubbly") ~= 1 and downposnode.name ~= "mcl_nether:soul_sand") then - meta:set_int("bubbly", 0) - end - --check up to see if needs to go up - local uppos = vector.add(pos, {x = 0, y = 1, z = 0}) - local upposnode = minetest.get_node(uppos) - local upmeta = minetest.get_meta(uppos) - if (minetest.get_item_group(upposnode.name, "water") == 3 and upmeta:get_int("bubbly") ~= 1) then - upmeta:set_int("bubbly", 1) - end - elseif meta:get_int("whirly") == 1 then--whirlpool - --check down if current needs to be deleted - local downpos = vector.add(pos, {x = 0, y = -1, z = 0}) - local downposnode = minetest.get_node(downpos) - local downmeta = minetest.get_meta(downpos) - if (downmeta:get_int("whirly") ~= 1 and downposnode.name ~= "mcl_nether:magma") then - meta:set_int("whirly", 0) - end - --check up to see if needs to go up - local uppos = vector.add(pos, {x = 0, y = 1, z = 0}) - local upposnode = minetest.get_node(uppos) - local upmeta = minetest.get_meta(uppos) - if (minetest.get_item_group(upposnode.name, "water") == 3 and upmeta:get_int("whirly") ~= 1) then - upmeta:set_int("whirly", 1) - end - end - end, -} - -minetest.register_abm{ - label = "startBubbleColumn", - nodenames = {"mcl_nether:soul_sand"}, - interval = 0.05, - chance = 1, - action = function(pos) - local uppos = vector.add(pos, {x = 0, y = 1, z = 0}) - local upposnode = minetest.get_node(uppos) - local upmeta = minetest.get_meta(uppos) - if (minetest.get_item_group(upposnode.name, "water") == 3 and upmeta:get_int("bubbly") ~= 1) then - upmeta:set_int("bubbly", 1) - end - end, -} - -minetest.register_abm{ - label = "startWhirlpool", - nodenames = {"mcl_nether:magma"}, - interval = 0.05, - chance = 1, - action = function(pos) - local uppos = vector.add(pos, {x = 0, y = 1, z = 0}) - local upposnode = minetest.get_node(uppos) - local upmeta = minetest.get_meta(uppos) - if (minetest.get_item_group(upposnode.name, "water") == 3 and upmeta:get_int("whirly") ~= 1) then - upmeta:set_int("whirly", 1) - end - end, -} - - -mcl_bubble_column.on_enter_bubble_column = function(self) - local velocity = self:get_velocity() - --[[if down.name == "mcl_nether:soul_sand" then - self:add_velocity({x = 0, y = math.min(10, math.abs(velocity.y)+9.4), z = 0}) - else]] - self:add_velocity({x = 0, y = math.min(3.6, math.abs(velocity.y)+3), z = 0}) - --end -end - -mcl_bubble_column.on_enter_whirlpool = function(self) - local velocity = self:get_velocity() - --self:add_velocity({x = 0, y = math.max(-3, (-math.abs(velocity.y))-2), z = 0}) - self:add_velocity({x = 0, y = math.max(-0.3, (-math.abs(velocity.y))-0.03), z = 0}) -end - -mcl_bubble_column.on_enter_bubble_column_with_air_above = function(self) - local velocity = self:get_velocity() - --[[if down.name == "mcl_nether:soul_sand" then - self:add_velocity({x = 0, y = math.min(4.3, math.abs(velocity.y)+2.8), z = 0}) - else]] - self:add_velocity({x = 0, y = math.min(2.6, math.abs(velocity.y)+2), z = 0}) - --end -end - -mcl_bubble_column.on_enter_whirlpool_with_air_above = function(self) - local velocity = self:get_velocity() - --self:add_velocity({x = 0, y = math.max(-3.5, (-math.abs(velocity.y))-2), z = 0}) - self:add_velocity({x = 0, y = math.max(-0.9, (-math.abs(velocity.y))-0.03), z = 0}) -end - -minetest.register_abm{ - label = "entGo", - nodenames = {"group:water"}, - interval = 0.05, - chance = 1, - action = function(pos) - --if not bubble column block return - local meta = minetest.get_meta(pos) - if meta:get_int("bubbly") == 1 then - local up = minetest.get_node(vector.add(pos, {x = 0, y = 1, z = 0})) - for _,entity in pairs(minetest.get_objects_inside_radius(pos, 0.75)) do - if up.name == "air" then - mcl_bubble_column.on_enter_bubble_column_with_air_above(entity) - else - mcl_bubble_column.on_enter_bubble_column(entity) - end - end - elseif meta:get_int("whirly") == 1 then - local up = minetest.get_node(vector.add(pos, {x = 0, y = 1, z = 0})) - for _,entity in pairs(minetest.get_objects_inside_radius(pos, 0.75)) do - if up.name == "air" then - mcl_bubble_column.on_enter_whirlpool_with_air_above(entity) - else - mcl_bubble_column.on_enter_whirlpool(entity) - end - end - end - end, -} - -minetest.register_globalstep(function() - for _,player in ipairs(minetest.get_connected_players()) do - local ppos = player:get_pos() - local eyepos = {x = ppos.x, y = ppos.y + player:get_properties().eye_height, z = ppos.z} - local node = minetest.get_node(ppos) - local eyenode = minetest.get_node(eyepos) - local meta = minetest.get_meta(ppos) - local eyemeta = minetest.get_meta(eyepos) - - local eyemeta = minetest.get_meta(ppos) - --if minetest.get_item_group(node.name, "water") == 3 and minetest.get_item_group(eyenode.name, "water") == 3 then return end - if meta:get_int("bubbly") == 1 or eyemeta:get_int("bubbly") == 1 then - local up = minetest.get_node(vector.add(eyepos, {x = 0, y = 1, z = 0})) - if up.name == "air" then - mcl_bubble_column.on_enter_bubble_column_with_air_above(player) - else - mcl_bubble_column.on_enter_bubble_column(player) - end - elseif meta:get_int("whirly") == 1 or eyemeta:get_int("whirly") == 1 then - local up = minetest.get_node(vector.add(ppos, {x = 0, y = 1, z = 0})) - if up.name == "air" then - mcl_bubble_column.on_enter_whirlpool_with_air_above(player) - else - mcl_bubble_column.on_enter_whirlpool(player) - end - end - end -end) - ---abms to remove and replace old bubble columns/whirlpools -minetest.register_abm{ - label = "removeOldFlowingColumns", - nodenames = {"mcl_bubble_column:water_flowing_up", "mcl_bubble_column:water_flowing_down"}, - interval = 1,--reduce lag - chance = 1, - action = function(pos) - minetest.set_node(pos, {name = "air"}) - end, -} -minetest.register_abm{ - label = "replaceBubbleColumns", - nodenames = {"mcl_bubble_column:water_source_up"}, - interval = 1,--reduce lag - chance = 1, - action = function(pos) - minetest.set_node(pos, {name = "mcl_core:water_source"}) - local meta = minetest.get_meta(pos) - meta:set_int("bubbly", 1) - end, -} -minetest.register_abm{ - label = "replaceWhirlpools", - nodenames = {"mcl_bubble_column:water_source_down"}, - interval = 1,--reduce lag - chance = 1, - action = function(pos) - minetest.set_node(pos, {name = "mcl_core:water_source"}) - local meta = minetest.get_meta(pos) - meta:set_int("whirly", 1) - end, -} \ No newline at end of file diff --git a/mods/CORE/mcl_bubble_column/mod.conf b/mods/CORE/mcl_bubble_column/mod.conf deleted file mode 100644 index 9167bf062..000000000 --- a/mods/CORE/mcl_bubble_column/mod.conf +++ /dev/null @@ -1 +0,0 @@ -name = mcl_bubble_column \ No newline at end of file diff --git a/mods/CORE/mcl_mapgen/init.lua b/mods/CORE/mcl_mapgen/init.lua index f24d76880..4aca65f54 100644 --- a/mods/CORE/mcl_mapgen/init.lua +++ b/mods/CORE/mcl_mapgen/init.lua @@ -416,7 +416,7 @@ mcl_mapgen.bedrock_is_rough = normal overworld.min = -62 if superflat then mcl_mapgen.ground = tonumber(minetest.get_mapgen_setting("mgflat_ground_level")) or 8 - overworld.min = ground - 3 + overworld.min = mcl_mapgen.ground - 3 end -- if singlenode then mcl_mapgen.overworld.min = -66 end -- DONT KNOW WHY overworld.max = mcl_mapgen.EDGE_MAX diff --git a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua index 6da0d5a1a..cbbda43d5 100644 --- a/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua +++ b/mods/ENTITIES/mcl_mobs/api/mob_functions/ai.lua @@ -801,20 +801,6 @@ function mobs.mob_step(self, dtime) return false end - - --DEBUG TIME! - --REMEMBER TO MOVE THIS AFTER DEATH CHECK - - --if self.has_head then - -- mobs.do_head_logic(self,dtime) - --end - - - - --if true then--DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG DEBUG - -- return - --end - --despawn mechanism --don't despawned tamed or bred mobs if not self.tamed and not self.bred then @@ -833,7 +819,7 @@ function mobs.mob_step(self, dtime) self.object:set_texture_mod("^[colorize:red:120") --fix double death sound if self.health > 0 then - mobs.play_sound(self,"damage") + mobs.play_sound(self, "damage") end end self.old_health = self.health @@ -863,7 +849,7 @@ function mobs.mob_step(self, dtime) return end - mobs.random_sound_handling(self,dtime) + mobs.random_sound_handling(self, dtime) --mobs drowning mechanic if not self.breathes_in_water then @@ -893,14 +879,36 @@ function mobs.mob_step(self, dtime) end end + local pos = self.object:get_pos() + local node = minetest_get_node(pos).name + --water damage - if self.water_damage and self.water_damage ~= 0 then - local pos = self.object:get_pos() - local node = minetest_get_node(pos).name - if minetest_get_item_group(node, "water") ~= 0 then + if self.water_damage and self.water_damage ~= 0 and minetest_get_item_group(node, "water") ~= 0 then + self.water_counter = (self.water_counter or 0) + dtime + if self.water_counter >= 1 then mobs.smoke_effect(self) self.health = self.health - self.water_damage self:teleport() + self.water_counter = 0 + end + end + + --lava damage + local lava_damage = self.lava_damage + if lava_damage and lava_damage ~= 0 and minetest_get_item_group(node, "lava") ~= 0 then + self.lava_counter = (self.lava_counter or 0) + dtime + if self.lava_counter >= 1 then + minetest.sound_play("default_punch", { + object = self.object, + max_hear_distance = 5 + }, true) + self.object:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = self.lava_damage} + }, nil) + self.lava_counter = 0 + self.health = self.health - lava_damage + self:teleport() end end diff --git a/mods/HUD/mcl_credits/CONTRUBUTOR_LIST.txt b/mods/HUD/mcl_credits/CONTRUBUTOR_LIST.txt new file mode 100644 index 000000000..561952adc --- /dev/null +++ b/mods/HUD/mcl_credits/CONTRUBUTOR_LIST.txt @@ -0,0 +1,86 @@ +1798643961 +3raven +AFCMS +aldum +Alexander Minges +aligator +ArTee3 +Artem Arbatsky +basxto +Benjamin Schötz +Blue Blancmange +Booglejr +Brandon +Bu-Gee +bzoss +chmodsayshello +Code-Sploit +cora +Daniel Cassidy +davedevils +Dave Devil's +David McMackins II +dBeans +debiankaios +Dieter44 +Doloment +Elias Åström +Elias Fleckenstein +Emily +Emojigit +epCode +erlehmann +FinishedFragment +Glaucos Ginez +Gustavo Ramos Rehermann +Guy Liner +GuyLiner +HimbeerserverDE +iliekprogrammar +j1233 +Jared Moody +jordan4ibanez +kabou +kay27 +Laurent Rocher +Li0n +marcin-serwin +Marcin Serwin +Mental-Inferno +Midgard +MysticTempest +Nicholas Niro +nickolas360 +Nicu +nikolaus-albinger +Nils Dagsson Moskopp +NO11 +NO411 +Oil_boi +pitchum +PrairieAstronomer +PrairieWind +Rocher Laurent +rootyjr +Rootyjr +rudzik8 +Sab Pyrope +Saku Laesvuori +sfan5 +SmallJoker +superfloh247 +Sven792 +Sydney Gems +talamh +TechDudie +Thinking +Tianyang Zhang +U.N.Owen +Wouters Dorian +wuniversales +Wuzzy +Yukitty +yutyo +ZedekThePD +ZeDique la Ruleta +ztianyang diff --git a/mods/HUD/mcl_credits/README.md b/mods/HUD/mcl_credits/README.md new file mode 100644 index 000000000..3d76497d0 --- /dev/null +++ b/mods/HUD/mcl_credits/README.md @@ -0,0 +1,9 @@ +Please run the following command to update contributor list: + +```bash +# git log --pretty="%an" | sort | uniq >CONTRUBUTOR_LIST.txt +``` + +Please check that there is no error on execution, and `CONTRUBUTOR_LIST.txt` is updated. + +There should be contributor names, line by line. diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index db3ac8436..357a7fdde 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -1,10 +1,40 @@ local modname = minetest.get_current_modname() local S = minetest.get_translator(modname) +local contributors_file_name = minetest.get_modpath(modname) .. "/CONTRUBUTOR_LIST.txt" + +local file = io.open(contributors_file_name) +local contributors = {} +if not file then + minetest.log("error", "[" .. modname .. "] Can't read contributors from " .. contributors_file_name) +else + local contributor_list = file:read("*a") + file:close() + for contributor in contributor_list:gmatch("[^\r\n]+") do + table.insert(contributors, contributor) + end +end + mcl_credits = { players = {}, description = S("A faithful Open Source clone of Minecraft"), - people = dofile(minetest.get_modpath(modname) .. "/people.lua"), + people = { + {S("Creator of MineClone"), 0x0A9400, { + "davedevils", + }}, + {S("Creator of MineClone 2"), 0xFBF837, { + "Wuzzy", + }}, + {S("Creators of MineClone 5"), 0x52FF00, + contributors + }, + {S("Special thanks"), 0x00E9FF, { + "celeron55 for creating Minetest", + "Jordach for the jukebox music compilation from Big Freaking Dig", + "The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game", + "Notch and Jeb for being the major forces behind Minecraft", + }} + } } local function add_hud_element(def, huds, y) diff --git a/mods/HUD/mcl_credits/people.lua b/mods/HUD/mcl_credits/people.lua deleted file mode 100644 index babd64bcc..000000000 --- a/mods/HUD/mcl_credits/people.lua +++ /dev/null @@ -1,145 +0,0 @@ -local modname = minetest.get_current_modname() -local S = minetest.get_translator(modname) - -return { - {S("Creator of MineClone"), 0x0A9400, { - "davedevils", - }}, - {S("Creator of MineClone2"), 0xFBF837, { - "Wuzzy", - }}, - {S("Creator of MineClone5"), 0xFF51D5, { - S("The Community"), - }}, - {S("Developers"), 0xF84355, { - "Fleckenstein", - "kay27", - "oilboi", - "bzoss", - "AFCMS", - "epCode", - "ryvnf", - "iliekprogrammar", - "MysticTempest", - "Rootyjr", - "Nicu", - "aligator", - "Code-Sploit", - "NO11", - "cora", - }}, - {S("Contributors"), 0x52FF00, { - "Laurent Rocher", - "HimbeerserverDE", - "TechDudie", - "Alexander Minges", - "ArTee3", - "ZeDique la Ruleta", - "pitchum", - "wuniversales", - "Bu-Gee", - "David McMackins II", - "Nicholas Niro", - "Wouters Dorian", - "Blue Blancmange", - "Jared Moody", - "Li0n", - "Midgard", - "Saku Laesvuori", - "Yukitty", - "ZedekThePD", - "aldum", - "dBeans", - "nickolas360", - "yutyo", - "ztianyang", - "j45", - "Marcin Serwin", - "erlehmann", - "E", - "Benjamin Schötz", - "Doloment", - "Sydney Gems", - "talamh", - "Emily2255", - "Emojigit", - "FinishedFragment", - "sfan5", - "Blue Blancmange", - "Jared Moody", - "SmallJoker", - "Sven792", - "aldum", - }}, - {S("MineClone5"), 0xA60014, { - "kay27", - "Debiankaios", - "epCode", - "NO11", - "j45", - }}, - {S("Original Mod Authors"), 0x343434, { - "Wuzzy", - "Fleckenstein", - "BlockMen", - "TenPlus1", - "PilzAdam", - "ryvnf", - "stujones11", - "Arcelmi", - "celeron55", - "maikerumine", - "GunshipPenguin", - "Qwertymine3", - "Rochambeau", - "rubenwardy", - "stu", - "4aiman", - "Kahrl", - "Krock", - "UgnilJoZ", - "lordfingle", - "22i", - "bzoss", - "kilbith", - "xeranas", - "kddekadenz", - "sofar", - "4Evergreen4", - "jordan4ibanez", - "paramat", - }}, - {S("3D Models"), 0x0019FF, { - "22i", - "tobyplowy", - "epCode", - }}, - {S("Textures"), 0xFF9705, { - "XSSheep", - "Wuzzy", - "kingoscargames", - "leorockway", - "xMrVizzy", - "yutyo", - "NO11", - "kay27", - }}, - {S("Translations"), 0x00FF60, { - "Wuzzy", - "Rocher Laurent", - "wuniversales", - "kay27", - "pitchum", - "todoporlalibertad", - "Marcin Serwin", - }}, - {S("Funders"), 0xF7FF00, { - "40W", - }}, - {S("Special thanks"), 0x00E9FF, { - "celeron55 for creating Minetest", - "Jordach for the jukebox music compilation from Big Freaking Dig", - "The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game", - "Notch and Jeb for being the major forces behind Minecraft", - }}, -} diff --git a/mods/HUD/mcl_credits/textures/mineclone2_logo.png b/mods/HUD/mcl_credits/textures/mineclone2_logo.png index 11435df51..f95e425b9 100644 Binary files a/mods/HUD/mcl_credits/textures/mineclone2_logo.png and b/mods/HUD/mcl_credits/textures/mineclone2_logo.png differ diff --git a/mods/HUD/mcl_info/init.lua b/mods/HUD/mcl_info/init.lua new file mode 100644 index 000000000..02af53fbc --- /dev/null +++ b/mods/HUD/mcl_info/init.lua @@ -0,0 +1,105 @@ +local refresh_interval = .63 +local huds = {} +local default_debug = 3 +local after = minetest.after +local get_connected_players = minetest.get_connected_players +local get_biome_name = minetest.get_biome_name +local get_biome_data = minetest.get_biome_data +local format = string.format + +local min1, min2, min3 = mcl_mapgen.overworld.min, mcl_mapgen.end_.min, mcl_mapgen.nether.min +local max1, max2, max3 = mcl_mapgen.overworld.max, mcl_mapgen.end_.max, mcl_mapgen.nether.max + 128 + +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) +local storage = minetest.get_mod_storage() +local player_dbg = minetest.deserialize(storage:get_string("player_dbg") or "return {}") or {} + +local function get_text(pos, bits) + local bits = bits + if bits == 0 then return "" end + local y = pos.y + if y >= min1 then + y = y - min1 + elseif y >= min3 and y <= max3 then + y = y - min3 + elseif y >= min2 and y <= max2 then + y = y - min2 + end + local biome_data = get_biome_data(pos) + local biome_name = biome_data and get_biome_name(biome_data.biome) or "No biome" + local text + if bits == 1 then + text = biome_name + elseif bits == 2 then + text = format("x:%.1f y:%.1f z:%.1f", pos.x, y, pos.z) + elseif bits == 3 then + text = format("%s x:%.1f y:%.1f z:%.1f", biome_name, pos.x, y, pos.z) + end + return text +end + +local function info() + for _, player in pairs(get_connected_players()) do + local name = player:get_player_name() + local pos = player:get_pos() + local text = get_text(pos, player_dbg[name] or default_debug) + local hud = huds[name] + if not hud then + local def = { + hud_elem_type = "text", + alignment = {x = 1, y = -1}, + scale = {x = 100, y = 100}, + position = {x = 0.0073, y = 0.989}, + text = text, + style = 5, + ["number"] = 0xcccac0, + z_index = 0, + } + local def_bg = table.copy(def) + def_bg.offset = {x = 2, y = 1} + def_bg["number"] = 0 + def_bg.z_index = -1 + huds[name] = { + player:hud_add(def), + player:hud_add(def_bg), + text, + } + elseif text ~= hud[3] then + hud[3] = text + player:hud_change(huds[name][1], "text", text) + player:hud_change(huds[name][2], "text", text) + end + end + after(refresh_interval, info) +end + +minetest.register_on_authplayer(function(name, ip, is_success) + if is_success then + huds[name] = nil + end +end) + +minetest.register_chatcommand("debug",{ + description = S("Set debug bit mask: 0 = disable, 1 = biome name, 2 = coordinates, 3 = all"), + func = function(name, params) + local dbg = math.floor(tonumber(params) or default_debug) + if dbg < 0 or dbg > 3 then + minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", 0, 3)) + return + end + if dbg == default_dbg then + player_dbg[name] = nil + else + player_dbg[name] = dbg + end + minetest.chat_send_player(name, S("Debug bit mask set to @1", dbg)) + end +}) + +minetest.register_on_shutdown(function() + storage:set_string("player_dbg", minetest.serialize(player_dbg)) +end) + +info() diff --git a/mods/HUD/mcl_info/locale/mcl_info.ru.tr b/mods/HUD/mcl_info/locale/mcl_info.ru.tr new file mode 100644 index 000000000..7f5b79fe1 --- /dev/null +++ b/mods/HUD/mcl_info/locale/mcl_info.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Установка отладочной битовой маски: 0 @= отключить, 1 @= биом, 2 @= координаты, 3 @= всё +Error! Possible values are integer numbers from @1 to @2=Ошибка! Допустимые значения - целые числа от @1 до @2 +Debug bit mask set to @1=Отладочной битовой маске присвоено значение @1 diff --git a/mods/HUD/mcl_info/locale/template.txt b/mods/HUD/mcl_info/locale/template.txt new file mode 100644 index 000000000..1a0b70ebc --- /dev/null +++ b/mods/HUD/mcl_info/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all= +Error! Possible values are integer numbers from @1 to @2= +Debug bit mask set to @1= diff --git a/mods/HUD/mcl_info/mod.conf b/mods/HUD/mcl_info/mod.conf new file mode 100644 index 000000000..da3e10fff --- /dev/null +++ b/mods/HUD/mcl_info/mod.conf @@ -0,0 +1,3 @@ +name = mcl_info +description = Prints biome name and player position +optional_depends = mcl_mapgen diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua index db8eb75a2..c7c3151f7 100644 --- a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua @@ -4,7 +4,6 @@ local table = table mesecon.mvps_stoppers = {} mesecon.mvps_unsticky = {} -mesecon.mvps_droppers = {} mesecon.on_mvps_move = {} mesecon.mvps_unmov = {} @@ -17,24 +16,6 @@ function mesecon.is_mvps_unmov(objectname) return mesecon.mvps_unmov[objectname] end -function mesecon.is_mvps_dropper(node, pushdir, stack, stackid) - local get_dropper = mesecon.mvps_droppers[node.name] - if type (get_dropper) == "function" then - get_dropper = get_dropper(node, pushdir, stack, stackid) - end - if not get_dropper then - get_dropper = minetest.get_item_group(node.name, "dig_by_piston") == 1 - end - return get_dropper -end - -function mesecon.register_mvps_dropper(nodename, get_dropper) - if get_dropper == nil then - get_dropper = true - end - mesecon.mvps_droppers[nodename] = get_dropper -end - -- Nodes that cannot be pushed / pulled by movestones, pistons function mesecon.is_mvps_stopper(node) -- unknown nodes are always stoppers @@ -220,19 +201,13 @@ end function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, piston_pos) local nodes, has_loop = mesecon.mvps_get_stack(pos, movedir, maximum, piston_pos) - if has_loop then - return false - end - - if not nodes then return end + if has_loop or not nodes then return end local newpos={} -- check node availability to push/pull into, and fill newpos[i] for i in ipairs(nodes) do newpos[i] = vector.add(nodes[i].pos, movedir) - if (newpos[i].x == piston_pos.x) and (newpos[i].y == piston_pos.y) and (newpos[i].z == piston_pos.z) then - return - end + if (newpos[i].x == piston_pos.x) and (newpos[i].y == piston_pos.y) and (newpos[i].z == piston_pos.z) then return end if not is_available(newpos[i]) then local available = false for j in ipairs(nodes) do @@ -243,23 +218,18 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, end end end - if not available then - return - end + if not available then return end end end - if are_protected(nodes, player_name) then - return - end + if are_protected(nodes, player_name) then return end local first_dropper = nil -- remove all nodes for id, n in ipairs(nodes) do n.meta = minetest.get_meta(n.pos):to_table() - local is_dropper = mesecon.is_mvps_dropper(n.node, movedir, nodes, id) + local is_dropper = minetest.get_item_group(n.node.name, "dig_by_piston") == 1 if is_dropper then - --local drops = minetest.get_node_drops(n.node.name, "") minetest.dig_node(n.pos) else minetest.remove_node(n.pos) diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index 0e0f71a11..75314cf9f 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -10,67 +10,133 @@ local WATER_VISC = 1 local LAVA_VISC = 7 local LIGHT_LAVA = minetest.LIGHT_MAX local USE_TEXTURE_ALPHA = true +local BUBBLE_COLUMN_SPEED = 1 +local BUBBLE_ABM_INTERVAL = 2 +local BUBBLE_AMOUNT = math.floor(BUBBLE_ABM_INTERVAL / math.abs(BUBBLE_COLUMN_SPEED) + 0.5) if minetest.features.use_texture_alpha_string_modes then USE_TEXTURE_ALPHA = "blend" end -minetest.register_node("mcl_core:water_flowing", { - description = S("Flowing Water"), - _doc_items_create_entry = false, - wield_image = "default_water_flowing_animated.png^[verticalframe:64:0", - drawtype = "flowingliquid", - tiles = {"default_water_flowing_animated.png^[verticalframe:64:0"}, - special_tiles = { - { - image="default_water_flowing_animated.png", - backface_culling=false, - animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} - }, - { - image="default_water_flowing_animated.png", - backface_culling=false, - animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} - }, - }, - sounds = mcl_sounds.node_sound_water_defaults(), - is_ground_content = false, - use_texture_alpha = USE_TEXTURE_ALPHA, - paramtype = "light", - paramtype2 = "flowingliquid", - walkable = false, - pointable = false, - diggable = false, - buildable_to = true, - drop = "", - drowning = 4, - liquidtype = "flowing", - liquid_alternative_flowing = "mcl_core:water_flowing", - liquid_alternative_source = "mcl_core:water_source", - liquid_viscosity = WATER_VISC, - liquid_range = 7, - post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, - groups = { water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1, dig_by_piston=1}, - _mcl_blast_resistance = 100, - -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode - _mcl_hardness = -1, -}) +function mcl_core.register_liquid(def) + local base_name = def.base_name + local description_flowing = def.description_flowing + local description_source = def.description_source + local _doc_items_entry_name = def._doc_items_entry_name + local _doc_items_longdesc = def._doc_items_longdesc + local wield_image = def.wield_image + local tiles_flowing = def.tiles_flowing + local tiles_source = def.tiles_source + local special_tiles_flowing = def.special_tiles_flowing + local special_tiles_source = def.special_tiles_source + local sounds = def.sounds + local use_texture_alpha = def.use_texture_alpha + local drowning = def.drowning + local liquid_viscosity = def.liquid_viscosity + local liquid_range = def.liquid_range + local post_effect_color = def.post_effect_color + local groups = def.groups -minetest.register_node("mcl_core:water_source", { - description = S("Water Source"), + local source_node_name = string.format("mcl_core:%s_source", base_name) + local flowing_node_name = string.format("mcl_core:%s_flowing", base_name) + local mandatory_liquid_groups = {liquid=3, not_in_creative_inventory=1, dig_by_piston=1} + for group_id, group_level in pairs(mandatory_liquid_groups) do + if not groups[group_id] then + groups[group_id] = group_level + elseif groups[group_id] == false then + groups[group_id] = nil + end + end + minetest.register_node(flowing_node_name, { + description = description_flowing, + _doc_items_create_entry = false, + wield_image = wield_image, + drawtype = "flowingliquid", + tiles = tiles_flowing, + special_tiles = special_tiles_flowing, + sounds = sounds, + is_ground_content = false, + use_texture_alpha = use_texture_alpha, + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = drowning, + liquidtype = "flowing", + liquid_alternative_flowing = flowing_node_name, + liquid_alternative_source = source_node_name, + liquid_viscosity = liquid_viscosity, + liquid_range = liquid_range, + post_effect_color = post_effect_color, + groups = groups, + _mcl_blast_resistance = 100, + -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode + _mcl_hardness = -1, + }) + + minetest.register_node(source_node_name, { + description = description_source, + _doc_items_entry_name = _doc_items_entry_name, + _doc_items_longdesc = _doc_items_longdesc, + _doc_items_hidden = false, + drawtype = "liquid", + tiles = tiles_source, + special_tiles = special_tiles_source, + sounds = sounds, + is_ground_content = false, + use_texture_alpha = use_texture_alpha, + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = drowning, + liquidtype = "source", + liquid_alternative_flowing = flowing_node_name, + liquid_alternative_source = source_node_name, + liquid_viscosity = liquid_viscosity, + liquid_range = liquid_range, + post_effect_color = post_effect_color, + stack_max = 64, + groups = groups, + _mcl_blast_resistance = 100, + -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode + _mcl_hardness = -1, + }) +end + +mcl_core.register_liquid({ + base_name = "water", + description_flowing = S("Flowing Water"), + description_source = S("Water Source"), _doc_items_entry_name = S("Water"), - _doc_items_longdesc = -S("Water is abundant in oceans and also appears in a few springs in the ground. You can swim easily in water, but you need to catch your breath from time to time.").."\n\n".. -S("Water interacts with lava in various ways:").."\n".. -S("• When water is directly above or horizontally next to a lava source, the lava turns into obsidian.").."\n".. -S("• When flowing water touches flowing lava either from above or horizontally, the lava turns into cobblestone.").."\n".. -S("• When water is directly below lava, the water turns into stone."), - _doc_items_hidden = false, - drawtype = "liquid", - tiles = { - {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} + _doc_items_longdesc = + S("Water is abundant in oceans and also appears in a few springs in the ground. You can swim easily in water, but you need to catch your breath from time to time.").."\n\n".. + S("Water interacts with lava in various ways:").."\n".. + S("• When water is directly above or horizontally next to a lava source, the lava turns into obsidian.").."\n".. + S("• When flowing water touches flowing lava either from above or horizontally, the lava turns into cobblestone.").."\n".. + S("• When water is directly below lava, the water turns into stone."), + wield_image = "default_water_flowing_animated.png^[verticalframe:64:0", + tiles_flowing = {"default_water_flowing_animated.png^[verticalframe:64:0"}, + tiles_source = {{name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}}}, + special_tiles_flowing = { + { + image="default_water_flowing_animated.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} + }, + { + image="default_water_flowing_animated.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} + }, }, - special_tiles = { + special_tiles_source = { -- New-style water source material (mostly unused) { name="default_water_source_animated.png", @@ -78,29 +144,94 @@ S("• When water is directly below lava, the water turns into stone."), backface_culling = false, } }, - sounds = mcl_sounds.node_sound_water_defaults(), - is_ground_content = false, - use_texture_alpha = USE_TEXTURE_ALPHA, - paramtype = "light", - walkable = false, - pointable = false, - diggable = false, - buildable_to = true, - drop = "", - drowning = 4, - liquidtype = "source", - liquid_alternative_flowing = "mcl_core:water_flowing", - liquid_alternative_source = "mcl_core:water_source", - liquid_viscosity = WATER_VISC, - liquid_range = 7, - post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, - stack_max = 64, - groups = { water=3, liquid=3, puts_out_fire=1, freezes=1, not_in_creative_inventory=1, dig_by_piston=1}, - _mcl_blast_resistance = 100, - -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode - _mcl_hardness = -1, + sounds = mcl_sounds.node_sound_water_defaults(), + use_texture_alpha = USE_TEXTURE_ALPHA, + drowning = 4, + liquid_viscosity = WATER_VISC, + liquid_range = 7, + post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, + groups = {water=3, puts_out_fire=1, freezes=1, melt_around=1}, }) +mcl_core.register_liquid({ + base_name = "whirlpool", + description_flowing = S("Flowing Water"), + description_source = S("Whirlpool"), + _doc_items_entry_name = S("Water"), + _doc_items_longdesc = + S("A whirlpool, or downward bubble column, is originating from magma at the bottom of underwater canyons.").."\n".. + S("They drag entities downward."), + wield_image = "default_water_flowing_animated.png^[verticalframe:64:0", + tiles_flowing = {"default_water_flowing_animated.png^[verticalframe:64:0"}, + tiles_source = {{name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}}}, + special_tiles_flowing = { + { + image="default_water_flowing_animated.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} + }, + { + image="default_water_flowing_animated.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} + }, + }, + special_tiles_source = { + { + name="default_water_source_animated.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}, + backface_culling = false, + } + }, + sounds = mcl_sounds.node_sound_water_defaults(), + use_texture_alpha = USE_TEXTURE_ALPHA, + drowning = 0, + liquid_viscosity = WATER_VISC, + liquid_range = 7, + post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, + groups = {puts_out_fire=1, freezes=1, melt_around=1}, +}) + +mcl_core.register_liquid({ + base_name = "bubble_column", + description_flowing = S("Flowing Water"), + description_source = S("Bubble Column"), + _doc_items_entry_name = S("Water"), + _doc_items_longdesc = + S("A bubble column is generated above soul sand.").."\n".. + S("It accelerates entities upward."), + wield_image = "default_water_flowing_animated.png^[verticalframe:64:0", + tiles_flowing = {"default_water_flowing_animated.png^[verticalframe:64:0"}, + tiles_source = {{name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}}}, + special_tiles_flowing = { + { + image="default_water_flowing_animated.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} + }, + { + image="default_water_flowing_animated.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} + }, + }, + special_tiles_source = { + { + name="default_water_source_animated.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}, + backface_culling = false, + } + }, + sounds = mcl_sounds.node_sound_water_defaults(), + use_texture_alpha = USE_TEXTURE_ALPHA, + drowning = 0, + liquid_viscosity = WATER_VISC, + liquid_range = 7, + post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, + groups = {puts_out_fire=1, freezes=1, melt_around=1}, +}) + + minetest.register_node("mcl_core:lava_flowing", { description = S("Flowing Lava"), _doc_items_create_entry = false, @@ -243,3 +374,58 @@ if minetest.settings:get("mcl_node_particles") == "full" then end, }) end + +--if minetest.settings:get("mcl_node_particles") ~= "none" then + local nether_node_to_check = { + ["mcl_core:whirlpool_source"] = "mcl_nether:magma", + ["mcl_core:bubble_column_source"] = "mcl_nether:soul_sand", + } + local nether_node_offset_y = { + ["mcl_core:whirlpool_source"] = 0.5, + ["mcl_core:bubble_column_source"] = -0.5, + } + local nether_node_speed_y = { + ["mcl_core:whirlpool_source"] = -BUBBLE_COLUMN_SPEED, + ["mcl_core:bubble_column_source"] = BUBBLE_COLUMN_SPEED, + } + minetest.register_abm({ + label = "Process bubble columns and whirlpools", + nodenames = {"mcl_core:whirlpool_source", "mcl_core:bubble_column_source"}, + interval = BUBBLE_ABM_INTERVAL, + chance = 1, + catch_up = false, + action = function(pos, node) + local x, y, z, name = pos.x, pos.y, pos.z, node.name + local check = nether_node_to_check[name] + local below = minetest.get_node({x = x, y = y - 1, z = z}).name + if below ~= name and below ~= check then + minetest.swap_node(pos, {name = "mcl_core:water_source"}) + return + end + local upper_pos = {x = x, y = y + 1, z = z} + local upper = minetest.get_node(upper_pos).name + if upper == "mcl_core:water_source" then + minetest.swap_node(upper_pos, {name = name}) + end + local offset_y, speed_y = nether_node_offset_y[name], nether_node_speed_y[name] + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 12)) do + if obj:is_player() then + minetest.add_particlespawner({ + amount = BUBBLE_AMOUNT, + minpos = {x = x - 0.2, y = y + offset_y, z = z - 0.2}, + maxpos = {x = x + 0.2, y = y + offset_y, z = z + 0.2}, + minvel = {x = 0 , y = speed_y, z = 0 }, + maxvel = {x = 0 , y = speed_y, z = 0 }, + minexptime = 0.95 / BUBBLE_COLUMN_SPEED, + maxexptime = 1.05 / BUBBLE_COLUMN_SPEED, + minsize = 0.6, + maxsize = 1.9, + collisiondetection = false, + texture = "mcl_core_bubble.png", + playername = obj:get_player_name(), + }) + end + end + end, + }) +--end diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_bubble.png b/mods/ITEMS/mcl_core/textures/mcl_core_bubble.png new file mode 100644 index 000000000..083d6707c Binary files /dev/null and b/mods/ITEMS/mcl_core/textures/mcl_core_bubble.png differ diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index c5e39f753..2d6fbcecc 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -167,7 +167,6 @@ minetest.register_node("mcl_nether:soul_sand", { sounds = mcl_sounds.node_sound_sand_defaults(), _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, - -- Movement handling is done in mcl_playerplus mod }) minetest.register_node("mcl_nether:nether_brick", { @@ -418,3 +417,23 @@ minetest.register_craft({ dofile(minetest.get_modpath(minetest.get_current_modname()).."/nether_wart.lua") dofile(minetest.get_modpath(minetest.get_current_modname()).."/lava.lua") + +local bubble_generation_schema = { + ["mcl_nether:soul_sand"] = "mcl_core:bubble_column_source", + ["mcl_nether:magma"] = "mcl_core:whirlpool_source", +} + +minetest.register_abm({ + label = "Make whirlpools and bubble columns", + nodenames = {"mcl_nether:soul_sand", "mcl_nether:magma"}, + neighbors = {"mcl_core:water_source"}, + interval = 2, + chance = 1, + action = function(pos, node) + local pos_above = {x = pos.x, y = pos.y + 1, z = pos.z} + local above_node_name = minetest.get_node(pos_above).name + if above_node_name ~= "mcl_core:water_source" then return end + local new_above_node_name = bubble_generation_schema[node.name] + minetest.swap_node(pos_above, {name = new_above_node_name}) + end, +}) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 3f2f819c8..883f6e4fc 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -746,6 +746,13 @@ minetest.register_abm({ return end + if lower_node_name == OBSIDIAN and pos.y >= mcl_mapgen.overworld.min and random(1, 200) == 19 then + local pigman_obj = minetest.add_entity(pos, "mobs_mc:pigman") + if pigman_obj then + teleport_cooloff(pigman_obj) + end + end + local o = node.param2 -- orientation local closer_node_name = get_node({x = pos.x - 1 + o, y = pos.y, z = pos.z - o}).name diff --git a/mods/ITEMS/mcl_shields/init.lua b/mods/ITEMS/mcl_shields/init.lua index 65ffc6b4b..feff76cd8 100644 --- a/mods/ITEMS/mcl_shields/init.lua +++ b/mods/ITEMS/mcl_shields/init.lua @@ -155,10 +155,13 @@ local function modify_shield(player, vpos, vrot, i) if i == 1 then arm = "Left" end - local shield = mcl_shields.players[player].shields[i] - if shield then - shield:set_attach(player, "Arm_" .. arm, vpos, vrot, false) - end + local player_data = mcl_shields.players[player] + if not player_data then return end + local shields = player_data.shields + if not shields then return end + local shield = shields[i] + if not shield then return end + shield:set_attach(player, "Arm_" .. arm, vpos, vrot, false) end local function set_shield(player, block, i) diff --git a/mods/ITEMS/mcl_throwing/register.lua b/mods/ITEMS/mcl_throwing/register.lua index ec11f86c7..605ee1386 100644 --- a/mods/ITEMS/mcl_throwing/register.lua +++ b/mods/ITEMS/mcl_throwing/register.lua @@ -139,6 +139,7 @@ local function egg_on_step(self, dtime) -- Turn given object into a child local function make_child(object) + if not object then return end local ent = object:get_luaentity() object:set_properties({ visual_size = { x = ent.base_size.x/2, y = ent.base_size.y/2 }, diff --git a/mods/PLAYER/mcl_anticheat/init.lua b/mods/PLAYER/mcl_anticheat/init.lua index f4a3ac909..bd76e2818 100644 --- a/mods/PLAYER/mcl_anticheat/init.lua +++ b/mods/PLAYER/mcl_anticheat/init.lua @@ -13,6 +13,7 @@ local find_nodes_in_area = minetest.find_nodes_in_area local ceil = math.ceil local floor = math.floor +local vector_length = vector.length local distance = vector.distance @@ -20,6 +21,10 @@ local window_size = 8 local detection_interval = 1.6 local step_seconds = detection_interval / window_size local joined_players = {} +local ip_to_players = {} +local player_name_to_ip = {} +local player_doesnt_move = {} +local ban_next_time = {} local function update_settings() enable_anticheat = minetest.settings:get_bool("enable_anticheat", true) @@ -58,9 +63,15 @@ local function update_player(player_object) local noclip = #find_nodes_in_area({x = x, y = head_y, z = z}, {x = x + 1, y = head_y + 1, z = z + 1}, "group:opaque") == 8 + local velocity = player_object:get_velocity() + if vector_length(velocity) < 0.00000001 then + player_doesnt_move[name] = (player_doesnt_move[name] or 0) + 1 + else + player_doesnt_move[name] = 0 + end local player_data = { pos = pos, - velocity = player_object:get_velocity(), + velocity = velocity, air = air, noclip = noclip, } @@ -142,7 +153,24 @@ local function remove_player(player_object) if not player_object then return end local name = player_object:get_player_name() if not name then return end + local ip = player_name_to_ip[name] + player_name_to_ip[name] = nil + if ip then + local players = ip_to_players[ip] + if players then + for k, v in pairs(players) do + if v == name then + if k < #players then + players[k] = players[#players] + end + players[#players] = nil + break + end + end + end + end minetest.after(step_seconds, function() + player_doesnt_move[name] = nil joined_players[name] = nil end) end @@ -154,6 +182,50 @@ local function step() check_player(player:get_player_name()) end end + for ip, players in pairs(ip_to_players) do + if #players > 2 then + local first = players[1] + local should_be_banned = ban_next_time[ip] + if #players < 6 then + for _, player_name in pairs(players) do + if (player_doesnt_move[player_name] or 0) > 1800/step_seconds then + minetest.kick_player(player_name, "Didn't move during 30 minutes, more than 2 connections from IP " .. ip) + end + end + elseif #players < 10 then + for _, player_name in pairs(players) do + if (player_doesnt_move[player_name] or 0) > 600/step_seconds then + minetest.kick_player(player_name, "Didn't move during 10 minutes, more than 5 connections from IP " .. ip) + end + end + elseif #players < 26 then + if should_be_banned then + minetest.chat_send_all("Player " .. first .. " has been banned for having more than 9 connections at once") + minetest.ban_player(first) + else + for _, player_name in pairs(players) do + if (player_doesnt_move[player_name] or 0) > 90/step_seconds then + minetest.kick_player(player_name, "Didn't move during 1.5 minutes being connected multiple times") + ban_next_time[ip] = 1 + end + end + end + elseif #players <= 100 then + if should_be_banned then + minetest.ban_player(first) + minetest.chat_send_all("Player " .. first .. " has been banned for having more than 25 connections at once") + else + for _, player_name in pairs(players) do + minetest.kick_player(player_name, "More than 25 connections from IP address " .. ip) + end + ban_next_time[ip] = 1 + end + else + minetest.ban_player(first) + minetest.chat_send_all("Player " .. first .. " has been banned for having more than 100 connections at once") + end + end + end after(step_seconds, step) end @@ -203,4 +275,15 @@ minetest.register_on_joinplayer(update_player) minetest.register_on_leaveplayer(remove_player) +minetest.register_on_authplayer(function(name, ip, is_success) + if not is_success then return end + local players = ip_to_players[ip] + if not players then + ip_to_players[ip] = {name} + else + players[#players + 1] = name + end + player_name_to_ip[name] = ip +end) + after(step_seconds, step) diff --git a/mods/PLAYER/mcl_music/mod.conf b/mods/PLAYER/mcl_music/mod.conf index e36fb6f9b..74493b42d 100644 --- a/mods/PLAYER/mcl_music/mod.conf +++ b/mods/PLAYER/mcl_music/mod.conf @@ -1,4 +1,4 @@ name = mcl_music -author = diminixed, kay27 +author = diminixed, horizonchris96, kay27 description = Mod check some conditions and plays music depends = mcl_player, mcl_weather, mcl_worlds diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index c7fd5b2b7..bdd2748b7 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -19,12 +19,15 @@ local playerphysics = playerphysics local vector = vector local math = math +local math_min = math.min -- Internal player state local mcl_playerplus_internal = {} local time = 0 local look_pitch = 0 +local player_pos_for_bubble_columns = {} + local function player_collision(player) local pos = player:get_pos() @@ -349,7 +352,7 @@ minetest.register_globalstep(function(dtime) set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35)) -- controls right and left arms pitch when loading a crossbow - elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then set_bone_position_conditional(player,"Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(45,-20,25)) set_bone_position_conditional(player,"Arm_Left_Pitch_Control", vector.new(3,5.785,0), vector.new(55,20,-45)) -- when punching @@ -407,14 +410,15 @@ minetest.register_globalstep(function(dtime) mcl_playerplus_internal[name].jump_cooldown = mcl_playerplus_internal[name].jump_cooldown - dtime end + node_head = mcl_playerinfo[name].node_head + node_feet = mcl_playerinfo[name].node_feet + if control.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then --pos = player:get_pos() node_stand = mcl_playerinfo[name].node_stand node_stand_below = mcl_playerinfo[name].node_stand_below - node_head = mcl_playerinfo[name].node_head - node_feet = mcl_playerinfo[name].node_feet if not node_stand or not node_stand_below or not node_head or not node_feet then return end @@ -453,6 +457,48 @@ minetest.register_globalstep(function(dtime) mcl_playerplus_internal[name].jump_cooldown = 0.45 end end + + local bubble_column_feet = node_feet == "mcl_core:bubble_column_source" + if bubble_column_feet then + if not player_pos_for_bubble_columns[name] then + player_pos_for_bubble_columns[name] = fly_pos + else + local bubble_column_head = node_head == "mcl_core:bubble_column_source" + fly_pos.y = player_pos_for_bubble_columns[name].y + (bubble_column_head and time or time/10) + player:set_pos(fly_pos) + player_pos_for_bubble_columns[name] = fly_pos + end + else + local whirlpool_feet = node_feet == "mcl_core:whirlpool_source" + if whirlpool_feet then + if not player_pos_for_bubble_columns[name] then + player_pos_for_bubble_columns[name] = fly_pos + else + local whirlpool_head = node_head == "mcl_core:whirlpool_source" + local stands_on = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.0001, z = fly_pos.z}).name + if stands_on == "mcl_nether:magma" then + fly_pos.y = math.floor(fly_pos.y) + (control.sneak and 0.51 or 0.5) + player:set_pos(fly_pos) + player_pos_for_bubble_columns[name] = fly_pos + else + fly_pos.y = player_pos_for_bubble_columns[name].y - (whirlpool_head and time/2 or time/5) + local will_stand_on = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.0001, z = fly_pos.z}).name + if will_stand_on == "mcl_nether:magma" then + fly_pos.y = math.floor(fly_pos.y) + (control.sneak and 0.51 or 0.5) + player:set_pos(fly_pos) + player_pos_for_bubble_columns[name] = fly_pos + elseif will_stand_on == "mcl_core:whirlpool_source" then + player:set_pos(fly_pos) + player_pos_for_bubble_columns[name] = fly_pos + else + player_pos_for_bubble_columns[name] = nil + end + end + end + elseif player_pos_for_bubble_columns[name] then + player_pos_for_bubble_columns[name] = nil + end + end end -- Run the rest of the code every 0.5 seconds @@ -643,7 +689,7 @@ minetest.register_on_leaveplayer(function(player) mcl_playerplus.elytra[name] = nil end) --- Don't change HP if the player falls in the water or through End Portal: +-- Don't change HP if the player falls in the liquid or through End Portal: mcl_damage.register_modifier(function(obj, damage, reason) if reason.type == "fall" then local pos = obj:get_pos() @@ -661,7 +707,7 @@ mcl_damage.register_modifier(function(obj, damage, reason) if not def or def.walkable then return end - if minetest.get_item_group(node.name, "water") ~= 0 then + if minetest.get_item_group(node.name, "liquid") ~= 0 then return 0 end if node.name == "mcl_portals:portal_end" then diff --git a/tools/convert_all_tga_to_png.bash b/tools/convert_all_tga_to_png.bash new file mode 100755 index 000000000..8d3032c12 --- /dev/null +++ b/tools/convert_all_tga_to_png.bash @@ -0,0 +1,10 @@ +#!/bin/bash + +for name in ./*.tga +do + convert "$name" "${name%.*}".png + +# Slow and useless: +# optipng -o7 -zm1-9 "${name%.*}".png + +done