diff --git a/.gitmodules b/.gitmodules index b76071d6..9687d01b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -53,12 +53,6 @@ [submodule "mods/pkarcs"] path = mods/pkarcs url = https://git.tchncs.de/Illuna-Minetest/pkarcs -[submodule "mods/farming"] - path = mods/farming - url = https://git.tchncs.de/Illuna-Minetest/farming -[submodule "mods/boats"] - path = mods/boats - url = https://git.tchncs.de/Illuna-Minetest/boats [submodule "mods/technic_chests"] path = mods/technic_chests url = https://git.tchncs.de/Illuna-Minetest/technic_chests diff --git a/.luacheckrc b/.luacheckrc index 52b25132..6f4fdd2c 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -8,6 +8,8 @@ read_globals = { "vector", "VoxelManip", "VoxelArea", "PseudoRandom", "ItemStack", + -- Silence "accessing undefined field copy of global table". + table = { fields = { "copy" } } } -- Overwrites minetest.handle_node_drops diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..48f0b8d1 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,519 @@ +License of media (textures and sounds) +-------------------------------------- +Copyright (C) 2010-2012 celeron55, Perttu Ahola +See README.txt in each mod directory for information about other authors. + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +License of menu/header.png +Copyright (C) 2015 paramat CC BY-SA 3.0 + + +License of source code +---------------------- +Copyright (C) 2010-2012 celeron55, Perttu Ahola +See README.txt in each mod directory for information about other authors. + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/game_api.txt b/game_api.txt index 38718c36..fa6225a0 100644 --- a/game_api.txt +++ b/game_api.txt @@ -78,6 +78,12 @@ For example, is used to show all tools. Name is used in the sfinv page name, title is the human readable title. +`is_enabled_for` is used to check whether a player is in creative mode: + + creative.is_enabled_for(name) + +Override this to allow per-player game modes. + The contents of `creative.formspec_add` is appended to every creative inventory page. Mods can use it to add additional formspec elements onto the default creative inventory formspec to be drawn after each update. @@ -406,18 +412,28 @@ Sfinv API ### sfinv Methods -* sfinv.set_player_inventory_formspec(player, context) - builds page formspec - and calls set_inventory_formspec(). - If context is nil, it is either found or created. -* sfinv.get_formspec(player, context) - builds current page's formspec -* sfinv.get_nav_fs(player, context, nav, current_idx) - see above +**Pages** + +* sfinv.set_page(player, pagename) - changes the page * sfinv.get_homepage_name(player) - get the page name of the first page to show to a player -* sfinv.make_formspec(player, context, content, show_inv, size) - adds a theme to a formspec - * show_inv, defaults to false. Whether to show the player's main inventory - * size, defaults to `size[8,8.6]` if not specified * sfinv.register_page(name, def) - register a page, see section below * sfinv.override_page(name, def) - overrides fields of an page registered with register_page. * Note: Page must already be defined, (opt)depend on the mod defining it. +* sfinv.set_player_inventory_formspec(player) - (re)builds page formspec + and calls set_inventory_formspec(). +* sfinv.get_formspec(player, context) - builds current page's formspec + +**Contexts** + +* sfinv.get_or_create_context(player) - gets the player's context +* sfinv.set_context(player, context) + +**Theming** + +* sfinv.make_formspec(player, context, content, show_inv, size) - adds a theme to a formspec + * show_inv, defaults to false. Whether to show the player's main inventory + * size, defaults to `size[8,8.6]` if not specified +* sfinv.get_nav_fs(player, context, nav, current_idx) - creates tabheader or "" ### sfinv Members @@ -642,20 +658,36 @@ default.player_get_animation(player) Leafdecay --------- -To enable leaf decay for a node, add it to the `leafdecay` group. +To enable leaf decay for leaves when a tree is cut down by a player, +register the tree with the default.register_leafdecay(leafdecaydef) +function. -The rating of the group determines how far from a node in the group `tree` -the node can be without decaying. +If `param2` of any registered node is ~= 0, the node will always be +preserved. Thus, if the player places a node of that kind, you will +want to set `param2 = 1` or so. -If `param2` of the node is ~= 0, the node will always be preserved. Thus, if -the player places a node of that kind, you will want to set `param2 = 1` or so. +The function `default.after_place_leaves` can be set as +`after_place_node of a node` to set param2 to 1 if the player places +the node (should not be used for nodes that use param2 otherwise +(e.g. facedir)). -The function `default.after_place_leaves` can be set as `after_place_node of a node` -to set param2 to 1 if the player places the node (should not be used for nodes -that use param2 otherwise (e.g. facedir)). +If the node is in the `leafdecay_drop` group then it will always be +dropped as an item. + +`default.register_leafdecay(leafdecaydef)` + +`leafdecaydef` is a table, with following members: + { + trunks = {"default:tree"}, -- nodes considered trunks + leaves = {"default:leaves", "default:apple"}, + -- nodes considered for removal + radius = 3, -- radius to consider for searching + } + +Note: all the listed nodes in `trunks` have their `on_after_destruct` +callback overridden. All the nodes listed in `leaves` have their +`on_timer` callback overridden. -If the node is in the `leafdecay_drop` group then it will always be dropped as an -item. Dyes ---- diff --git a/mods/beds/api.lua b/mods/beds/api.lua index 3b2bb0d5..daa6d8e2 100644 --- a/mods/beds/api.lua +++ b/mods/beds/api.lua @@ -34,7 +34,7 @@ function beds.register_bed(name, def) is_ground_content = false, stack_max = 1, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1}, - sounds = default.node_sound_wood_defaults(), + sounds = def.sounds or default.node_sound_wood_defaults(), node_box = { type = "fixed", fixed = def.nodebox.bottom, @@ -46,6 +46,14 @@ function beds.register_bed(name, def) on_place = function(itemstack, placer, pointed_thing) local under = pointed_thing.under + local node = minetest.get_node(under) + local udef = minetest.registered_nodes[node.name] + if udef and udef.on_rightclick and + not (placer and placer:get_player_control().sneak) then + return udef.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + local pos if minetest.registered_items[minetest.get_node(under).name].buildable_to then pos = under @@ -138,7 +146,7 @@ function beds.register_bed(name, def) is_ground_content = false, pointable = false, groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2}, - sounds = default.node_sound_wood_defaults(), + sounds = def.sounds or default.node_sound_wood_defaults(), drop = name .. "_bottom", node_box = { type = "fixed", diff --git a/mods/boats b/mods/boats deleted file mode 160000 index a7534e93..00000000 --- a/mods/boats +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a7534e938834c1a0322e49df796f613ca1f55880 diff --git a/mods/carts/cart_entity.lua b/mods/carts/cart_entity.lua index e8707fb4..bf0a450d 100644 --- a/mods/carts/cart_entity.lua +++ b/mods/carts/cart_entity.lua @@ -362,6 +362,15 @@ minetest.register_craftitem("carts:cart", { inventory_image = minetest.inventorycube("carts_cart_top.png", "carts_cart_side.png", "carts_cart_side.png"), wield_image = "carts_cart_side.png", on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local node = minetest.get_node(under) + local udef = minetest.registered_nodes[node.name] + if udef and udef.on_rightclick and + not (placer and placer:get_player_control().sneak) then + return udef.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + if not pointed_thing.type == "node" then return end diff --git a/mods/carts/functions.lua b/mods/carts/functions.lua index 285645cb..a4717194 100644 --- a/mods/carts/functions.lua +++ b/mods/carts/functions.lua @@ -181,8 +181,8 @@ function carts:pathfinder(pos_, old_pos, old_dir, ctrl, pf_switch, railtype) return false end -function carts:register_rail(name, def, railparams) - local def_default = { +function carts:register_rail(name, def_overwrite, railparams) + local def = { drawtype = "raillike", paramtype = "light", sunlight_propagates = true, @@ -194,7 +194,7 @@ function carts:register_rail(name, def, railparams) }, sounds = default.node_sound_metal_defaults() } - for k, v in pairs(def_default) do + for k, v in pairs(def_overwrite) do def[k] = v end if not def.inventory_image then diff --git a/mods/carts/textures/carts_cart_front.png b/mods/carts/textures/carts_cart_front.png index b85696f9..38955b25 100644 Binary files a/mods/carts/textures/carts_cart_front.png and b/mods/carts/textures/carts_cart_front.png differ diff --git a/mods/carts/textures/carts_cart_side.png b/mods/carts/textures/carts_cart_side.png index 4362d6b1..f53808c6 100644 Binary files a/mods/carts/textures/carts_cart_side.png and b/mods/carts/textures/carts_cart_side.png differ diff --git a/mods/carts/textures/carts_cart_top.png b/mods/carts/textures/carts_cart_top.png index 5f775ff1..d9a31a9d 100644 Binary files a/mods/carts/textures/carts_cart_top.png and b/mods/carts/textures/carts_cart_top.png differ diff --git a/mods/creative/init.lua b/mods/creative/init.lua index 868b802b..7471e603 100644 --- a/mods/creative/init.lua +++ b/mods/creative/init.lua @@ -1,3 +1,11 @@ +creative = {} + +local creative_mode_cache = minetest.setting_getbool("creative_mode") + +function creative.is_enabled_for(name) + return creative_mode_cache +end + dofile(minetest.get_modpath("creative") .. "/inventory.lua") if minetest.setting_getbool("creative_mode") then @@ -28,22 +36,28 @@ if minetest.setting_getbool("creative_mode") then damage_groups = {fleshy = 10}, } }) +end - minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) - return true - end) +-- Unlimited node placement +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + return creative.is_enabled_for(placer:get_player_name()) +end) - function minetest.handle_node_drops(pos, drops, digger) - if not digger or not digger:is_player() then - return - end - local inv = digger:get_inventory() - if inv then - for _, item in ipairs(drops) do - item = ItemStack(item):get_name() - if not inv:contains_item("main", item) then - inv:add_item("main", item) - end +-- Don't pick up if the item is already in the inventory +local old_handle_node_drops = minetest.handle_node_drops +function minetest.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() then + return + end + if not creative.is_enabled_for(digger:get_player_name()) then + return old_handle_node_drops(pos, drops, digger) + end + local inv = digger:get_inventory() + if inv then + for _, item in ipairs(drops) do + item = ItemStack(item):get_name() + if not inv:contains_item("main", item) then + inv:add_item("main", item) end end end diff --git a/mods/creative/inventory.lua b/mods/creative/inventory.lua index be24b3a2..1363e294 100644 --- a/mods/creative/inventory.lua +++ b/mods/creative/inventory.lua @@ -1,4 +1,3 @@ -creative = {} local player_inventory = {} function creative.init_creative_inventory(player) @@ -79,7 +78,7 @@ function creative.register_tab(name, title, items) sfinv.register_page("creative:" .. name, { title = title, is_in_nav = function(self, player, context) - return minetest.setting_getbool("creative_mode") + return creative.is_enabled_for(player:get_player_name()) end, get = function(self, player, context) local player_name = player:get_player_name() @@ -172,7 +171,7 @@ creative.register_tab("craftitems", "Items", minetest.registered_craftitems) local old_homepage_name = sfinv.get_homepage_name function sfinv.get_homepage_name(player) - if minetest.setting_getbool("creative_mode") then + if creative.is_enabled_for(player:get_player_name()) then return "creative:all" else return old_homepage_name(player) diff --git a/mods/default/README.txt b/mods/default/README.txt index d261b6b5..1ca66e4e 100644 --- a/mods/default/README.txt +++ b/mods/default/README.txt @@ -115,6 +115,9 @@ paramat (CC BY-SA 3.0): default_grass_side.png default_mese_block.png default_silver_sand.png + default_mese_post_light_side.png + default_mese_post_light_side_dark.png + default_mese_post_light_top.png brunob.santos (CC BY-SA 4.0): default_desert_cobble.png @@ -195,6 +198,20 @@ Ferk (CC0 1.0) default_item_smoke.png default_item_smoke.ogg, based on sound by http://opengameart.org/users/bart +npx (CC BY-SA 3.0) + default_rainforest_litter.png + default_rainforest_litter_side.png + +GreenXenith (CC-BY-SA 3.0): + default_silver_sandstone.png + default_silver_sandstone_brick.png + default_silver_sandstone_block.png + +kaeza (CC-BY-SA 3.0): + default_desert_sandstone.png + default_desert_sandstone_brick.png + default_desert_sandstone_block.png + Glass breaking sounds (CC BY 3.0): 1: http://www.freesound.org/people/cmusounddesign/sounds/71947/ 2: http://www.freesound.org/people/Tomlija/sounds/97669/ diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua index 483245c2..1eca8887 100644 --- a/mods/default/crafting.lua +++ b/mods/default/crafting.lua @@ -495,34 +495,98 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'default:sandstone', + output = "default:sandstone", recipe = { - {'group:sand', 'group:sand'}, - {'group:sand', 'group:sand'}, + {"default:sand", "default:sand"}, + {"default:sand", "default:sand"}, } }) minetest.register_craft({ - output = 'default:sand 4', + output = "default:sand 4", recipe = { - {'default:sandstone'}, + {"default:sandstone"}, } }) minetest.register_craft({ - output = 'default:sandstonebrick 4', + output = "default:sandstonebrick 4", recipe = { - {'default:sandstone', 'default:sandstone'}, - {'default:sandstone', 'default:sandstone'}, + {"default:sandstone", "default:sandstone"}, + {"default:sandstone", "default:sandstone"}, } }) minetest.register_craft({ - output = 'default:sandstone_block 9', + output = "default:sandstone_block 9", recipe = { - {'default:sandstone', 'default:sandstone', 'default:sandstone'}, - {'default:sandstone', 'default:sandstone', 'default:sandstone'}, - {'default:sandstone', 'default:sandstone', 'default:sandstone'}, + {"default:sandstone", "default:sandstone", "default:sandstone"}, + {"default:sandstone", "default:sandstone", "default:sandstone"}, + {"default:sandstone", "default:sandstone", "default:sandstone"}, + } +}) + +minetest.register_craft({ + output = "default:desert_sandstone", + recipe = { + {"default:desert_sand", "default:desert_sand"}, + {"default:desert_sand", "default:desert_sand"}, + } +}) + +minetest.register_craft({ + output = "default:desert_sand 4", + recipe = { + {"default:desert_sandstone"}, + } +}) + +minetest.register_craft({ + output = "default:desert_sandstone_brick 4", + recipe = { + {"default:desert_sandstone", "default:desert_sandstone"}, + {"default:desert_sandstone", "default:desert_sandstone"}, + } +}) + +minetest.register_craft({ + output = "default:desert_sandstone_block 9", + recipe = { + {"default:desert_sandstone", "default:desert_sandstone", "default:desert_sandstone"}, + {"default:desert_sandstone", "default:desert_sandstone", "default:desert_sandstone"}, + {"default:desert_sandstone", "default:desert_sandstone", "default:desert_sandstone"}, + } +}) + +minetest.register_craft({ + output = "default:silver_sandstone", + recipe = { + {"default:silver_sand", "default:silver_sand"}, + {"default:silver_sand", "default:silver_sand"}, + } +}) + +minetest.register_craft({ + output = "default:silver_sand 4", + recipe = { + {"default:silver_sandstone"}, + } +}) + +minetest.register_craft({ + output = "default:silver_sandstone_brick 4", + recipe = { + {"default:silver_sandstone", "default:silver_sandstone"}, + {"default:silver_sandstone", "default:silver_sandstone"}, + } +}) + +minetest.register_craft({ + output = "default:silver_sandstone_block 9", + recipe = { + {"default:silver_sandstone", "default:silver_sandstone", "default:silver_sandstone"}, + {"default:silver_sandstone", "default:silver_sandstone", "default:silver_sandstone"}, + {"default:silver_sandstone", "default:silver_sandstone", "default:silver_sandstone"}, } }) @@ -582,11 +646,11 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'default:ladder_wood 3', + output = "default:ladder_wood 5", recipe = { - {'group:stick', '', 'group:stick'}, - {'group:stick', 'group:stick', 'group:stick'}, - {'group:stick', '', 'group:stick'}, + {"group:stick", "", "group:stick"}, + {"group:stick", "group:stick", "group:stick"}, + {"group:stick", "", "group:stick"}, } }) @@ -632,10 +696,19 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'default:meselamp 1', + output = 'default:meselamp', recipe = { - {'', 'default:mese_crystal',''}, - {'default:mese_crystal', 'default:glass', 'default:mese_crystal'}, + {'default:glass'}, + {'default:mese_crystal'}, + } +}) + +minetest.register_craft({ + output = "default:mese_post_light 3", + recipe = { + {"", "default:glass", ""}, + {"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"}, + {"", "group:wood", ""}, } }) diff --git a/mods/default/craftitems.lua b/mods/default/craftitems.lua index 9d38a0b0..94e6b50e 100644 --- a/mods/default/craftitems.lua +++ b/mods/default/craftitems.lua @@ -20,11 +20,19 @@ minetest.register_craftitem("default:paper", { local lpp = 14 -- Lines per book's page local function book_on_use(itemstack, user) local player_name = user:get_player_name() - local data = minetest.deserialize(itemstack:get_metadata()) + local meta = itemstack:get_meta() local title, text, owner = "", "", player_name local page, page_max, lines, string = 1, 1, {}, "" - if data then + -- Backwards compatibility + local old_data = minetest.deserialize(itemstack:get_metadata()) + if old_data then + meta:from_table({ fields = old_data }) + end + + local data = meta:to_table().fields + + if data.owner then title = data.title text = data.text owner = data.owner @@ -86,35 +94,38 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) new_stack = ItemStack("default:book_written") end else - data = minetest.deserialize(stack:get_metadata()) + data = stack:get_meta():to_table().fields end if not data then data = {} end data.title = fields.title + data.owner = player:get_player_name() + data.description = "\""..fields.title.."\" by "..data.owner data.text = fields.text data.text_len = #data.text data.page = 1 data.page_max = math.ceil((#data.text:gsub("[^\n]", "") + 1) / lpp) - data.owner = player:get_player_name() - local data_str = minetest.serialize(data) if new_stack then - new_stack:set_metadata(data_str) + new_stack:get_meta():from_table({ fields = data }) if inv:room_for_item("main", new_stack) then inv:add_item("main", new_stack) else minetest.add_item(player:getpos(), new_stack) end else - stack:set_metadata(data_str) + stack:get_meta():from_table({ fields = data }) end elseif fields.book_next or fields.book_prev then - local data = minetest.deserialize(stack:get_metadata()) + local data = stack:get_meta():to_table().fields if not data or not data.page then return end + data.page = tonumber(data.page) + data.page_max = tonumber(data.page_max) + if fields.book_next then data.page = data.page + 1 if data.page > data.page_max then @@ -254,4 +265,3 @@ minetest.register_craftitem("default:flint", { description = "Flint", inventory_image = "default_flint.png" }) - diff --git a/mods/default/functions.lua b/mods/default/functions.lua index e8b20781..1566cef0 100644 --- a/mods/default/functions.lua +++ b/mods/default/functions.lua @@ -18,7 +18,7 @@ end function default.node_sound_stone_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_hard_footstep", gain = 0.5} + {name = "default_hard_footstep", gain = 0.3} table.dug = table.dug or {name = "default_hard_footstep", gain = 1.0} default.node_sound_defaults(table) @@ -28,9 +28,9 @@ end function default.node_sound_dirt_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_dirt_footstep", gain = 1.0} + {name = "default_dirt_footstep", gain = 0.4} table.dug = table.dug or - {name = "default_dirt_footstep", gain = 1.5} + {name = "default_dirt_footstep", gain = 1.0} table.place = table.place or {name = "default_place_node", gain = 1.0} default.node_sound_defaults(table) @@ -52,7 +52,7 @@ end function default.node_sound_gravel_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_gravel_footstep", gain = 0.5} + {name = "default_gravel_footstep", gain = 0.4} table.dug = table.dug or {name = "default_gravel_footstep", gain = 1.0} table.place = table.place or @@ -64,7 +64,7 @@ end function default.node_sound_wood_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_wood_footstep", gain = 0.5} + {name = "default_wood_footstep", gain = 0.3} table.dug = table.dug or {name = "default_wood_footstep", gain = 1.0} default.node_sound_defaults(table) @@ -74,11 +74,9 @@ end function default.node_sound_leaves_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_grass_footstep", gain = 0.35} + {name = "default_grass_footstep", gain = 0.45} table.dug = table.dug or {name = "default_grass_footstep", gain = 0.7} - table.dig = table.dig or - {name = "default_dig_crumbly", gain = 0.4} table.place = table.place or {name = "default_place_node", gain = 1.0} default.node_sound_defaults(table) @@ -88,9 +86,9 @@ end function default.node_sound_glass_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_glass_footstep", gain = 0.25} + {name = "default_glass_footstep", gain = 0.3} table.dig = table.dig or - {name = "default_glass_footstep", gain = 0.45} + {name = "default_glass_footstep", gain = 0.5} table.dug = table.dug or {name = "default_break_glass", gain = 1.0} default.node_sound_defaults(table) @@ -100,7 +98,7 @@ end function default.node_sound_metal_defaults(table) table = table or {} table.footstep = table.footstep or - {name = "default_metal_footstep", gain = 0.5} + {name = "default_metal_footstep", gain = 0.4} table.dig = table.dig or {name = "default_dig_metal", gain = 0.5} table.dug = table.dug or @@ -147,7 +145,7 @@ minetest.register_abm({ nodenames = {"default:lava_source", "default:lava_flowing"}, neighbors = {"group:cools_lava", "group:water"}, interval = 1, - chance = 1, + chance = 2, catch_up = false, action = function(...) default.cool_lava(...) @@ -195,6 +193,9 @@ function default.grow_cactus(pos, node) if height == 4 or node.name ~= "air" then return end + if minetest.get_node_light(pos) < 13 then + return + end minetest.set_node(pos, {name = "default:cactus"}) return true end @@ -218,6 +219,9 @@ function default.grow_papyrus(pos, node) if height == 4 or node.name ~= "air" then return end + if minetest.get_node_light(pos) < 13 then + return + end minetest.set_node(pos, {name = "default:papyrus"}) return true end @@ -319,47 +323,64 @@ default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) end end --- Leafdecay ABM - -minetest.register_abm({ - label = "Leaf decay", - nodenames = {"group:leafdecay"}, - neighbors = {"air"}, - interval = 2, - chance = 10, - catch_up = false, - - action = function(pos, node, _, _) - -- Check if leaf is placed - if node.param2 ~= 0 then - return +-- Leafdecay +local function leafdecay_after_destruct(pos, oldnode, def) + for _, v in pairs(minetest.find_nodes_in_area(vector.subtract(pos, def.radius), + vector.add(pos, def.radius), def.leaves)) do + local node = minetest.get_node(v) + if node.param2 == 0 then + minetest.get_node_timer(v):start(math.random(20, 120) / 10) end + end +end - local rad = minetest.registered_nodes[node.name].groups.leafdecay - -- Assume ignore is a trunk, to make this - -- work at the border of a loaded area - if minetest.find_node_near(pos, rad, {"ignore", "group:tree"}) then - return - end - -- Drop stuff - local itemstacks = minetest.get_node_drops(node.name) - for _, itemname in ipairs(itemstacks) do - if itemname ~= node.name or - minetest.get_item_group(node.name, "leafdecay_drop") ~= 0 then - local p_drop = { - x = pos.x - 0.5 + math.random(), - y = pos.y - 0.5 + math.random(), - z = pos.z - 0.5 + math.random(), - } - minetest.add_item(p_drop, itemname) +local function leafdecay_on_timer(pos, def) + if minetest.find_node_near(pos, def.radius, def.trunks) then + return false + end + + local node = minetest.get_node(pos) + local drops = minetest.get_node_drops(node.name) + for _, item in ipairs(drops) do + local is_leaf + for _, v in pairs(def.leaves) do + if v == item then + is_leaf = true end end - -- Remove node - minetest.remove_node(pos) - minetest.check_for_falling(pos) + if minetest.get_item_group(item, "leafdecay_drop") ~= 0 or + not is_leaf then + minetest.add_item({ + x = pos.x - 0.5 + math.random(), + y = pos.y - 0.5 + math.random(), + z = pos.z - 0.5 + math.random(), + }, item) + end end -}) + minetest.remove_node(pos) + minetest.check_for_falling(pos) +end + +function default.register_leafdecay(def) + assert(def.leaves) + assert(def.trunks) + assert(def.radius) + for _, v in pairs(def.trunks) do + minetest.override_item(v, { + after_destruct = function(pos, oldnode) + leafdecay_after_destruct(pos, oldnode, def) + end, + }) + end + for _, v in pairs(def.leaves) do + minetest.override_item(v, { + on_timer = function(pos) + leafdecay_on_timer(pos, def) + end, + }) + end +end -- -- Convert dirt to something that fits the environment @@ -514,3 +535,39 @@ minetest.register_abm({ minetest.set_node(pos, {name = "default:coral_skeleton"}) end, }) + + +-- +-- NOTICE: This method is not an official part of the API yet! +-- This method may change in future. +-- + +function default.can_interact_with_node(player, pos) + if player then + if minetest.check_player_privs(player, "protection_bypass") then + return true + end + else + return false + end + + local meta = minetest.get_meta(pos) + + -- is player wielding the right key? + local item = player:get_wielded_item() + if item:get_name() == "default:key" then + local key_meta = minetest.parse_json(item:get_metadata()) + local secret = meta:get_string("key_lock_secret") + if secret ~= key_meta.secret then + return false + end + + return true + end + + if player:get_player_name() ~= meta:get_string("owner") then + return false + end + + return true +end \ No newline at end of file diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua index fed7cf2e..4b822058 100644 --- a/mods/default/furnace.lua +++ b/mods/default/furnace.lua @@ -116,6 +116,7 @@ local function furnace_node_timer(pos, elapsed) local srclist, fuellist local cookable, cooked + local fuel local update = true while update do @@ -154,7 +155,8 @@ local function furnace_node_timer(pos, elapsed) -- Furnace ran out of fuel if cookable then -- We need to get new fuel - local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + local afterfuel + fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) if fuel.time == 0 then -- No valid fuel in fuel list @@ -164,7 +166,6 @@ local function furnace_node_timer(pos, elapsed) -- Take fuel from fuel list inv:set_stack("fuel", 1, afterfuel.items[1]) update = true - fuel_totaltime = fuel.time + (fuel_time - fuel_totaltime) src_time = src_time + elapsed end @@ -179,6 +180,13 @@ local function furnace_node_timer(pos, elapsed) elapsed = 0 end + if fuel and fuel_totaltime > fuel.time then + fuel_totaltime = fuel.time + end + if srclist[1]:is_empty() then + src_time = 0 + end + -- -- Update formspec, infotext and node -- diff --git a/mods/default/license.txt b/mods/default/license.txt index e9267366..09e4225f 100644 --- a/mods/default/license.txt +++ b/mods/default/license.txt @@ -41,6 +41,8 @@ Copyright (C) 2010-2016: asl97 KevDoy Mito551 + GreenXenith + kaeza You are free to: Share — copy and redistribute the material in any medium or format. diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua index d786a841..0fabb2ed 100644 --- a/mods/default/mapgen.lua +++ b/mods/default/mapgen.lua @@ -1,5 +1,5 @@ -- --- Aliases for map generator outputs +-- Aliases for map generators -- minetest.register_alias("mapgen_stone", "default:stone") @@ -34,18 +34,21 @@ minetest.register_alias("mapgen_pine_needles", "default:pine_needles") minetest.register_alias("mapgen_cobble", "default:cobble") minetest.register_alias("mapgen_stair_cobble", "stairs:stair_cobble") minetest.register_alias("mapgen_mossycobble", "default:mossycobble") +minetest.register_alias("mapgen_stair_desert_stone", "stairs:stair_desert_stone") minetest.register_alias("mapgen_sandstonebrick", "default:sandstonebrick") -minetest.register_alias("mapgen_stair_sandstonebrick", "stairs:stair_sandstonebrick") +minetest.register_alias("mapgen_stair_sandstone_block", "stairs:stair_sandstone_block") -- -- Register ores -- -function default.register_ores() - minetest.clear_registered_ores() - -- Blob ores - -- These first to avoid other ores in blobs +-- Blob ores +-- These first to avoid other ores in blobs + +-- Mgv6 + +function default.register_mgv6_blob_ores() -- Clay -- This first to avoid clay in sand blobs @@ -74,8 +77,7 @@ function default.register_ores() minetest.register_ore({ ore_type = "blob", ore = "default:sand", - wherein = {"default:stone", "default:sandstone", - "default:desert_stone"}, + wherein = {"default:stone", "default:desert_stone"}, clust_scarcity = 16 * 16 * 16, clust_size = 5, y_min = -31, @@ -110,8 +112,6 @@ function default.register_ores() octaves = 1, persist = 0.0 }, - biomes = {"taiga", "snowy_grassland", "grassland", "coniferous_forest", - "deciduous_forest", "savanna", "rainforest"} }) -- Gravel @@ -134,8 +134,120 @@ function default.register_ores() persist = 0.0 }, }) +end - -- Scatter ores + +-- All mapgens except mgv6 + +function default.register_blob_ores() + + -- Clay + + minetest.register_ore({ + ore_type = "blob", + ore = "default:clay", + wherein = {"default:sand"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_min = -15, + y_max = 0, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = -316, + octaves = 1, + persist = 0.0 + }, + }) + + -- Silver sand + + minetest.register_ore({ + ore_type = "blob", + ore = "default:silver_sand", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_min = -31000, + y_max = 31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 2316, + octaves = 1, + persist = 0.0 + }, + biomes = {"icesheet_ocean", "tundra", "tundra_beach", "tundra_ocean", + "taiga", "taiga_ocean", "snowy_grassland", "snowy_grassland_ocean", + "grassland", "grassland_dunes", "grassland_ocean", "coniferous_forest", + "coniferous_forest_dunes", "coniferous_forest_ocean", "deciduous_forest", + "deciduous_forest_shore", "deciduous_forest_ocean", "cold_desert", + "cold_desert_ocean", "savanna", "savanna_shore", "savanna_ocean", + "rainforest", "rainforest_swamp", "rainforest_ocean", "underground"} + }) + + -- Dirt + + minetest.register_ore({ + ore_type = "blob", + ore = "default:dirt", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_min = -31, + y_max = 31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 17676, + octaves = 1, + persist = 0.0 + }, + biomes = {"taiga", "snowy_grassland", "grassland", "coniferous_forest", + "deciduous_forest", "deciduous_forest_shore", "savanna", "savanna_shore", + "rainforest", "rainforest_swamp"} + }) + + -- Gravel + + minetest.register_ore({ + ore_type = "blob", + ore = "default:gravel", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_min = -31000, + y_max = 31000, + noise_threshold = 0.0, + noise_params = { + offset = 0.5, + scale = 0.2, + spread = {x = 5, y = 5, z = 5}, + seed = 766, + octaves = 1, + persist = 0.0 + }, + biomes = {"icesheet_ocean", "tundra", "tundra_beach", "tundra_ocean", + "taiga", "taiga_ocean", "snowy_grassland", "snowy_grassland_ocean", + "grassland", "grassland_dunes", "grassland_ocean", "coniferous_forest", + "coniferous_forest_dunes", "coniferous_forest_ocean", "deciduous_forest", + "deciduous_forest_shore", "deciduous_forest_ocean", "cold_desert", + "cold_desert_ocean", "savanna", "savanna_shore", "savanna_ocean", + "rainforest", "rainforest_swamp", "rainforest_ocean", "underground"} + }) +end + + +-- Scatter ores +-- All mapgens + +function default.register_ores() -- Coal @@ -377,10 +489,9 @@ end -- Register biomes -- --- All mapgens except mgv6 and singlenode +-- All mapgens except mgv6 function default.register_biomes() - minetest.clear_registered_biomes() -- Icesheet @@ -947,7 +1058,7 @@ function default.register_biomes() minetest.register_biome({ name = "rainforest", --node_dust = "", - node_top = "default:dirt_with_grass", + node_top = "default:dirt_with_rainforest_litter", depth_top = 1, node_filler = "default:dirt", depth_filler = 3, @@ -1033,7 +1144,6 @@ end -- Mgv6 function default.register_mgv6_decorations() - minetest.clear_registered_decorations() -- Papyrus @@ -1166,7 +1276,6 @@ end function default.register_decorations() - minetest.clear_registered_decorations() -- Apple tree and log @@ -1187,6 +1296,7 @@ function default.register_decorations() y_max = 31000, schematic = minetest.get_modpath("default") .. "/schematics/apple_tree.mts", flags = "place_center_x, place_center_z", + rotation = "random", }) minetest.register_decoration({ @@ -1204,20 +1314,7 @@ function default.register_decorations() biomes = {"deciduous_forest"}, y_min = 1, y_max = 31000, - schematic = { - size = {x = 3, y = 3, z = 1}, - data = { - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "default:tree", param2 = 12, prob = 191}, - {name = "default:tree", param2 = 12}, - {name = "default:tree", param2 = 12, prob = 127}, - {name = "air", prob = 0}, - {name = "flowers:mushroom_brown", prob = 63}, - {name = "air", prob = 0}, - }, - }, + schematic = minetest.get_modpath("default") .. "/schematics/apple_log.mts", flags = "place_center_x", rotation = "random", }) @@ -1226,8 +1323,8 @@ function default.register_decorations() minetest.register_decoration({ deco_type = "schematic", - place_on = {"default:dirt_with_grass", "default:dirt"}, - sidelen = 80, + place_on = {"default:dirt_with_rainforest_litter", "default:dirt"}, + sidelen = 16, fill_ratio = 0.1, biomes = {"rainforest", "rainforest_swamp"}, y_min = -1, @@ -1239,26 +1336,13 @@ function default.register_decorations() minetest.register_decoration({ deco_type = "schematic", - place_on = {"default:dirt_with_grass", "default:dirt"}, - sidelen = 80, + place_on = {"default:dirt_with_rainforest_litter", "default:dirt"}, + sidelen = 16, fill_ratio = 0.005, biomes = {"rainforest", "rainforest_swamp"}, y_min = 1, y_max = 31000, - schematic = { - size = {x = 3, y = 3, z = 1}, - data = { - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "default:jungletree", param2 = 12, prob = 191}, - {name = "default:jungletree", param2 = 12}, - {name = "default:jungletree", param2 = 12, prob = 127}, - {name = "air", prob = 0}, - {name = "flowers:mushroom_brown", prob = 127}, - {name = "air", prob = 0}, - }, - }, + schematic = minetest.get_modpath("default") .. "/schematics/jungle_log.mts", flags = "place_center_x", rotation = "random", }) @@ -1299,20 +1383,7 @@ function default.register_decorations() biomes = {"taiga", "coniferous_forest"}, y_min = 1, y_max = 31000, - schematic = { - size = {x = 3, y = 3, z = 1}, - data = { - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "default:pine_tree", param2 = 12, prob = 191}, - {name = "default:pine_tree", param2 = 12}, - {name = "default:pine_tree", param2 = 12, prob = 127}, - {name = "air", prob = 0}, - {name = "flowers:mushroom_red", prob = 63}, - {name = "air", prob = 0}, - }, - }, + schematic = minetest.get_modpath("default") .. "/schematics/pine_log.mts", flags = "place_center_x", rotation = "random", }) @@ -1354,17 +1425,7 @@ function default.register_decorations() biomes = {"savanna"}, y_min = 1, y_max = 31000, - schematic = { - size = {x = 3, y = 2, z = 1}, - data = { - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "default:acacia_tree", param2 = 12, prob = 191}, - {name = "default:acacia_tree", param2 = 12}, - {name = "default:acacia_tree", param2 = 12, prob = 127}, - }, - }, + schematic = minetest.get_modpath("default") .. "/schematics/acacia_log.mts", flags = "place_center_x", rotation = "random", }) @@ -1405,20 +1466,7 @@ function default.register_decorations() biomes = {"deciduous_forest"}, y_min = 1, y_max = 31000, - schematic = { - size = {x = 3, y = 3, z = 1}, - data = { - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "air", prob = 0}, - {name = "default:aspen_tree", param2 = 12}, - {name = "default:aspen_tree", param2 = 12}, - {name = "default:aspen_tree", param2 = 12, prob = 127}, - {name = "flowers:mushroom_red", prob = 63}, - {name = "flowers:mushroom_brown", prob = 63}, - {name = "air", prob = 0}, - }, - }, + schematic = minetest.get_modpath("default") .. "/schematics/aspen_log.mts", flags = "place_center_x", rotation = "random", }) @@ -1549,8 +1597,8 @@ function default.register_decorations() minetest.register_decoration({ deco_type = "simple", - place_on = {"default:dirt_with_grass"}, - sidelen = 80, + place_on = {"default:dirt_with_rainforest_litter"}, + sidelen = 16, fill_ratio = 0.1, biomes = {"rainforest"}, y_min = 1, @@ -1585,9 +1633,9 @@ function default.register_decorations() deco_type = "schematic", place_on = {"default:sand"}, noise_params = { - offset = -0.1, + offset = -0.15, scale = 0.1, - spread = {x = 200, y = 200, z = 200}, + spread = {x = 100, y = 100, z = 100}, seed = 7013, octaves = 3, persist = 1, @@ -1610,12 +1658,18 @@ end -- Detect mapgen to select functions -- +minetest.clear_registered_biomes() +minetest.clear_registered_ores() +minetest.clear_registered_decorations() + local mg_name = minetest.get_mapgen_setting("mg_name") if mg_name == "v6" then + default.register_mgv6_blob_ores() default.register_ores() default.register_mgv6_decorations() else default.register_biomes() + default.register_blob_ores() default.register_ores() default.register_decorations() end diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua index f9ac23e3..655b9e82 100644 --- a/mods/default/nodes.lua +++ b/mods/default/nodes.lua @@ -30,6 +30,12 @@ default:desert_stone_block default:sandstone default:sandstonebrick default:sandstone_block +default:desert_sandstone +default:desert_sandstone_brick +default:desert_sandstone_block +default:silver_sandstone +default:silver_sandstone_brick +default:silver_sandstone_block default:obsidian default:obsidianbrick @@ -44,6 +50,7 @@ default:dirt_with_grass default:dirt_with_grass_footsteps default:dirt_with_dry_grass default:dirt_with_snow +default:dirt_with_rainforest_litter default:sand default:desert_sand @@ -182,6 +189,7 @@ default:obsidian_glass default:brick default:meselamp +default:mese_post_light Misc ---- @@ -288,7 +296,6 @@ minetest.register_node("default:desert_stone_block", { sounds = default.node_sound_stone_defaults(), }) - minetest.register_node("default:sandstone", { description = "Sandstone", tiles = {"default_sandstone.png"}, @@ -314,6 +321,55 @@ minetest.register_node("default:sandstone_block", { sounds = default.node_sound_stone_defaults(), }) +minetest.register_node("default:desert_sandstone", { + description = "Desert Sandstone", + tiles = {"default_desert_sandstone.png"}, + groups = {crumbly = 1, cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:desert_sandstone_brick", { + description = "Desert Sandstone Brick", + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_desert_sandstone_brick.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:desert_sandstone_block", { + description = "Desert Sandstone Block", + tiles = {"default_desert_sandstone_block.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:silver_sandstone", { + description = "Silver Sandstone", + tiles = {"default_silver_sandstone.png"}, + groups = {crumbly = 1, cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:silver_sandstone_brick", { + description = "Silver Sandstone Brick", + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_silver_sandstone_brick.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:silver_sandstone_block", { + description = "Silver Sandstone Block", + tiles = {"default_silver_sandstone_block.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) minetest.register_node("default:obsidian", { description = "Obsidian", @@ -401,13 +457,28 @@ minetest.register_node("default:dirt_with_snow", { tiles = {"default_snow.png", "default_dirt.png", {name = "default_dirt.png^default_snow_side.png", tileable_vertical = false}}, - groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1, snowy = 1}, drop = 'default:dirt', sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_snow_footstep", gain = 0.15}, }), }) +minetest.register_node("default:dirt_with_rainforest_litter", { + description = "Dirt with Rainforest Litter", + tiles = { + "default_rainforest_litter.png", + "default_dirt.png", + {name = "default_dirt.png^default_rainforest_litter_side.png", + tileable_vertical = false} + }, + groups = {crumbly = 3, soil = 1, spreading_dirt_type = 1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name = "default_grass_footstep", gain = 0.4}, + }), +}) + minetest.register_node("default:sand", { description = "Sand", tiles = {"default_sand.png"}, @@ -468,7 +539,7 @@ minetest.register_node("default:snow", { {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, }, }, - groups = {crumbly = 3, falling_node = 1, puts_out_fire = 1}, + groups = {crumbly = 3, falling_node = 1, puts_out_fire = 1, snowy = 1}, sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_snow_footstep", gain = 0.15}, dug = {name = "default_snow_footstep", gain = 0.2}, @@ -486,7 +557,7 @@ minetest.register_node("default:snow", { minetest.register_node("default:snowblock", { description = "Snow Block", tiles = {"default_snow.png"}, - groups = {crumbly = 3, puts_out_fire = 1, cools_lava = 1}, + groups = {crumbly = 3, puts_out_fire = 1, cools_lava = 1, snowy = 1}, sounds = default.node_sound_dirt_defaults({ footstep = {name = "default_snow_footstep", gain = 0.15}, dug = {name = "default_snow_footstep", gain = 0.2}, @@ -538,7 +609,6 @@ minetest.register_node("default:wood", { minetest.register_node("default:sapling", { description = "Sapling", drawtype = "plantlike", - visual_scale = 1.0, tiles = {"default_sapling.png"}, inventory_image = "default_sapling.png", wield_image = "default_sapling.png", @@ -604,7 +674,6 @@ minetest.register_node("default:leaves", { minetest.register_node("default:apple", { description = "Apple", drawtype = "plantlike", - visual_scale = 1.0, tiles = {"default_apple.png"}, inventory_image = "default_apple.png", paramtype = "light", @@ -674,7 +743,6 @@ minetest.register_node("default:jungleleaves", { minetest.register_node("default:junglesapling", { description = "Jungle Sapling", drawtype = "plantlike", - visual_scale = 1.0, tiles = {"default_junglesapling.png"}, inventory_image = "default_junglesapling.png", wield_image = "default_junglesapling.png", @@ -754,7 +822,6 @@ minetest.register_node("default:pine_needles",{ minetest.register_node("default:pine_sapling", { description = "Pine Sapling", drawtype = "plantlike", - visual_scale = 1.0, tiles = {"default_pine_sapling.png"}, inventory_image = "default_pine_sapling.png", wield_image = "default_pine_sapling.png", @@ -835,7 +902,6 @@ minetest.register_node("default:acacia_leaves", { minetest.register_node("default:acacia_sapling", { description = "Acacia Tree Sapling", drawtype = "plantlike", - visual_scale = 1.0, tiles = {"default_acacia_sapling.png"}, inventory_image = "default_acacia_sapling.png", wield_image = "default_acacia_sapling.png", @@ -914,7 +980,6 @@ minetest.register_node("default:aspen_leaves", { minetest.register_node("default:aspen_sapling", { description = "Aspen Tree Sapling", drawtype = "plantlike", - visual_scale = 1.0, tiles = {"default_aspen_sapling.png"}, inventory_image = "default_aspen_sapling.png", wield_image = "default_aspen_sapling.png", @@ -1101,7 +1166,6 @@ minetest.register_node("default:dry_shrub", { description = "Dry Shrub", drawtype = "plantlike", waving = 1, - visual_scale = 1.0, tiles = {"default_dry_shrub.png"}, inventory_image = "default_dry_shrub.png", wield_image = "default_dry_shrub.png", @@ -1121,7 +1185,7 @@ minetest.register_node("default:junglegrass", { description = "Jungle Grass", drawtype = "plantlike", waving = 1, - visual_scale = 1.3, + visual_scale = 1.69, tiles = {"default_junglegrass.png"}, inventory_image = "default_junglegrass.png", wield_image = "default_junglegrass.png", @@ -1245,7 +1309,7 @@ end minetest.register_node("default:bush_stem", { description = "Bush Stem", drawtype = "plantlike", - visual_scale = 1.18, + visual_scale = 1.41, tiles = {"default_bush_stem.png"}, inventory_image = "default_bush_stem.png", wield_image = "default_bush_stem.png", @@ -1272,7 +1336,7 @@ minetest.register_node("default:bush_leaves", { minetest.register_node("default:acacia_bush_stem", { description = "Acacia Bush Stem", drawtype = "plantlike", - visual_scale = 1.18, + visual_scale = 1.41, tiles = {"default_acacia_bush_stem.png"}, inventory_image = "default_acacia_bush_stem.png", wield_image = "default_acacia_bush_stem.png", @@ -1641,34 +1705,6 @@ local function get_locked_chest_formspec(pos) return formspec end -local function has_locked_chest_privilege(meta, player) - if player then - if minetest.check_player_privs(player, "protection_bypass") then - return true - end - else - return false - end - - -- is player wielding the right key? - local item = player:get_wielded_item() - if item:get_name() == "default:key" then - local key_meta = minetest.parse_json(item:get_metadata()) - local secret = meta:get_string("key_lock_secret") - if secret ~= key_meta.secret then - return false - end - - return true - end - - if player:get_player_name() ~= meta:get_string("owner") then - return false - end - - return true -end - minetest.register_node("default:chest", { description = "Chest", tiles = {"default_chest_top.png", "default_chest_top.png", "default_chest_side.png", @@ -1739,26 +1775,23 @@ minetest.register_node("default:chest_locked", { can_dig = function(pos,player) local meta = minetest.get_meta(pos); local inv = meta:get_inventory() - return inv:is_empty("main") and has_locked_chest_privilege(meta, player) + return inv:is_empty("main") and default.can_interact_with_node(player, pos) end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then + if not default.can_interact_with_node(player, pos) then return 0 end return count end, allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then + if not default.can_interact_with_node(player, pos) then return 0 end return stack:get_count() end, allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local meta = minetest.get_meta(pos) - if not has_locked_chest_privilege(meta, player) then + if not default.can_interact_with_node(player, pos) then return 0 end return stack:get_count() @@ -1774,8 +1807,7 @@ minetest.register_node("default:chest_locked", { " from locked chest at " .. minetest.pos_to_string(pos)) end, on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - local meta = minetest.get_meta(pos) - if has_locked_chest_privilege(meta, clicker) then + if default.can_interact_with_node(clicker, pos) then minetest.show_formspec( clicker:get_player_name(), "default:chest_locked", @@ -1788,9 +1820,13 @@ minetest.register_node("default:chest_locked", { on_key_use = function(pos, player) local secret = minetest.get_meta(pos):get_string("key_lock_secret") local itemstack = player:get_wielded_item() - local key_meta = minetest.parse_json(itemstack:get_metadata()) + local key_meta = itemstack:get_meta() - if secret ~= key_meta.secret then + if key_meta:get_string("secret") == "" then + key_meta:set_string("secret", minetest.parse_json(itemstack:get_metadata()).secret) + end + + if secret ~= key_meta:get_string("secret") then return end @@ -2101,6 +2137,27 @@ minetest.register_node("default:meselamp", { light_source = default.LIGHT_MAX, }) +minetest.register_node("default:mese_post_light", { + description = "Mese Post Light", + tiles = {"default_mese_post_light_top.png", "default_mese_post_light_top.png", + "default_mese_post_light_side_dark.png", "default_mese_post_light_side_dark.png", + "default_mese_post_light_side.png", "default_mese_post_light_side.png"}, + wield_image = "default_mese_post_light_side.png", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-2 / 16, -8 / 16, -2 / 16, 2 / 16, 8 / 16, 2 / 16}, + }, + }, + paramtype = "light", + light_source = default.LIGHT_MAX, + sunlight_propagates = true, + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults(), +}) + -- -- Misc -- @@ -2112,3 +2169,57 @@ minetest.register_node("default:cloud", { sounds = default.node_sound_defaults(), groups = {not_in_creative_inventory = 1}, }) + +-- +-- register trees for leafdecay +-- + +if minetest.get_mapgen_setting("mg_name") == "v6" then + default.register_leafdecay({ + trunks = {"default:tree"}, + leaves = {"default:apple", "default:leaves"}, + radius = 2, + }) + + default.register_leafdecay({ + trunks = {"default:jungletree"}, + leaves = {"default:jungleleaves"}, + radius = 3, + }) + + default.register_leafdecay({ + trunks = {"default:pine_tree"}, + leaves = {"default:pine_needles"}, + radius = 3, + }) +else + default.register_leafdecay({ + trunks = {"default:tree"}, + leaves = {"default:apple", "default:leaves"}, + radius = 3, + }) + + default.register_leafdecay({ + trunks = {"default:jungletree"}, + leaves = {"default:jungleleaves"}, + radius = 2, + }) + + default.register_leafdecay({ + trunks = {"default:pine_tree"}, + leaves = {"default:pine_needles"}, + radius = 2, + }) +end + +default.register_leafdecay({ + trunks = {"default:acacia_tree"}, + leaves = {"default:acacia_leaves"}, + radius = 2, +}) + +default.register_leafdecay({ + trunks = {"default:aspen_tree"}, + leaves = {"default:aspen_leaves"}, + radius = 2, +}) diff --git a/mods/default/schematics/acacia_log.mts b/mods/default/schematics/acacia_log.mts new file mode 100644 index 00000000..037bca8c Binary files /dev/null and b/mods/default/schematics/acacia_log.mts differ diff --git a/mods/default/schematics/apple_log.mts b/mods/default/schematics/apple_log.mts new file mode 100644 index 00000000..e7ee8f2b Binary files /dev/null and b/mods/default/schematics/apple_log.mts differ diff --git a/mods/default/schematics/apple_tree.mts b/mods/default/schematics/apple_tree.mts index ac09b466..2bd57c1f 100644 Binary files a/mods/default/schematics/apple_tree.mts and b/mods/default/schematics/apple_tree.mts differ diff --git a/mods/default/schematics/apple_tree_from_sapling.mts b/mods/default/schematics/apple_tree_from_sapling.mts index 5d35a154..d258ab1a 100644 Binary files a/mods/default/schematics/apple_tree_from_sapling.mts and b/mods/default/schematics/apple_tree_from_sapling.mts differ diff --git a/mods/default/schematics/aspen_log.mts b/mods/default/schematics/aspen_log.mts new file mode 100644 index 00000000..180e6fd1 Binary files /dev/null and b/mods/default/schematics/aspen_log.mts differ diff --git a/mods/default/schematics/aspen_tree.mts b/mods/default/schematics/aspen_tree.mts index 724aae08..429a831c 100644 Binary files a/mods/default/schematics/aspen_tree.mts and b/mods/default/schematics/aspen_tree.mts differ diff --git a/mods/default/schematics/aspen_tree_from_sapling.mts b/mods/default/schematics/aspen_tree_from_sapling.mts index b7ca1619..b7ab3ee6 100644 Binary files a/mods/default/schematics/aspen_tree_from_sapling.mts and b/mods/default/schematics/aspen_tree_from_sapling.mts differ diff --git a/mods/default/schematics/jungle_log.mts b/mods/default/schematics/jungle_log.mts new file mode 100644 index 00000000..54fa16d1 Binary files /dev/null and b/mods/default/schematics/jungle_log.mts differ diff --git a/mods/default/schematics/jungle_tree.mts b/mods/default/schematics/jungle_tree.mts index 329364a8..01a1b11a 100644 Binary files a/mods/default/schematics/jungle_tree.mts and b/mods/default/schematics/jungle_tree.mts differ diff --git a/mods/default/schematics/jungle_tree_from_sapling.mts b/mods/default/schematics/jungle_tree_from_sapling.mts index babaa45f..f93f0141 100644 Binary files a/mods/default/schematics/jungle_tree_from_sapling.mts and b/mods/default/schematics/jungle_tree_from_sapling.mts differ diff --git a/mods/default/schematics/pine_log.mts b/mods/default/schematics/pine_log.mts new file mode 100644 index 00000000..744c38b0 Binary files /dev/null and b/mods/default/schematics/pine_log.mts differ diff --git a/mods/default/schematics/pine_tree.mts b/mods/default/schematics/pine_tree.mts index 3a3fa7ad..6f27d839 100644 Binary files a/mods/default/schematics/pine_tree.mts and b/mods/default/schematics/pine_tree.mts differ diff --git a/mods/default/schematics/pine_tree_from_sapling.mts b/mods/default/schematics/pine_tree_from_sapling.mts index 629c5da0..e42a9965 100644 Binary files a/mods/default/schematics/pine_tree_from_sapling.mts and b/mods/default/schematics/pine_tree_from_sapling.mts differ diff --git a/mods/default/textures/default_desert_sandstone.png b/mods/default/textures/default_desert_sandstone.png new file mode 100644 index 00000000..52e445fa Binary files /dev/null and b/mods/default/textures/default_desert_sandstone.png differ diff --git a/mods/default/textures/default_desert_sandstone_block.png b/mods/default/textures/default_desert_sandstone_block.png new file mode 100644 index 00000000..8fc54e75 Binary files /dev/null and b/mods/default/textures/default_desert_sandstone_block.png differ diff --git a/mods/default/textures/default_desert_sandstone_brick.png b/mods/default/textures/default_desert_sandstone_brick.png new file mode 100644 index 00000000..ab58db52 Binary files /dev/null and b/mods/default/textures/default_desert_sandstone_brick.png differ diff --git a/mods/default/textures/default_flint.png b/mods/default/textures/default_flint.png index 3211db15..226c7406 100644 Binary files a/mods/default/textures/default_flint.png and b/mods/default/textures/default_flint.png differ diff --git a/mods/default/textures/default_grass_1.png b/mods/default/textures/default_grass_1.png index 5ed8388b..e9faa2c3 100644 Binary files a/mods/default/textures/default_grass_1.png and b/mods/default/textures/default_grass_1.png differ diff --git a/mods/default/textures/default_grass_2.png b/mods/default/textures/default_grass_2.png index 0ffa8fc2..03729a00 100644 Binary files a/mods/default/textures/default_grass_2.png and b/mods/default/textures/default_grass_2.png differ diff --git a/mods/default/textures/default_grass_3.png b/mods/default/textures/default_grass_3.png index 101fefaa..92ca1b5d 100644 Binary files a/mods/default/textures/default_grass_3.png and b/mods/default/textures/default_grass_3.png differ diff --git a/mods/default/textures/default_grass_4.png b/mods/default/textures/default_grass_4.png index 72c721af..c782a33b 100644 Binary files a/mods/default/textures/default_grass_4.png and b/mods/default/textures/default_grass_4.png differ diff --git a/mods/default/textures/default_grass_5.png b/mods/default/textures/default_grass_5.png index 7fd68388..b727e9cf 100644 Binary files a/mods/default/textures/default_grass_5.png and b/mods/default/textures/default_grass_5.png differ diff --git a/mods/default/textures/default_key.png b/mods/default/textures/default_key.png index d59bfb6b..783d3139 100644 Binary files a/mods/default/textures/default_key.png and b/mods/default/textures/default_key.png differ diff --git a/mods/default/textures/default_key_skeleton.png b/mods/default/textures/default_key_skeleton.png index eafcc195..2b3497d3 100644 Binary files a/mods/default/textures/default_key_skeleton.png and b/mods/default/textures/default_key_skeleton.png differ diff --git a/mods/default/textures/default_ladder_steel.png b/mods/default/textures/default_ladder_steel.png index 1cc6dfde..a312f3e8 100644 Binary files a/mods/default/textures/default_ladder_steel.png and b/mods/default/textures/default_ladder_steel.png differ diff --git a/mods/default/textures/default_mese_post_light_side.png b/mods/default/textures/default_mese_post_light_side.png new file mode 100644 index 00000000..c23b551a Binary files /dev/null and b/mods/default/textures/default_mese_post_light_side.png differ diff --git a/mods/default/textures/default_mese_post_light_side_dark.png b/mods/default/textures/default_mese_post_light_side_dark.png new file mode 100644 index 00000000..c4fc7cea Binary files /dev/null and b/mods/default/textures/default_mese_post_light_side_dark.png differ diff --git a/mods/default/textures/default_mese_post_light_top.png b/mods/default/textures/default_mese_post_light_top.png new file mode 100644 index 00000000..6834bd36 Binary files /dev/null and b/mods/default/textures/default_mese_post_light_top.png differ diff --git a/mods/default/textures/default_rainforest_litter.png b/mods/default/textures/default_rainforest_litter.png new file mode 100644 index 00000000..d762deb4 Binary files /dev/null and b/mods/default/textures/default_rainforest_litter.png differ diff --git a/mods/default/textures/default_rainforest_litter_side.png b/mods/default/textures/default_rainforest_litter_side.png new file mode 100644 index 00000000..7ccb11de Binary files /dev/null and b/mods/default/textures/default_rainforest_litter_side.png differ diff --git a/mods/default/textures/default_sign_steel.png b/mods/default/textures/default_sign_steel.png index 5705c787..3ca0c59d 100644 Binary files a/mods/default/textures/default_sign_steel.png and b/mods/default/textures/default_sign_steel.png differ diff --git a/mods/default/textures/default_sign_wall_steel.png b/mods/default/textures/default_sign_wall_steel.png index d8d4a5b0..2227477f 100644 Binary files a/mods/default/textures/default_sign_wall_steel.png and b/mods/default/textures/default_sign_wall_steel.png differ diff --git a/mods/default/textures/default_sign_wall_wood.png b/mods/default/textures/default_sign_wall_wood.png index f25a67a8..40552c73 100644 Binary files a/mods/default/textures/default_sign_wall_wood.png and b/mods/default/textures/default_sign_wall_wood.png differ diff --git a/mods/default/textures/default_sign_wood.png b/mods/default/textures/default_sign_wood.png index a25a4c34..d0559dac 100644 Binary files a/mods/default/textures/default_sign_wood.png and b/mods/default/textures/default_sign_wood.png differ diff --git a/mods/default/textures/default_silver_sandstone.png b/mods/default/textures/default_silver_sandstone.png new file mode 100644 index 00000000..cb4f404a Binary files /dev/null and b/mods/default/textures/default_silver_sandstone.png differ diff --git a/mods/default/textures/default_silver_sandstone_block.png b/mods/default/textures/default_silver_sandstone_block.png new file mode 100644 index 00000000..f33ea683 Binary files /dev/null and b/mods/default/textures/default_silver_sandstone_block.png differ diff --git a/mods/default/textures/default_silver_sandstone_brick.png b/mods/default/textures/default_silver_sandstone_brick.png new file mode 100644 index 00000000..711d9635 Binary files /dev/null and b/mods/default/textures/default_silver_sandstone_brick.png differ diff --git a/mods/default/textures/default_snow_side.png b/mods/default/textures/default_snow_side.png index f95b3af8..03456c84 100644 Binary files a/mods/default/textures/default_snow_side.png and b/mods/default/textures/default_snow_side.png differ diff --git a/mods/default/textures/default_snowball.png b/mods/default/textures/default_snowball.png index e952b79c..3a4dc1f6 100644 Binary files a/mods/default/textures/default_snowball.png and b/mods/default/textures/default_snowball.png differ diff --git a/mods/default/tools.lua b/mods/default/tools.lua index 58b87fc5..816a6475 100644 --- a/mods/default/tools.lua +++ b/mods/default/tools.lua @@ -384,12 +384,21 @@ minetest.register_tool("default:skeleton_key", { inventory_image = "default_key_skeleton.png", groups = {key = 1}, on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if def and def.on_rightclick and + not (placer and placer:get_player_control().sneak) then + return def.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + if pointed_thing.type ~= "node" then return itemstack end local pos = pointed_thing.under - local node = minetest.get_node(pos) + node = minetest.get_node(pos) if not node then return itemstack @@ -410,9 +419,10 @@ minetest.register_tool("default:skeleton_key", { -- finish and return the new key itemstack:take_item() itemstack:add_item("default:key") - itemstack:set_metadata(minetest.write_json({ - secret = secret - })) + local meta = itemstack:get_meta() + meta:set_string("secret", secret) + meta:set_string("description", "Key to "..placer:get_player_name().."'s " + ..minetest.registered_nodes[node.name].description) return itemstack end end @@ -426,12 +436,20 @@ minetest.register_tool("default:key", { groups = {key = 1, not_in_creative_inventory = 1}, stack_max = 1, on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if def and def.on_rightclick and + not (placer and placer:get_player_control().sneak) then + return def.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end if pointed_thing.type ~= "node" then return itemstack end local pos = pointed_thing.under - local node = minetest.get_node(pos) + node = minetest.get_node(pos) if not node or node.name == "ignore" then return itemstack diff --git a/mods/default/torch.lua b/mods/default/torch.lua index e94c5bd6..3c3ae965 100644 --- a/mods/default/torch.lua +++ b/mods/default/torch.lua @@ -50,7 +50,7 @@ minetest.register_node("default:torch", { sunlight_propagates = true, walkable = false, liquids_pointable = false, - light_source = 13, + light_source = 12, groups = {choppy=2, dig_immediate=3, flammable=1, attached_node=1, torch=1}, drop = "default:torch", selection_box = { @@ -97,7 +97,7 @@ minetest.register_node("default:torch_wall", { paramtype2 = "wallmounted", sunlight_propagates = true, walkable = false, - light_source = 13, + light_source = 12, groups = {choppy=2, dig_immediate=3, flammable=1, not_in_creative_inventory=1, attached_node=1, torch=1}, drop = "default:torch", selection_box = { @@ -118,7 +118,7 @@ minetest.register_node("default:torch_ceiling", { paramtype2 = "wallmounted", sunlight_propagates = true, walkable = false, - light_source = 13, + light_source = 12, groups = {choppy=2, dig_immediate=3, flammable=1, not_in_creative_inventory=1, attached_node=1, torch=1}, drop = "default:torch", selection_box = { @@ -144,4 +144,3 @@ minetest.register_lbm({ end end }) - diff --git a/mods/default/trees.lua b/mods/default/trees.lua index 0b95742c..5f4d3f1e 100644 --- a/mods/default/trees.lua +++ b/mods/default/trees.lua @@ -27,8 +27,7 @@ end -- 'is snow nearby' function local function is_snow_nearby(pos) - return minetest.find_node_near(pos, 1, - {"default:snow", "default:snowblock", "default:dirt_with_snow"}) + return minetest.find_node_near(pos, 1, {"group:snowy"}) end @@ -373,7 +372,7 @@ function default.grow_new_apple_tree(pos) local path = minetest.get_modpath("default") .. "/schematics/apple_tree_from_sapling.mts" minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, - path, "0", nil, false) + path, "random", nil, false) end diff --git a/mods/doors/init.lua b/mods/doors/init.lua index 9924ae10..62b43edd 100644 --- a/mods/doors/init.lua +++ b/mods/doors/init.lua @@ -144,9 +144,14 @@ function _doors.door_toggle(pos, node, clicker) local item = clicker:get_wielded_item() local owner = meta:get_string("doors_owner") if item:get_name() == "default:key" then - local key_meta = minetest.parse_json(item:get_metadata()) + local key_meta = item:get_meta() local secret = meta:get_string("key_lock_secret") - if secret ~= key_meta.secret then + + if key_meta:get_string("secret") == "" then + key_meta:set_string("secret", minetest.parse_json(item:get_metadata()).secret) + end + + if secret ~= key_meta:get_string("secret") then return false end @@ -265,7 +270,8 @@ function doors.register(name, def) local node = minetest.get_node(pointed_thing.under) local pdef = minetest.registered_nodes[node.name] - if pdef and pdef.on_rightclick then + if pdef and pdef.on_rightclick and + not placer:get_player_control().sneak then return pdef.on_rightclick(pointed_thing.under, node, placer, itemstack, pointed_thing) end @@ -375,7 +381,9 @@ function doors.register(name, def) minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) minetest.check_for_falling({x = pos.x, y = pos.y + 1, z = pos.z}) end - def.on_rotate = false + def.on_rotate = function(pos, node, user, mode, new_param2) + return false + end if def.protected then def.can_dig = can_dig_door @@ -529,9 +537,14 @@ function _doors.trapdoor_toggle(pos, node, clicker) local meta = minetest.get_meta(pos) local owner = meta:get_string("doors_owner") if item:get_name() == "default:key" then - local key_meta = minetest.parse_json(item:get_metadata()) + local key_meta = item:get_meta() local secret = meta:get_string("key_lock_secret") - if secret ~= key_meta.secret then + + if key_meta:get_string("secret") == "" then + key_meta:set_string("secret", minetest.parse_json(item:get_metadata()).secret) + end + + if secret ~= key_meta:get_string("secret") then return false end diff --git a/mods/doors/textures/doors_door_glass.png b/mods/doors/textures/doors_door_glass.png index f597299b..26c427b9 100644 Binary files a/mods/doors/textures/doors_door_glass.png and b/mods/doors/textures/doors_door_glass.png differ diff --git a/mods/doors/textures/doors_door_obsidian_glass.png b/mods/doors/textures/doors_door_obsidian_glass.png index 107a5a1a..07ac5b20 100644 Binary files a/mods/doors/textures/doors_door_obsidian_glass.png and b/mods/doors/textures/doors_door_obsidian_glass.png differ diff --git a/mods/dye/init.lua b/mods/dye/init.lua index d414d77c..87f31d12 100644 --- a/mods/dye/init.lua +++ b/mods/dye/init.lua @@ -74,36 +74,40 @@ minetest.register_craft({ }) -- Mix recipes --- Just mix everything to everything somehow sanely - -local mixbases = {"pink", "magenta", "red", "orange", "brown", "yellow", "green", "dark_green", "cyan", "blue", "violet", "black", "dark_grey", "grey", "white"} - -local mixes = { - -- pink, magenta, red, orange, brown, yellow, green, dark_green, cyan, blue, violet, black, dark_grey, grey, white - white = {"pink", "pink", "pink", "orange", "orange", "yellow", "green", "green", "grey", "cyan", "violet","grey", "grey", "grey","white"}, - grey = {"pink", "pink", "pink", "orange", "orange", "yellow", "green", "green", "grey", "cyan", "violet","dark_grey","grey", "grey"}, - dark_grey = {"brown", "brown", "brown", "brown", "brown", "brown", "dark_green","dark_green","blue", "blue", "violet","black", "dark_grey"}, - black = {"black", "black", "black", "black", "black", "black", "black", "black", "black","black", "black", "black"}, - violet = {"magenta","magenta","magenta","red", "brown", "red", "cyan", "brown", "blue", "violet","violet"}, - blue = {"violet", "violet", "magenta","brown", "brown", "dark_green","cyan", "cyan", "cyan", "blue"}, - cyan = {"brown", "blue", "brown", "dark_green","dark_grey", "green", "cyan", "dark_green","cyan"}, - dark_green = {"brown", "brown", "brown", "brown", "brown", "green", "green", "dark_green"}, - green = {"yellow", "brown", "yellow", "yellow", "dark_green","green", "green"}, - yellow = {"orange", "red", "orange", "yellow", "orange", "yellow"}, - brown = {"brown", "brown", "brown", "orange", "brown"}, - orange = {"orange", "red", "orange", "orange"}, - red = {"pink", "magenta","red"}, - magenta = {"magenta","magenta"}, - pink = {"pink"}, +local dye_recipes = { + -- src1, src2, dst + -- RYB mixes + {"red", "blue", "violet"}, -- "purple" + {"yellow", "red", "orange"}, + {"yellow", "blue", "green"}, + -- RYB complementary mixes + {"red", "green", "dark_grey"}, + {"yellow", "violet", "dark_grey"}, + {"blue", "orange", "dark_grey"}, + -- CMY mixes - approximation + {"cyan", "yellow", "green"}, + {"cyan", "magenta", "blue"}, + {"yellow", "magenta", "red"}, + -- other mixes that result in a color we have + {"red", "green", "brown"}, + {"magenta", "blue", "violet"}, + {"green", "blue", "cyan"}, + {"pink", "violet", "magenta"}, + -- mixes with black + {"white", "black", "grey"}, + {"grey", "black", "dark_grey"}, + {"green", "black", "dark_green"}, + {"orange", "black", "brown"}, + -- mixes with white + {"white", "red", "pink"}, + {"white", "dark_grey", "grey"}, + {"white", "dark_green", "green"}, } -for one, results in pairs(mixes) do - for i, result in ipairs(results) do - local another = mixbases[i] - minetest.register_craft({ - type = "shapeless", - output = 'dye:' .. result .. ' 2', - recipe = {'dye:' .. one, 'dye:' .. another}, - }) - end +for _, mix in pairs(dye_recipes) do + minetest.register_craft({ + type = "shapeless", + output = 'dye:' .. mix[3] .. ' 2', + recipe = {'dye:' .. mix[1], 'dye:' .. mix[2]}, + }) end diff --git a/mods/farming b/mods/farming deleted file mode 160000 index cac6a518..00000000 --- a/mods/farming +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cac6a518ca8652744d5aeb1bae5652b5d1895429 diff --git a/mods/fire/init.lua b/mods/fire/init.lua index bee487a5..a846b289 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -24,7 +24,7 @@ minetest.register_node("fire:basic_flame", { }, inventory_image = "fire_basic_flame.png", paramtype = "light", - light_source = 14, + light_source = 13, walkable = false, buildable_to = true, sunlight_propagates = true, @@ -44,9 +44,6 @@ minetest.register_node("fire:basic_flame", { on_construct = function(pos) minetest.get_node_timer(pos):start(math.random(30, 60)) end, - - on_blast = function() -- Unaffected by explosions - end, }) minetest.register_node("fire:permanent_flame", { @@ -65,16 +62,13 @@ minetest.register_node("fire:permanent_flame", { }, inventory_image = "fire_basic_flame.png", paramtype = "light", - light_source = 14, + light_source = 13, walkable = false, buildable_to = true, sunlight_propagates = true, damage_per_second = 4, groups = {igniter = 2, dig_immediate = 3}, drop = "", - - on_blast = function() -- Unaffected by explosions - end, }) @@ -86,27 +80,27 @@ minetest.register_tool("fire:flint_and_steel", { sound = {breaks = "default_tool_breaks"}, on_use = function(itemstack, user, pointed_thing) - local pt = pointed_thing + local sound_pos = pointed_thing.above or user:get_pos() minetest.sound_play( "fire_flint_and_steel", - {pos = pt.above, gain = 0.5, max_hear_distance = 8} + {pos = sound_pos, gain = 0.5, max_hear_distance = 8} ) - if pt.type == "node" then - local node_under = minetest.get_node(pt.under).name + if pointed_thing.type == "node" then + local node_under = minetest.get_node(pointed_thing.under).name local nodedef = minetest.registered_nodes[node_under] if not nodedef then return end local player_name = user:get_player_name() - if minetest.is_protected(pt.under, player_name) then + if minetest.is_protected(pointed_thing.under, player_name) then minetest.chat_send_player(player_name, "This area is protected") return end if nodedef.on_ignite then - nodedef.on_ignite(pt.under, user) + nodedef.on_ignite(pointed_thing.under, user) elseif minetest.get_item_group(node_under, "flammable") >= 1 - and minetest.get_node(pt.above).name == "air" then - minetest.set_node(pt.above, {name = "fire:basic_flame"}) + and minetest.get_node(pointed_thing.above).name == "air" then + minetest.set_node(pointed_thing.above, {name = "fire:basic_flame"}) end end if not minetest.setting_getbool("creative_mode") then @@ -115,7 +109,7 @@ minetest.register_tool("fire:flint_and_steel", { itemstack:add_wear(1000) -- Tool break sound if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then - minetest.sound_play(wdef.sound.breaks, {pos = pt.above, gain = 0.5}) + minetest.sound_play(wdef.sound.breaks, {pos = sound_pos, gain = 0.5}) end return itemstack end diff --git a/mods/fire/textures/fire_flint_steel.png b/mods/fire/textures/fire_flint_steel.png index 624f5565..c262ebc0 100644 Binary files a/mods/fire/textures/fire_flint_steel.png and b/mods/fire/textures/fire_flint_steel.png differ diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua index 763265ed..f92da9d8 100644 --- a/mods/flowers/init.lua +++ b/mods/flowers/init.lua @@ -265,7 +265,7 @@ minetest.register_node("flowers:waterlily", { node_placement_prediction = "", node_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, -15 / 32, 0.5} + fixed = {-0.5, -31 / 64, -0.5, 0.5, -15 / 32, 0.5} }, selection_box = { type = "fixed", diff --git a/mods/flowers/textures/flowers_waterlily.png b/mods/flowers/textures/flowers_waterlily.png index a92d3b9f..305c4458 100644 Binary files a/mods/flowers/textures/flowers_waterlily.png and b/mods/flowers/textures/flowers_waterlily.png differ diff --git a/mods/killme/init.lua b/mods/killme/init.lua new file mode 100644 index 00000000..06aa39de --- /dev/null +++ b/mods/killme/init.lua @@ -0,0 +1,24 @@ +minetest.register_chatcommand("killme", { + description = "Kill yourself to respawn", + func = function(name) + local player = minetest.get_player_by_name(name) + if player then + if minetest.setting_getbool("enable_damage") then + player:set_hp(0) + return true + else + for _, callback in pairs(core.registered_on_respawnplayers) do + if callback(player) then + return true + end + end + + -- There doesn't seem to be a way to get a default spawn pos from the lua API + return false, "No static_spawnpoint defined" + end + else + -- Show error message if used when not logged in, eg: from IRC mod + return false, "You need to be online to be killed!" + end + end +}) diff --git a/mods/screwdriver/init.lua b/mods/screwdriver/init.lua index 17c1ce16..7af01bfa 100644 --- a/mods/screwdriver/init.lua +++ b/mods/screwdriver/init.lua @@ -52,7 +52,8 @@ screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) local new_param2 = preservePart + rotationPart local should_rotate = true - if ndef and ndef.on_rotate then -- Node provides a handler, so let the handler decide instead if the node can be rotated + -- Node provides a handler, so let the handler decide instead if the node can be rotated + if ndef and ndef.on_rotate then -- Copy pos and node because callback can modify it local result = ndef.on_rotate(vector.new(pos), {name = node.name, param1 = node.param1, param2 = node.param2}, @@ -66,7 +67,7 @@ screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) if not ndef or not ndef.paramtype2 == "facedir" or ndef.on_rotate == false or (ndef.drawtype == "nodebox" and - not ndef.node_box.type == "fixed") or + (ndef.node_box and ndef.node_box.type ~= "fixed")) or node.param2 == nil then return end diff --git a/mods/sfinv/api.lua b/mods/sfinv/api.lua index 2fef3c84..ff6433b9 100644 --- a/mods/sfinv/api.lua +++ b/mods/sfinv/api.lua @@ -70,7 +70,7 @@ function sfinv.get_formspec(player, context) nav[#nav + 1] = pdef.title nav_ids[#nav_ids + 1] = pdef.name if pdef.name == context.page then - current_idx = i + current_idx = #nav_ids end end end @@ -91,22 +91,42 @@ function sfinv.get_formspec(player, context) end end -function sfinv.set_player_inventory_formspec(player, context) +function sfinv.get_or_create_context(player) + local name = player:get_player_name() + local context = sfinv.contexts[name] if not context then - local name = player:get_player_name() - context = sfinv.contexts[name] - if not context then - context = { - page = sfinv.get_homepage_name(player) - } - sfinv.contexts[name] = context - end + context = { + page = sfinv.get_homepage_name(player) + } + sfinv.contexts[name] = context end + return context +end - local fs = sfinv.get_formspec(player, context) +function sfinv.set_context(player, context) + sfinv.contexts[player:get_player_name()] = context +end + +function sfinv.set_player_inventory_formspec(player, context) + local fs = sfinv.get_formspec(player, + context or sfinv.get_or_create_context(player)) player:set_inventory_formspec(fs) end +function sfinv.set_page(player, pagename) + local context = sfinv.get_or_create_context(player) + local oldpage = sfinv.pages[context.page] + if oldpage and oldpage.on_leave then + oldpage:on_leave(player, context) + end + context.page = pagename + local page = sfinv.pages[pagename] + if page.on_enter then + page:on_enter(player, context) + end + sfinv.set_player_inventory_formspec(player, context) +end + minetest.register_on_joinplayer(function(player) if sfinv.enabled then minetest.after(0.5, function() @@ -132,30 +152,21 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) return false end - -- Handle Events + -- Was a tab selected? if fields.tabs and context.nav then local tid = tonumber(fields.tabs) if tid and tid > 0 then local id = context.nav[tid] local page = sfinv.pages[id] if id and page then - local oldpage = sfinv.pages[context.page] - if oldpage and oldpage.on_leave then - oldpage:on_leave(player, context) - end - context.page = id - if page.on_enter then - page:on_enter(player, context) - end - sfinv.set_player_inventory_formspec(player, context) + sfinv.set_page(player, id) end end - return - end - - -- Pass to page - local page = sfinv.pages[context.page] - if page and page.on_player_receive_fields then - return page:on_player_receive_fields(player, context, fields) + else + -- Pass event to page + local page = sfinv.pages[context.page] + if page and page.on_player_receive_fields then + return page:on_player_receive_fields(player, context, fields) + end end end) diff --git a/mods/stairs/init.lua b/mods/stairs/init.lua index a4e343cf..0606916a 100644 --- a/mods/stairs/init.lua +++ b/mods/stairs/init.lua @@ -447,6 +447,66 @@ stairs.register_stair_and_slab( default.node_sound_stone_defaults() ) +stairs.register_stair_and_slab( + "desert_sandstone", + "default:desert_sandstone", + {crumbly = 1, cracky = 3}, + {"default_desert_sandstone.png"}, + "Desert Sandstone Stair", + "Desert Sandstone Slab", + default.node_sound_stone_defaults() +) + +stairs.register_stair_and_slab( + "desert_sandstone_brick", + "default:desert_sandstone_brick", + {cracky = 2}, + {"default_desert_sandstone_brick.png"}, + "Desert Sandstone Brick Stair", + "Desert Sandstone Brick Slab", + default.node_sound_stone_defaults() +) + +stairs.register_stair_and_slab( + "desert_sandstone_block", + "default:desert_sandstone_block", + {cracky = 2}, + {"default_desert_sandstone_block.png"}, + "Desert Sandstone Block Stair", + "Desert Sandstone Block Slab", + default.node_sound_stone_defaults() +) + +stairs.register_stair_and_slab( + "silver_sandstone", + "default:silver_sandstone", + {crumbly = 1, cracky = 3}, + {"default_silver_sandstone.png"}, + "Silver Sandstone Stair", + "Silver Sandstone Slab", + default.node_sound_stone_defaults() +) + +stairs.register_stair_and_slab( + "silver_sandstone_brick", + "default:silver_sandstone_brick", + {cracky = 2}, + {"default_silver_sandstone_brick.png"}, + "Silver Sandstone Brick Stair", + "Silver Sandstone Brick Slab", + default.node_sound_stone_defaults() +) + +stairs.register_stair_and_slab( + "silver_sandstone_block", + "default:silver_sandstone_block", + {cracky = 2}, + {"default_silver_sandstone_block.png"}, + "Silver Sandstone Block Stair", + "Silver Sandstone Block Slab", + default.node_sound_stone_defaults() +) + stairs.register_stair_and_slab( "obsidian", "default:obsidian", diff --git a/mods/stairs/models/stairs_stair.obj b/mods/stairs/models/stairs_stair.obj index 45882c6e..198edf6e 100644 --- a/mods/stairs/models/stairs_stair.obj +++ b/mods/stairs/models/stairs_stair.obj @@ -55,7 +55,8 @@ usemtl None s off f 13/11/3 14/12/3 15/13/3 f 15/13/3 18/14/3 17/15/3 -f 14/12/3 16/16/3 18/14/3 +f 14/12/3 16/16/3 15/13/3 +f 16/16/3 18/14/3 15/13/3 o stairs_left v 0.500000 0.000000 0.000000 v 0.500000 -0.500000 -0.500000 @@ -75,7 +76,8 @@ usemtl None s off f 19/17/4 20/18/4 21/19/4 f 19/17/4 23/20/4 24/21/4 -f 20/18/4 24/21/4 22/22/4 +f 20/18/4 19/17/4 22/22/4 +f 19/17/4 24/21/4 22/22/4 o stairs_back v -0.500000 -0.500000 0.500000 v 0.500000 -0.500000 0.500000 diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index c928fe45..46817731 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -367,6 +367,8 @@ function tnt.boom(pos, def) eject_drops(drops, pos, radius) end add_effects(pos, radius, drops) + minetest.log("action", "A TNT explosion occurred at " .. minetest.pos_to_string(pos) .. + " with radius " .. radius) end minetest.register_node("tnt:boom", { @@ -392,7 +394,12 @@ minetest.register_node("tnt:gunpowder", { is_ground_content = false, sunlight_propagates = true, walkable = false, - tiles = {"tnt_gunpowder_straight.png", "tnt_gunpowder_curved.png", "tnt_gunpowder_t_junction.png", "tnt_gunpowder_crossing.png"}, + tiles = { + "tnt_gunpowder_straight.png", + "tnt_gunpowder_curved.png", + "tnt_gunpowder_t_junction.png", + "tnt_gunpowder_crossing.png" + }, inventory_image = "tnt_gunpowder_inventory.png", wield_image = "tnt_gunpowder_inventory.png", selection_box = { @@ -408,6 +415,9 @@ minetest.register_node("tnt:gunpowder", { if(minetest.check_player_privs(puncher:get_player_name(), {trusted_player=true})) then --tnt.burn(pos) minetest.set_node(pos, {name = "tnt:gunpowder_burning"}) + minetest.log("action", puncher:get_player_name() .. + " ignites tnt:gunpowder at " .. + minetest.pos_to_string(pos)) end end end, @@ -469,7 +479,11 @@ minetest.register_node("tnt:gunpowder_burning", { fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, }, drop = "", - groups = {dig_immediate = 2, attached_node = 1, connect_to_raillike = minetest.raillike_group("gunpowder")}, + groups = { + dig_immediate = 2, + attached_node = 1, + connect_to_raillike = minetest.raillike_group("gunpowder") + }, sounds = default.node_sound_leaves_defaults(), on_timer = function(pos, elapsed) for dx = -1, 1 do @@ -496,7 +510,7 @@ minetest.register_node("tnt:gunpowder_burning", { }) minetest.register_craft({ - output = "tnt:gunpowder", + output = "tnt:gunpowder 5", type = "shapeless", groups = {gunpowder = 1}, recipe = {"default:coal_lump", "default:gravel"} @@ -505,22 +519,22 @@ minetest.register_craft({ minetest.register_craft({ output = "tnt:tnt", recipe = { - {"", "group:wood", ""}, - {"group:wood", "tnt:gunpowder", "group:wood"}, - {"", "group:wood", ""} + {"group:wood", "tnt:gunpowder", "group:wood"}, + {"tnt:gunpowder", "tnt:gunpowder", "tnt:gunpowder"}, + {"group:wood", "tnt:gunpowder", "group:wood"} } }) - minetest.register_abm({ - label = "TNT ignition", - nodenames = {"group:tnt", "tnt:gunpowder"}, - neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, - interval = 4, - chance = 1, - action = function(pos, node) - tnt.burn(pos, node.name) - end, - }) +minetest.register_abm({ + label = "TNT ignition", + nodenames = {"group:tnt", "tnt:gunpowder"}, + neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, + interval = 4, + chance = 1, + action = function(pos, node) + tnt.burn(pos, node.name) + end, +}) function tnt.register_tnt(def) local name @@ -547,6 +561,9 @@ function tnt.register_tnt(def) on_punch = function(pos, node, puncher) if puncher:get_wielded_item():get_name() == "default:torch" then minetest.set_node(pos, {name = name .. "_burning"}) + minetest.log("action", puncher:get_player_name() .. + " ignites " .. node.name .. " at " .. + minetest.pos_to_string(pos)) end end, on_blast = function(pos, intensity)