commit fb98659b03779eb361e4648ae02dc642273bef28 Author: NathanSalapat Date: Sun Jun 14 18:29:10 2020 -0500 initial upload diff --git a/.stignore b/.stignore new file mode 100644 index 0000000..6b8710a --- /dev/null +++ b/.stignore @@ -0,0 +1 @@ +.git diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..48f0b8d --- /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.conf b/game.conf new file mode 100644 index 0000000..feebefc --- /dev/null +++ b/game.conf @@ -0,0 +1,3 @@ +name = Epic +author = Nathan Salapat +description = Based off of MTG with a bunch of custom mods. diff --git a/game_api.txt b/game_api.txt new file mode 100644 index 0000000..3f31133 --- /dev/null +++ b/game_api.txt @@ -0,0 +1,1076 @@ +Minetest Game API +================= +GitHub Repo: https://github.com/minetest/minetest_game + + +Introduction +------------ + +The Minetest Game game offers multiple new possibilities in addition to the Minetest engine's built-in API, +allowing you to add new plants to farming mod, buckets for new liquids, new stairs and custom panes. +For information on the Minetest API, visit https://github.com/minetest/minetest/blob/master/doc/lua_api.txt +Please note: + + * [XYZ] refers to a section the Minetest API + * [#ABC] refers to a section in this document + * [pos] refers to a position table `{x = -5, y = 0, z = 200}` + + +Bucket API +---------- + +The bucket API allows registering new types of buckets for non-default liquids. + + bucket.register_liquid( + "default:lava_source", -- name of the source node + "default:lava_flowing", -- name of the flowing node + "bucket:bucket_lava", -- name of the new bucket item (or nil if liquid is not takeable) + "bucket_lava.png", -- texture of the new bucket item (ignored if itemname == nil) + "Lava Bucket", -- text description of the bucket item + {lava_bucket = 1}, -- groups of the bucket item, OPTIONAL + false -- force-renew, OPTIONAL. Force the liquid source to renew if it has + -- a source neighbour, even if defined as 'liquid_renewable = false'. + -- Needed to avoid creating holes in sloping rivers. + ) + +The filled bucket item is returned to the player that uses an empty bucket pointing to the given liquid source. +When punching with an empty bucket pointing to an entity or a non-liquid node, the on_punch of the entity or node will be triggered. + + +Beds API +-------- + + beds.register_bed( + "beds:bed", -- Bed name + def -- See [#Bed definition] + ) + + * `beds.can_dig(bed_pos)` Returns a boolean whether the bed at `bed_pos` may be dug + * `beds.read_spawns() ` Returns a table containing players respawn positions + * `beds.kick_players()` Forces all players to leave bed + * `beds.skip_night()` Sets world time to morning and saves respawn position of all players currently sleeping + +### Bed definition + + { + description = "Simple Bed", + inventory_image = "beds_bed.png", + wield_image = "beds_bed.png", + tiles = { + bottom = {'Tile definition'}, -- the tiles of the bottom part of the bed. + top = {Tile definition} -- the tiles of the bottom part of the bed. + }, + nodebox = { + bottom = 'regular nodebox', -- bottom part of bed (see [Node boxes]) + top = 'regular nodebox', -- top part of bed (see [Node boxes]) + }, + selectionbox = 'regular nodebox', -- for both nodeboxes (see [Node boxes]) + recipe = { -- Craft recipe + {"group:wool", "group:wool", "group:wool"}, + {"group:wood", "group:wood", "group:wood"} + } + } + + +Bones API +--------- + +An ordered list of listnames (default: "main", "craft") of the player inventory, +that will be placed into bones or dropped on player death can be looked up or changed +in `bones.player_inventory_lists`. + +e.g. `table.insert(bones.player_inventory_lists, "backpack")` + + +Creative API +------------ + +Use `creative.register_tab(name, title, items)` to add a tab with filtered items. +For example, + + creative.register_tab("tools", "Tools", minetest.registered_tools) + +is used to show all tools. Name is used in the sfinv page name, title is the +human readable title. + +Creative provides `creative.is_enabled_for(name)`, which is identical in +functionality to the engine's `minetest.creative_is_enabled(name)`. +Its use is deprecated and it should also not be overriden. + +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. + +Group overrides can be used for any registered item, node or tool. Use one of +the groups stated below to pick which category it will appear in. + + node = 1 -- Appears in the Nodes category + tool = 1 -- Appears in the Tools category + craftitem = 1 -- Appears in the Items category + + +Chests API +---------- + +The chests API allows the creation of chests, which have their own inventories for holding items. + +`default.chest.get_chest_formspec(pos)` + + * Returns a formspec for a specific chest. + * `pos` Location of the chest node, e.g `{x = 1, y = 1, z = 1}` + +`default.chest.chest_lid_obstructed(pos)` + + * Returns a boolean depending on whether or not a chest has its top obstructed by a solid node. + * `pos` Location of the chest node, e.g `{x = 1, y = 1, z = 1}` + +`default.chest.chest_lid_close(pn)` + + * Closes the chest that a player is currently looking in. + * `pn` The name of the player whose chest is going to be closed + +`default.chest.open_chests` + + * A table indexed by player name to keep track of who opened what chest. + * Key: The name of the player. + * Value: A table containing information about the chest the player is looking at. + e.g `{ pos = {1, 1, 1}, sound = null, swap = "default:chest" }` + +`default.chest.register_chest(name, def)` + + * Registers new chest + * `name` Name for chest e.g. "default:chest" + * `def` See [#Chest Definition] + +### Chest Definition + + description = "Chest", + tiles = { + "default_chest_top.png", + "default_chest_top.png", + "default_chest_side.png", + "default_chest_side.png", + "default_chest_front.png", + "default_chest_inside.png" + }, -- Textures which are applied to the chest model. + sounds = default.node_sound_wood_defaults(), + sound_open = "default_chest_open", + sound_close = "default_chest_close", + groups = {choppy = 2, oddly_breakable_by_hand = 2}, + protected = false, -- If true, only placer can modify chest. + + +Doors API +--------- + +The doors mod allows modders to register custom doors and trapdoors. + +`doors.registered_doors[name] = Door definition` + * Table of registered doors, indexed by door name + +`doors.registered_trapdoors[name] = Trapdoor definition` + * Table of registered trap doors, indexed by trap door name + +`doors.register_door(name, def)` + + * Registers new door + * `name` Name for door + * `def` See [#Door definition] + +`doors.register_trapdoor(name, def)` + + * Registers new trapdoor + * `name` Name for trapdoor + * `def` See [#Trapdoor definition] + +`doors.register_fencegate(name, def)` + + * Registers new fence gate + * `name` Name for fence gate + * `def` See [#Fence gate definition] + +`doors.get(pos)` + + * `pos` A position as a table, e.g `{x = 1, y = 1, z = 1}` + * Returns an ObjectRef to a door, or nil if the position does not contain a door + + ### Methods + + :open(player) -- Open the door object, returns if door was opened + :close(player) -- Close the door object, returns if door was closed + :toggle(player) -- Toggle the door state, returns if state was toggled + :state() -- returns the door state, true = open, false = closed + + the "player" parameter can be omitted in all methods. If passed then + the usual permission checks will be performed to make sure the player + has the permissions needed to open this door. If omitted then no + permission checks are performed. + +`doors.door_toggle(pos, node, clicker)` + + * Toggle door open or shut + * `pos` Position of the door + * `node` Node definition + * `clicker` Player definition for the player that clicked on the door + +### Door definition + + description = "Door description", + inventory_image = "mod_door_inv.png", + groups = {choppy = 2}, + tiles = {"mod_door.png"}, -- UV map. + -- The front and back of the door must be identical in appearence as they swap on + -- open/close. + recipe = craftrecipe, + sounds = default.node_sound_wood_defaults(), -- optional + sound_open = sound play for open door, -- optional + sound_close = sound play for close door, -- optional + protected = false, -- If true, only placer can open the door (locked for others) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + -- optional function containing the on_rightclick callback, defaults to a doors.door_toggle-wrapper + +### Trapdoor definition + + description = "Trapdoor description", + inventory_image = "mod_trapdoor_inv.png", + groups = {choppy = 2}, + tile_front = "doors_trapdoor.png", -- the texture for the front and back of the trapdoor + tile_side = "doors_trapdoor_side.png", + -- The texture for the four sides of the trapdoor. + -- The texture should have the trapdoor side drawn twice, in the lowest and highest + -- 1/8ths of the texture, both upright. The area between is not used. + -- The lower 1/8th will be used for the closed trapdoor, the higher 1/8th will be used + -- for the open trapdoor. + sounds = default.node_sound_wood_defaults(), -- optional + sound_open = sound play for open door, -- optional + sound_close = sound play for close door, -- optional + protected = false, -- If true, only placer can open the door (locked for others) + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + -- function containing the on_rightclick callback + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + -- function containing the on_rightclick callback + +### Fence gate definition + + description = "Wooden Fence Gate", + texture = "default_wood.png", -- `backface_culling` will automatically be + -- set to `true` if not specified. + material = "default:wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults(), -- optional + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + -- function containing the on_rightclick callback + + +Dungeon Loot API +---------------- + +The mod that places chests with loot in dungeons provides an API to register additional loot. + +`dungeon_loot.register(def)` + + * Registers one or more loot items + * `def` Can be a single [#Loot definition] or a list of them + +`dungeon_loot.registered_loot` + + * Table of all registered loot, not to be modified manually + +### Loot definition + + name = "item:name", + chance = 0.5, + -- ^ chance value from 0.0 to 1.0 that the item will appear in the chest when chosen + -- Due to an extra step in the selection process, 0.5 does not(!) mean that + -- on average every second chest will have this item + count = {1, 4}, + -- ^ table with minimum and maximum amounts of this item + -- optional, defaults to always single item + y = {-32768, -512}, + -- ^ table with minimum and maximum heights this item can be found at + -- optional, defaults to no height restrictions + types = {"desert"}, + -- ^ table with types of dungeons this item can be found in + -- supported types: "normal" (the cobble/mossycobble one), "sandstone" + -- "desert" and "ice" + -- optional, defaults to no type restrictions + + +Fence API +--------- + +Allows creation of new fences with "fencelike" drawtype. + +`default.register_fence(name, item definition)` + + Registers a new fence. Custom fields texture and material are required, as + are name and description. The rest is optional. You can pass most normal + nodedef fields here except drawtype. The fence group will always be added + for this node. + +### fence definition + + name = "default:fence_wood", + description = "Wooden Fence", + texture = "default_wood.png", + material = "default:wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + + +Walls API +--------- + +The walls API allows easy addition of stone auto-connecting wall nodes. + +walls.register(name, desc, texture, mat, sounds) +^ name = "walls:stone_wall". Node name. +^ desc = "A Stone wall" +^ texture = "default_stone.png" +^ mat = "default:stone". Used to auto-generate crafting recipe. +^ sounds = sounds: see [#Default sounds] + + +Farming API +----------- + +The farming API allows you to easily register plants and hoes. + +`farming.register_hoe(name, hoe definition)` + * Register a new hoe, see [#hoe definition] + +`farming.register_plant(name, Plant definition)` + * Register a new growing plant, see [#Plant definition] + +`farming.registered_plants[name] = definition` + * Table of registered plants, indexed by plant name + +### Hoe Definition + + + { + description = "", -- Description for tooltip + inventory_image = "unknown_item.png", -- Image to be used as wield- and inventory image + max_uses = 30, -- Uses until destroyed + material = "", -- Material for recipes + recipe = { -- Craft recipe, if material isn't used + {"air", "air", "air"}, + {"", "group:stick"}, + {"", "group:stick"}, + } + } + +### Plant definition + + { + description = "", -- Description of seed item + harvest_description = "", -- Description of harvest item + -- (optional, derived automatically if not provided) + inventory_image = "unknown_item.png", -- Image to be used as seed's wield- and inventory image + steps = 8, -- How many steps the plant has to grow, until it can be harvested + -- ^ Always provide a plant texture for each step, format: modname_plantname_i.png (i = stepnumber) + minlight = 13, -- Minimum light to grow + maxlight = default.LIGHT_MAX -- Maximum light to grow + } + + +Fire API +-------- + +Add group flammable when registering a node to make fire seek for it. +Add it to an item to make it burn up when dropped in lava or fire. +New node def property: + +`on_burn(pos)` + + * Called when fire attempts to remove a burning node. + * `pos` Position of the burning node. + + `on_ignite(pos, igniter)` + + * Called when Flint and steel (or a mod defined ignitor) is used on a node. + Defining it may prevent the default action (spawning flames) from triggering. + * `pos` Position of the ignited node. + * `igniter` Player that used the tool, when available. + + +Give Initial Stuff API +---------------------- + +`give_initial_stuff.give(player)` + +^ Give initial stuff to "player" + +`give_initial_stuff.add(stack)` + +^ Add item to the initial stuff +^ Stack can be an ItemStack or a item name eg: "default:dirt 99" +^ Can be called after the game has loaded + +`give_initial_stuff.clear()` + +^ Removes all items from the initial stuff +^ Can be called after the game has loaded + +`give_initial_stuff.get_list()` + +^ returns list of item stacks + +`give_initial_stuff.set_list(list)` + +^ List of initial items with numeric indices. + +`give_initial_stuff.add_from_csv(str)` + +^ str is a comma separated list of initial stuff +^ Adds items to the list of items to be given + + +Players API +----------- + +The player API can register player models and update the player's appearance. + +* `player_api.register_model(name, def)` + * Register a new model to be used by players + * name: model filename such as "character.x", "foo.b3d", etc. + * def: See [#Model definition] + * saved to player_api.registered_models + +* `player_api.registered_player_models[name]` + * Get a model's definition + * see [#Model definition] + +* `player_api.set_model(player, model_name)` + * Change a player's model + * `player`: PlayerRef + * `model_name`: model registered with player_api.register_model() + +* `player_api.set_animation(player, anim_name [, speed])` + * Applies an animation to a player + * anim_name: name of the animation. + * speed: frames per second. If nil, default from the model is used + +* `player_api.set_textures(player, textures)` + * Sets player textures + * `player`: PlayerRef + * `textures`: array of textures, If `textures` is nil the default + textures from the model def are used + +* `player_api.get_animation(player)` + * Returns a table containing fields `model`, `textures` and `animation`. + * Any of the fields of the returned table may be nil. + * player: PlayerRef + +* `player_api.player_attached` + * A table that maps a player name to a boolean. + * If the value for a given player is set to true, the default player + animations (walking, digging, ...) will no longer be updated. + Knockback from damage is also prevented for that player. + +### Model Definition + + { + animation_speed = 30, -- Default animation speed, in FPS. + textures = {"character.png", }, -- Default array of textures. + visual_size = {x = 1, y = 1}, -- Used to scale the model. + animations = { + -- = {x = , y = }, + foo = {x = 0, y = 19}, + bar = {x = 20, y = 39}, + -- ... + }, + collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}, -- In nodes from feet position + stepheight = 0.6, -- In nodes + eye_height = 1.47, -- In nodes above feet position + } + + +TNT API +------- + +`tnt.register_tnt(definition)` + +^ Register a new type of tnt. + + * `name` The name of the node. If no prefix is given `tnt` is used. + * `description` A description for your TNT. + * `radius` The radius within which the TNT can destroy nodes. The default is 3. + * `damage_radius` The radius within which the TNT can damage players and mobs. By default it is twice the `radius`. + * `sound` The sound played when explosion occurs. By default it is `tnt_explode`. + * `disable_drops` Disable drops. By default it is set to false. + * `ignore_protection` Don't check `minetest.is_protected` before removing a node. + * `ignore_on_blast` Don't call `on_blast` even if a node has one. + * `tiles` Textures for node + * `side` Side tiles. By default the name of the tnt with a suffix of `_side.png`. + * `top` Top tile. By default the name of the tnt with a suffix of `_top.png`. + * `bottom` Bottom tile. By default the name of the tnt with a suffix of `_bottom.png`. + * `burning` Top tile when lit. By default the name of the tnt with a suffix of `_top_burning_animated.png". + +`tnt.boom(position[, definition])` + +^ Create an explosion. + +* `position` The center of explosion. +* `definition` The TNT definion as passed to `tnt.register` with the following addition: + * `explode_center` false by default which removes TNT node on blast, when true will explode center node. + +`tnt.burn(position, [nodename])` + +^ Ignite node at position, triggering its `on_ignite` callback (see fire mod). +If no such callback exists, fallback to turn tnt group nodes to their +"_burning" variant. + nodename isn't required unless already known. + +To make dropping items from node inventories easier, you can use the +following helper function from 'default': + +default.get_inventory_drops(pos, inventory, drops) + +^ Return drops from node inventory "inventory" in drops. + +* `pos` - the node position +* `inventory` - the name of the inventory (string) +* `drops` - an initialized list + +The function returns no values. The drops are returned in the `drops` +parameter, and drops is not reinitialized so you can call it several +times in a row to add more inventory items to it. + + +`on_blast` callbacks: + +Both nodedefs and entitydefs can provide an `on_blast()` callback + +`nodedef.on_blast(pos, intensity)` +^ Allow drop and node removal overriding +* `pos` - node position +* `intensity` - TNT explosion measure. larger or equal to 1.0 +^ Should return a list of drops (e.g. {"default:stone"}) +^ Should perform node removal itself. If callback exists in the nodedef +^ then the TNT code will not destroy this node. + +`entitydef.on_blast(luaobj, damage)` +^ Allow TNT effects on entities to be overridden +* `luaobj` - LuaEntityRef of the entity +* `damage` - suggested HP damage value +^ Should return a list of (bool do_damage, bool do_knockback, table drops) +* `do_damage` - if true then TNT mod wil damage the entity +* `do_knockback` - if true then TNT mod will knock the entity away +* `drops` - a list of drops, e.g. {"wool:red"} + + +Screwdriver API +--------------- + +The screwdriver API allows you to control a node's behaviour when a screwdriver is used on it. +To use it, add the `on_screwdriver` function to the node definition. + +`on_rotate(pos, node, user, mode, new_param2)` + + * `pos` Position of the node that the screwdriver is being used on + * `node` that node + * `user` The player who used the screwdriver + * `mode` screwdriver.ROTATE_FACE or screwdriver.ROTATE_AXIS + * `new_param2` the new value of param2 that would have been set if on_rotate wasn't there + * return value: false to disallow rotation, nil to keep default behaviour, true to allow + it but to indicate that changed have already been made (so the screwdriver will wear out) + * use `on_rotate = false` to always disallow rotation + * use `on_rotate = screwdriver.rotate_simple` to allow only face rotation + + +Sethome API +----------- + +The sethome API adds three global functions to allow mods to read a players home position, +set a players home position and teleport a player to home position. + +`sethome.get(name)` + + * `name` Player who's home position you wish to get + * return value: false if no player home coords exist, position table if true + +`sethome.set(name, pos)` + + * `name` Player who's home position you wish to set + * `pos` Position table containing coords of home position + * return value: false if unable to set and save new home position, otherwise true + +`sethome.go(name)` + + * `name` Player you wish to teleport to their home position + * return value: false if player cannot be sent home, otherwise true + + +Sfinv API +--------- + +It is recommended that you read this link for a good introduction to the +sfinv API by its author: https://rubenwardy.com/minetest_modding_book/en/chapters/sfinv.html + +### sfinv Methods + +**Pages** + +* sfinv.set_page(player, pagename) - changes the page +* sfinv.get_page(player) - get the current page name. Will never return nil +* sfinv.get_homepage_name(player) - get the page name of the first page to show to a player +* 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 + +* pages - table of pages[pagename] = def +* pages_unordered - array table of pages in order of addition (used to build navigation tabs). +* contexts - contexts[playername] = player_context +* enabled - set to false to disable. Good for inventory rehaul mods like unified inventory + +### Context + +A table with these keys: + +* page - current page name +* nav - a list of page names +* nav_titles - a list of page titles +* nav_idx - current nav index (in nav and nav_titles) +* any thing you want to store + * sfinv will clear the stored data on log out / log in + +### sfinv.register_page + +sfinv.register_page(name, def) + +def is a table containing: + +* `title` - human readable page name (required) +* `get(self, player, context)` - returns a formspec string. See formspec variables. (required) +* `is_in_nav(self, player, context)` - return true to show in the navigation (the tab header, by default) +* `on_player_receive_fields(self, player, context, fields)` - on formspec submit. +* `on_enter(self, player, context)` - called when the player changes pages, usually using the tabs. +* `on_leave(self, player, context)` - when leaving this page to go to another, called before other's on_enter + +### get formspec + +Use sfinv.make_formspec to apply a layout: + + return sfinv.make_formspec(player, context, [[ + list[current_player;craft;1.75,0.5;3,3;] + list[current_player;craftpreview;5.75,1.5;1,1;] + image[4.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270] + listring[current_player;main] + listring[current_player;craft] + image[0,4.25;1,1;gui_hb_bg.png] + image[1,4.25;1,1;gui_hb_bg.png] + image[2,4.25;1,1;gui_hb_bg.png] + image[3,4.25;1,1;gui_hb_bg.png] + image[4,4.25;1,1;gui_hb_bg.png] + image[5,4.25;1,1;gui_hb_bg.png] + image[6,4.25;1,1;gui_hb_bg.png] + image[7,4.25;1,1;gui_hb_bg.png] + ]], true) + +See above (methods section) for more options. + +### Customising themes + +Simply override this function to change the navigation: + + function sfinv.get_nav_fs(player, context, nav, current_idx) + return "navformspec" + end + +And override this function to change the layout: + + function sfinv.make_formspec(player, context, content, show_inv, size) + local tmp = { + size or "size[8,8.6]", + theme_main, + sfinv.get_nav_fs(player, context, context.nav_titles, context.nav_idx), + content + } + if show_inv then + tmp[4] = theme_inv + end + return table.concat(tmp, "") + end + + +Stairs API +---------- + +The stairs API lets you register stairs and slabs and ensures that they are registered the same way as those +delivered with Minetest Game, to keep them compatible with other mods. + +`stairs.register_stair(subname, recipeitem, groups, images, description, sounds, worldaligntex)` + + * Registers a stair + * `subname`: Basically the material name (e.g. cobble) used for the stair name. Nodename pattern: "stairs:stair_subname" + * `recipeitem`: Item used in the craft recipe, e.g. "default:cobble", may be `nil` + * `groups`: See [Known damage and digging time defining groups] + * `images`: See [Tile definition] + * `description`: Used for the description field in the stair's definition + * `sounds`: See [#Default sounds] + * `worldaligntex`: A bool to set all textures world-aligned. Default false. See [Tile definition] + +`stairs.register_slab(subname, recipeitem, groups, images, description, sounds, worldaligntex)` + + * Registers a slab + * `subname`: Basically the material name (e.g. cobble) used for the slab name. Nodename pattern: "stairs:slab_subname" + * `recipeitem`: Item used in the craft recipe, e.g. "default:cobble" + * `groups`: See [Known damage and digging time defining groups] + * `images`: See [Tile definition] + * `description`: Used for the description field in the slab's definition + * `sounds`: See [#Default sounds] + * `worldaligntex`: A bool to set all textures world-aligned. Default false. See [Tile definition] + +`stairs.register_stair_inner(subname, recipeitem, groups, images, description, sounds, worldaligntex, full_description)` + + * Registers an inner corner stair + * `subname`: Basically the material name (e.g. cobble) used for the stair name. Nodename pattern: "stairs:stair_inner_subname" + * `recipeitem`: Item used in the craft recipe, e.g. "default:cobble", may be `nil` + * `groups`: See [Known damage and digging time defining groups] + * `images`: See [Tile definition] + * `description`: Used for the description field in the stair's definition with "Inner" prepended + * `sounds`: See [#Default sounds] + * `worldaligntex`: A bool to set all textures world-aligned. Default false. See [Tile definition] + * `full_description`: Overrides the description, bypassing string concatenation. This is useful for translation. (optional) + +`stairs.register_stair_outer(subname, recipeitem, groups, images, description, sounds, worldaligntex, full_description)` + + * Registers an outer corner stair + * `subname`: Basically the material name (e.g. cobble) used for the stair name. Nodename pattern: "stairs:stair_outer_subname" + * `recipeitem`: Item used in the craft recipe, e.g. "default:cobble", may be `nil` + * `groups`: See [Known damage and digging time defining groups] + * `images`: See [Tile definition] + * `description`: Used for the description field in the stair's definition with "Outer" prepended + * `sounds`: See [#Default sounds] + * `worldaligntex`: A bool to set all textures world-aligned. Default false. See [Tile definition] + * `full_description`: Overrides the description, bypassing string concatenation. This is useful for translation. (optional) + +`stairs.register_stair_and_slab(subname, recipeitem, groups, images, desc_stair, desc_slab, sounds, worldaligntex)` + + * A wrapper for stairs.register_stair, stairs.register_slab, stairs.register_stair_inner, stairs.register_stair_outer + * Uses almost the same arguments as stairs.register_stair + * `desc_stair`: Description for stair nodes. For corner stairs 'Inner' or 'Outer' will be prefixed + * `desc_slab`: Description for slab node + + +Xpanes API +---------- + +Creates panes that automatically connect to each other + +`xpanes.register_pane(subname, def)` + + * `subname`: used for nodename. Result: "xpanes:subname" and "xpanes:subname_{2..15}" + * `def`: See [#Pane definition] + +### Pane definition + + { + textures = { + "texture for front and back", + (unused), + "texture for the 4 edges" + }, -- More tiles aren't supported + groups = {group = rating}, -- Uses the known node groups, see [Known damage and digging time defining groups] + sounds = SoundSpec, -- See [#Default sounds] + recipe = {{"","","","","","","","",""}}, -- Recipe field only + use_texture_alpha = true, -- Optional boolean (default: `false`) for colored glass panes + } + + +Raillike definitions +-------------------- + +The following nodes use the group `connect_to_raillike` and will only connect to +raillike nodes within this group and the same group value. +Use `minetest.raillike_group()` to get the group value. + +| Node type | Raillike group name +|-----------------------|--------------------- +| default:rail | "rail" +| tnt:gunpowder | "gunpowder" +| tnt:gunpowder_burning | "gunpowder" + +Example: +If you want to add a new rail type and want it to connect with default:rail, +add `connect_to_raillike=minetest.raillike_group("rail")` into the `groups` table +of your node. + + +Default sounds +-------------- + +Sounds inside the default table can be used within the sounds field of node definitions. + + * `default.node_sound_defaults()` + * `default.node_sound_stone_defaults()` + * `default.node_sound_dirt_defaults()` + * `default.node_sound_sand_defaults()` + * `default.node_sound_wood_defaults()` + * `default.node_sound_leaves_defaults()` + * `default.node_sound_glass_defaults()` + * `default.node_sound_metal_defaults()` + + +Default constants +----------------- + +`default.LIGHT_MAX` The maximum light level (see [Node definition] light_source) + + +GUI and formspecs +----------------- + +`default.get_hotbar_bg(x, y)` + + * Get the hotbar background as string, containing the formspec elements + * x: Horizontal position in the formspec + * y: Vertical position in the formspec + +`default.gui_bg` + + * Deprecated, remove from mods. + +`default.gui_bg_img` + + * Deprecated, remove from mods. + +`default.gui_slots` + + * Deprecated, remove from mods. + +`default.gui_survival_form` + + * Entire formspec for the survival inventory + +`default.get_furnace_active_formspec(fuel_percent, item_percent)` + + * Get the active furnace formspec using the defined GUI elements + * fuel_percent: Percent of how much the fuel is used + * item_percent: Percent of how much the item is cooked + +`default.get_furnace_inactive_formspec()` + + * Get the inactive furnace formspec using the defined GUI elements + + +Leafdecay +--------- + +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. + +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. + +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. + + +Dyes +---- + +Minetest Game dyes are registered with: + + groups = {dye = 1, color_ = 1}, + +To make recipes that will work with dyes from many mods, define them using the +dye group and the color groups. + +Dye color groups: + + * `color_white` + * `color_grey` + * `color_dark_grey` + * `color_black` + * `color_red` + * `color_pink` + * `color_orange` + * `color_brown` + * `color_yellow` + * `color_green` + * `color_dark_green` + * `color_blue` + * `color_cyan` + * `color_violet` + * `color_magenta` + +Example of one shapeless recipe using the dye group and a color group: + + minetest.register_craft({ + type = "shapeless", + output = ":item_yellow", + recipe = {":item_no_color", "group:dye,color_yellow"}, + }) + + +Trees +----- + + * `default.grow_tree(pos, is_apple_tree)` + * Grows a mgv6 tree or apple tree at pos + + * `default.grow_jungle_tree(pos)` + * Grows a mgv6 jungletree at pos + + * `default.grow_pine_tree(pos)` + * Grows a mgv6 pinetree at pos + + * `default.grow_new_apple_tree(pos)` + * Grows a new design apple tree at pos + + * `default.grow_new_jungle_tree(pos)` + * Grows a new design jungle tree at pos + + * `default.grow_new_pine_tree(pos)` + * Grows a new design pine tree at pos + + * `default.grow_new_snowy_pine_tree(pos)` + * Grows a new design snowy pine tree at pos + + * `default.grow_new_acacia_tree(pos)` + * Grows a new design acacia tree at pos + + * `default.grow_new_aspen_tree(pos)` + * Grows a new design aspen tree at pos + + * `default.grow_bush(pos)` + * Grows a bush at pos + + * `default.grow_acacia_bush(pos)` + * Grows an acaia bush at pos + + * `default.grow_pine_bush(pos)` + * Grows a pine bush at pos + + * `default.grow_blueberry_bush(pos)` + * Grows a blueberry bush at pos + + +Carts +----- + + carts.register_rail( + "mycarts:myrail", -- Rail name + nodedef, -- standard nodedef + railparams -- rail parameter struct (optional) + ) + + railparams = { + on_step(obj, dtime), -- Event handler called when + -- cart is on rail + acceleration, -- integer acceleration factor (negative + -- values to brake) + } + + The event handler is called after all default calculations + are made, so the custom on_step handler can override things + like speed, acceleration, player attachment. The handler will + likely be called many times per second, so the function needs + to make sure that the event is handled properly. + + +Key API +------- + +The key API allows mods to add key functionality to nodes that have +ownership or specific permissions. Using the API will make it so +that a node owner can use skeleton keys on their nodes to create keys +for that node in that location, and give that key to other players, +allowing them some sort of access that they otherwise would not have +due to node protection. + +To make your new nodes work with the key API, you need to register +two callback functions in each nodedef: + + +`on_key_use(pos, player)` + * Is called when a player right-clicks (uses) a normal key on your + * node. + * `pos` - position of the node + * `player` - PlayerRef + * return value: none, ignored + +The `on_key_use` callback should validate that the player is wielding +a key item with the right key meta secret. If needed the code should +deny access to the node functionality. + +If formspecs are used, the formspec callbacks should duplicate these +checks in the metadata callback functions. + + +`on_skeleton_key_use(pos, player, newsecret)` + + * Is called when a player right-clicks (uses) a skeleton key on your + * node. + * `pos` - position of the node + * `player` - PlayerRef + * `newsecret` - a secret value(string) + * return values: + * `secret` - `nil` or the secret value that unlocks the door + * `name` - a string description of the node ("a locked chest") + * `owner` - name of the node owner + +The `on_skeleton_key_use` function should validate that the player has +the right permissions to make a new key for the item. The newsecret +value is useful if the node has no secret value. The function should +store this secret value somewhere so that in the future it may compare +key secrets and match them to allow access. If a node already has a +secret value, the function should return that secret value instead +of the newsecret value. The secret value stored for the node should +not be overwritten, as this would invalidate existing keys. + +Aside from the secret value, the function should retun a descriptive +name for the node and the owner name. The return values are all +encoded in the key that will be given to the player in replacement +for the wielded skeleton key. + +if `nil` is returned, it is assumed that the wielder did not have +permissions to create a key for this node, and no key is created. + +`default.register_craft_metadata_copy(ingredient, result)` +---------------------------------------------------------- + +This function registers a shapeless recipe that takes `ingredient` +and `result` as input and outputs `result`. + +The metadata of the input `result` is copied to the output `result`. diff --git a/menu/icon.png b/menu/icon.png new file mode 100644 index 0000000..ac259f9 Binary files /dev/null and b/menu/icon.png differ diff --git a/mods/arctic_life/init.lua b/mods/arctic_life/init.lua new file mode 100644 index 0000000..49bb4c5 --- /dev/null +++ b/mods/arctic_life/init.lua @@ -0,0 +1,2 @@ +dofile(minetest.get_modpath('arctic_life')..'/penguin.lua') +dofile(minetest.get_modpath('arctic_life')..'/walrus.lua') diff --git a/mods/arctic_life/license.txt b/mods/arctic_life/license.txt new file mode 100644 index 0000000..da0f88f --- /dev/null +++ b/mods/arctic_life/license.txt @@ -0,0 +1,21 @@ +Graphics by Nathan(CC-BY-SA 4.0) +mobs_penguin +mobs_walrus1 +mobs_walrus2 + +Graphics by DuCake (CC-BY-SA 4.0) +mobs_penguin_tux + +Sound: +Penguin_chirrup.ogg +Tai "DuCake" Kedzierski CC-BY-SA 4.0 + +Walrus sounds +AlexTriceratops123 CCA + +Code is licensed MIT, +Copyright 2020 Nathan Salapat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/arctic_life/mod.conf b/mods/arctic_life/mod.conf new file mode 100644 index 0000000..a69dc94 --- /dev/null +++ b/mods/arctic_life/mod.conf @@ -0,0 +1,5 @@ +name = arctic_life +title = Artic Life +author = Nathan Salapat +description = Simple mod that adds penguins and walrus to snowy biomes. +depends = default, mobs diff --git a/mods/arctic_life/models/arctic_life_penguin.b3d b/mods/arctic_life/models/arctic_life_penguin.b3d new file mode 100644 index 0000000..36be96e Binary files /dev/null and b/mods/arctic_life/models/arctic_life_penguin.b3d differ diff --git a/mods/arctic_life/models/arctic_life_walrus.b3d b/mods/arctic_life/models/arctic_life_walrus.b3d new file mode 100644 index 0000000..c65764b Binary files /dev/null and b/mods/arctic_life/models/arctic_life_walrus.b3d differ diff --git a/mods/arctic_life/penguin.lua b/mods/arctic_life/penguin.lua new file mode 100644 index 0000000..66a20fd --- /dev/null +++ b/mods/arctic_life/penguin.lua @@ -0,0 +1,58 @@ +mobs:register_mob("arctic_life:penguin", { + type = "animal", + passive = false, + attack_type = "dogfight", + group_attack = true, + reach = 1, + damage = 1, + hp_min = 5, + hp_max = 15, + armor = 200, + fly_in = "default:water_source", + collisionbox = {-0.25, -0.4, -0.25, 0.25, 0.3, 0.25}, + visual = "mesh", + mesh = "arctic_life_penguin.b3d", + drawtype = "front", + textures = { + {"arctic_life_penguin.png"}, + {"arctic_life_penguin_tux.png"}, + }, + blood_texture = "mobs_blood.png", + visual_size = {x=8,y=8}, + makes_footstep_sound = true, + sounds = { + random = "penguin_chirrup", + }, + -- speed and jump + walk_velocity = 1, + run_velocity = 2, + jump = true, + jump_height = 1, + stepheight = 1.1, + floats = 0, + -- drops raw meat when dead + drops = { + {name = "mobs:meat_raw", chance = 1, min = 1, max = 4}, + {name = 'bonemeal:bone', chance = 2, min = 1, max = 2}, + }, + -- damaged by + water_damage = 0, + lava_damage = 5, + light_damage = 0, + -- model animation + animation = { + speed_normal = 15, speed_run = 15, + stand_start = 0, stand_end = 60, -- head down/up + walk_start = 150, walk_end = 170, -- walk + run_start = 150, run_end = 170, -- walk + punch_start = 70, punch_end = 140, -- attack + fly_start = 171, fly_end = 201, -- swimming + }, + follow = "fishing:fish_raw", view_range = 7, + replace_rate = 50, + replace_what = {"group:flora"}, + replace_with = "air", +}) + +mobs:register_spawn("arctic_life:penguin", {"default:dirt_with_snow", "default:snowblock"}, 20, 0, 20000, 1, 600) +mobs:register_egg("arctic_life:penguin", "Penguin", "default_grass.png", 1) diff --git a/mods/arctic_life/sounds/penguin_chirrup.ogg b/mods/arctic_life/sounds/penguin_chirrup.ogg new file mode 100644 index 0000000..865dec9 Binary files /dev/null and b/mods/arctic_life/sounds/penguin_chirrup.ogg differ diff --git a/mods/arctic_life/sounds/walrus_attack_1.ogg b/mods/arctic_life/sounds/walrus_attack_1.ogg new file mode 100644 index 0000000..15a58c1 Binary files /dev/null and b/mods/arctic_life/sounds/walrus_attack_1.ogg differ diff --git a/mods/arctic_life/sounds/walrus_attack_2.ogg b/mods/arctic_life/sounds/walrus_attack_2.ogg new file mode 100644 index 0000000..2058f1a Binary files /dev/null and b/mods/arctic_life/sounds/walrus_attack_2.ogg differ diff --git a/mods/arctic_life/sounds/walrus_random_1.ogg b/mods/arctic_life/sounds/walrus_random_1.ogg new file mode 100644 index 0000000..0a7744d Binary files /dev/null and b/mods/arctic_life/sounds/walrus_random_1.ogg differ diff --git a/mods/arctic_life/sounds/walrus_random_2.ogg b/mods/arctic_life/sounds/walrus_random_2.ogg new file mode 100644 index 0000000..9607b10 Binary files /dev/null and b/mods/arctic_life/sounds/walrus_random_2.ogg differ diff --git a/mods/arctic_life/sounds/walrus_random_3.ogg b/mods/arctic_life/sounds/walrus_random_3.ogg new file mode 100644 index 0000000..5adaccf Binary files /dev/null and b/mods/arctic_life/sounds/walrus_random_3.ogg differ diff --git a/mods/arctic_life/sounds/walrus_war_cry.ogg b/mods/arctic_life/sounds/walrus_war_cry.ogg new file mode 100644 index 0000000..1889f0b Binary files /dev/null and b/mods/arctic_life/sounds/walrus_war_cry.ogg differ diff --git a/mods/arctic_life/textures/arctic_life_penguin.png b/mods/arctic_life/textures/arctic_life_penguin.png new file mode 100644 index 0000000..977ac43 Binary files /dev/null and b/mods/arctic_life/textures/arctic_life_penguin.png differ diff --git a/mods/arctic_life/textures/arctic_life_penguin_tux.png b/mods/arctic_life/textures/arctic_life_penguin_tux.png new file mode 100644 index 0000000..aaa6f4b Binary files /dev/null and b/mods/arctic_life/textures/arctic_life_penguin_tux.png differ diff --git a/mods/arctic_life/textures/arctic_life_walrus1.png b/mods/arctic_life/textures/arctic_life_walrus1.png new file mode 100644 index 0000000..c981d59 Binary files /dev/null and b/mods/arctic_life/textures/arctic_life_walrus1.png differ diff --git a/mods/arctic_life/textures/arctic_life_walrus2.png b/mods/arctic_life/textures/arctic_life_walrus2.png new file mode 100644 index 0000000..88e6439 Binary files /dev/null and b/mods/arctic_life/textures/arctic_life_walrus2.png differ diff --git a/mods/arctic_life/walrus.lua b/mods/arctic_life/walrus.lua new file mode 100644 index 0000000..2b57a2b --- /dev/null +++ b/mods/arctic_life/walrus.lua @@ -0,0 +1,55 @@ +mobs:register_mob("arctic_life:walrus", { + type = "animal", + passive = false, + attack_type = "dogfight", + reach = 1, + damage = 5, + hp_min = 15, + hp_max = 45, + armor = 200, + collisionbox = {-0.35, -0.5, -0.35, 0.35, 0.4, 0.35}, + visual = "mesh", + mesh = "arctic_life_walrus.b3d", + drawtype = "front", + textures = { + {"arctic_life_walrus1.png"}, + {"arctic_life_walrus2.png"}, + }, + blood_texture = "mobs_blood.png", + visual_size = {x=10,y=10}, + makes_footstep_sound = false, + sounds = { + random = "walrus_random.ogg", + war_cry = 'walrus_war_cry.ogg', + attack = 'walrus_attack.ogg' + }, + -- speed and jump + walk_velocity = 1, + run_velocity = 2, + jump = true, + jump_height = 1, + stepheight = 1.1, + floats = 1, + -- drops raw meat when dead + drops = { + {name = "mobs:meat_raw", chance = 1, min = 2, max = 5}, + {name = 'bonemeal:bone', chance = 2, min = 1, max = 3}, + }, + -- damaged by + water_damage = 1, + lava_damage = 5, + light_damage = 0, + -- model animation + animation = { + speed_normal = 15, speed_run = 15, + stand_start = 0, stand_end = 50, -- head down/up + walk_start = 55, walk_end = 95, -- walk + run_start = 55, run_end = 95, -- walk + punch_start = 100, punch_end = 145, -- attack + }, + follow = {"fishing:fish_raw", "mobs_fish:clownfish", "fishing:pike"}, + view_range = 7, +}) + +mobs:register_spawn("arctic_life:walrus", {"default:dirt_with_snow", "default:snowblock"}, 20, 0, 20000, 1, 600) +mobs:register_egg("arctic_life:walrus", "Walrus", "default_grass.png", 1) diff --git a/mods/areas/LICENSE.txt b/mods/areas/LICENSE.txt new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/mods/areas/LICENSE.txt @@ -0,0 +1,502 @@ + 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/mods/areas/README.md b/mods/areas/README.md new file mode 100644 index 0000000..6e41b1a --- /dev/null +++ b/mods/areas/README.md @@ -0,0 +1,103 @@ +Areas mod for Minetest +====================== + +Dependencies +------------ + +Minetest 5.0.0+ is recommended, but 0.4.16+ should work as well. + + +Configuration +------------- + +Open the tab `Settings -> All Settings -> Mods -> areas` to get a list of all +possible settings. + +For server owners: Check `settingtypes.txt` and modify your `minetest.conf` +according to the wanted setting changes. + + + +Tutorial +-------- + +1) Specify the corner positions of the area you would like to protect. +Use one of the following commands: + + * `/area_pos set` and punch the two corner nodes to set them. + * `/area_pos set1/set2` and punch only the first or second corner node to + set them one at a time. + * `/area_pos1/2` to set one of the positions to your current position. + * `/area_pos1/2 X Y Z` to set one of the positions to the specified + coordinates. + +2) Protect the selected area by running one of the following commands: + + * `/set_owner ` -- If you have the `areas` privilege. + * `/protect ` -- If you have the `areas` privilege or the server + administrator has enabled area self-protection. + +The area name is used only for informational purposes and has no functional +importance. + +For example: `/set_owner SomePlayer Mese city` + +3) You now own an area. You may now add sub-owners to it if you want to (see command `/add_owner`). Before using the `/add_owner` command you have to +select the corners of the sub-area as you did in step 1. + +If your markers are still around your original area and you want to grant +access to your entire area you will not have to re-set them. Use `/select_area` to place the markers at the corners of an existing area if you've reset your +markers and want to grant access to a full area. + +The `/add_owner` command expects three arguments: + 1. The ID number of the parent area (the area that you want to add a + sub-area to). + 2. The name of the player that will own the sub-area. + 3. The name of the sub-area. (can contain spaces) + +For example: `/add_owner 123 BobTheBuilder Diamond lighthouse` + + +Commands +-------- + + * `/protect ` -- Protects an area for yourself. (if + self-protection is enabled) + + * `/set_owner ` -- Protects an area for a specified + player. (requires the `areas` privilege) + + * `/add_owner ` -- Grants another player + control over part (or all) of an area. + + * `/rename_area ` -- Renames an existing area. + + * `/list_areas` -- Lists all of the areas that you own, or all areas if you + have the `areas` privilege. + + * `/find_areas ` -- Finds areas using a Lua regular expresion. + For example, to find castles: + + /find_areas [Cc]astle + + * `/remove_area ` -- Removes an area that you own. Any sub-areas of that + area are made sub-areas of the removed area's parent, if it exists. + If the removed area has no parent it's sub-areas will have no parent. + + * `/recursive_remove_areas ` -- Removes an area and all sub-areas of it. + + * `/change_owner ` -- Change the owner of an area. + + * `/area_info` -- Returns information about area configuration and usage. + + * `/select_area ` -- Sets the area positions to those of an existing + area. + + * `/area_pos {set,set1,set2,get}` -- Sets the area positions by punching + nodes or shows the current area positions. + + * `/area_pos1 [X,Y,Z|X Y Z]` -- Sets area position one to your position or + the one supplied. + + * `/area_pos2 [X,Y,Z|X Y Z]` -- Sets area position two to your position or + the one supplied. diff --git a/mods/areas/api.lua b/mods/areas/api.lua new file mode 100644 index 0000000..40a9841 --- /dev/null +++ b/mods/areas/api.lua @@ -0,0 +1,165 @@ +local hudHandlers = {} + + +areas.registered_on_adds = {} +areas.registered_on_removes = {} +areas.registered_on_moves = {} + +function areas:registerOnAdd(func) + table.insert(areas.registered_on_adds, func) +end + +function areas:registerOnRemove(func) + table.insert(areas.registered_on_removes, func) +end + +function areas:registerOnMove(func) + table.insert(areas.registered_on_moves, func) +end + + +--- Adds a function as a HUD handler, it will be able to add items to the Areas HUD element. +function areas:registerHudHandler(handler) + table.insert(hudHandlers, handler) +end + + +function areas:getExternalHudEntries(pos) + local areas = {} + for _, func in pairs(hudHandlers) do + func(pos, areas) + end + return areas +end + +--- Returns a list of areas that include the provided position. +function areas:getAreasAtPos(pos) + local res = {} + + if self.store then + local a = self.store:get_areas_for_pos(pos, false, true) + for store_id, store_area in pairs(a) do + local id = tonumber(store_area.data) + res[id] = self.areas[id] + end + else + local px, py, pz = pos.x, pos.y, pos.z + for id, area in pairs(self.areas) do + local ap1, ap2 = area.pos1, area.pos2 + if + (px >= ap1.x and px <= ap2.x) and + (py >= ap1.y and py <= ap2.y) and + (pz >= ap1.z and pz <= ap2.z) then + res[id] = area + end + end + end + return res +end + +--- Returns areas that intersect with the passed area. +function areas:getAreasIntersectingArea(pos1, pos2) + local res = {} + if self.store then + local a = self.store:get_areas_in_area(pos1, pos2, + true, false, true) + for store_id, store_area in pairs(a) do + local id = tonumber(store_area.data) + res[id] = self.areas[id] + end + else + self:sortPos(pos1, pos2) + local p1x, p1y, p1z = pos1.x, pos1.y, pos1.z + local p2x, p2y, p2z = pos2.x, pos2.y, pos2.z + for id, area in pairs(self.areas) do + local ap1, ap2 = area.pos1, area.pos2 + if + (ap1.x <= p2x and ap2.x >= p1x) and + (ap1.y <= p2y and ap2.y >= p1y) and + (ap1.z <= p2z and ap2.z >= p1z) then + -- Found an intersecting area. + res[id] = area + end + end + end + return res +end + +-- Checks if the area is unprotected or owned by you +function areas:canInteract(pos, name) + if minetest.check_player_privs(name, self.adminPrivs) then + return true + end + local owned = false + for _, area in pairs(self:getAreasAtPos(pos)) do + if area.owner == name or area.open then + return true + elseif areas.factions_available and area.faction_open then + local faction_name = factions.get_player_faction(area.owner) + if faction_name ~= nil and faction_name == factions.get_player_faction(name) then + return true + end + end + owned = true + end + return not owned +end + +-- Returns a table (list) of all players that own an area +function areas:getNodeOwners(pos) + local owners = {} + for _, area in pairs(self:getAreasAtPos(pos)) do + table.insert(owners, area.owner) + end + return owners +end + +--- Checks if the area intersects with an area that the player can't interact in. +-- Note that this fails and returns false when the specified area is fully +-- owned by the player, but with multiple protection zones, none of which +-- cover the entire checked area. +-- @param name (optional) Player name. If not specified checks for any intersecting areas. +-- @param allow_open Whether open areas should be counted as if they didn't exist. +-- @return Boolean indicating whether the player can interact in that area. +-- @return Un-owned intersecting area ID, if found. +function areas:canInteractInArea(pos1, pos2, name, allow_open) + if name and minetest.check_player_privs(name, self.adminPrivs) then + return true + end + self:sortPos(pos1, pos2) + + -- Intersecting non-owned area ID, if found. + local blocking_area = nil + + local areas = self:getAreasIntersectingArea(pos1, pos2) + for id, area in pairs(areas) do + -- First check for a fully enclosing owned area. + -- A little optimization: isAreaOwner isn't necessary + -- here since we're iterating over all relevant areas. + if area.owner == name and + self:isSubarea(pos1, pos2, id) then + return true + end + + -- Then check for intersecting non-owned (blocking) areas. + -- We don't bother with this check if we've already found a + -- blocking area, as the check is somewhat expensive. + -- The area blocks if the area is closed or open areas aren't + -- acceptable to the caller, and the area isn't owned. + -- Note: We can't return directly here, because there might be + -- an exclosing owned area that we haven't gotten to yet. + if not blocking_area and + (not allow_open or not area.open) and + (not name or not self:isAreaOwner(id, name)) then + blocking_area = id + end + end + + if blocking_area then + return false, blocking_area + end + + -- There are no intersecting areas or they are only partially + -- intersecting areas and they are all owned by the player. + return true +end diff --git a/mods/areas/api.md b/mods/areas/api.md new file mode 100644 index 0000000..e243a8a --- /dev/null +++ b/mods/areas/api.md @@ -0,0 +1,48 @@ +Areas mod API +=== + +API list +--- + + * `areas:registerHudHandler(handler)` - Registers a handler to add items to the Areas HUD. See [HUD](#hud). + * `areas:registerOnAdd(func(id, area))` + * `areas:registerOnRemove(func(id))` + * `areas:registerOnMove(func(id, area, pos1, pos2))` + + +HUD +--- + +If you are making a protection mod or a similar mod that adds invisible regions +to the world, and you would like then to show up in the areas HUD element, you +can register a callback to show your areas. + +HUD handler specification: + + * `handler(pos, list)` + * `pos` - The position to check. + * `list` - The list of area HUD elements, this should be modified in-place. + +The area list item is a table containing a list of tables with the following fields: + + * `id` - An identifier for the area. This should be a unique string in the format `mod:id`. + * `name` - The name of the area. + * `owner` - The player name of the region owner, if any. + +All of the fields are optional but at least one of them must be set. + +### Example + + local function areas_hud_handler(pos, areas) + local val = find_my_protection(pos) + + if val then + table.insert(areas, { + id = "mod:"..val.id, + name = val.name, + owner = val.owner, + }) + end + end + + areas:registerHudHandler(areas_hud_handler) diff --git a/mods/areas/chatcommands.lua b/mods/areas/chatcommands.lua new file mode 100644 index 0000000..ac5d247 --- /dev/null +++ b/mods/areas/chatcommands.lua @@ -0,0 +1,434 @@ + +minetest.register_chatcommand("protect", { + params = "", + description = "Protect your own area", + privs = {[areas.config.self_protection_privilege]=true}, + func = function(name, param) + if param == "" then + return false, "Invalid usage, see /help protect." + end + local player = minetest.get_player_by_name(name) + if not player:get_inventory():contains_item('main', 'epic:deed') then + minetest.chat_send_player(name, 'You need a land deed.') + return + end + local pos1, pos2 = areas:getPos(name) + if not (pos1 and pos2) then + return false, "You need to select an area first." + end + + minetest.log("action", "/protect invoked, owner="..name.. + " AreaName="..param.. + " StartPos="..minetest.pos_to_string(pos1).. + " EndPos=" ..minetest.pos_to_string(pos2)) + + local canAdd, errMsg = areas:canPlayerAddArea(pos1, pos2, name) + if not canAdd then + return false, "You can't protect that area: "..errMsg + end + + local id = areas:add(name, param, pos1, pos2, nil) + areas:save() + + player:get_inventory():remove_item('main', 'epic:deed') + return true, "Area protected. ID: "..id + end +}) + + +minetest.register_chatcommand("set_owner", { + params = " ", + description = "Protect an area beetween two positions and give" + .." a player access to it without setting the parent of the" + .." area to any existing area", + privs = areas.adminPrivs, + func = function(name, param) + local ownerName, areaName = param:match('^(%S+)%s(.+)$') + + if not ownerName then + return false, "Incorrect usage, see /help set_owner." + end + + local pos1, pos2 = areas:getPos(name) + if not (pos1 and pos2) then + return false, "You need to select an area first." + end + + if not areas:player_exists(ownerName) then + return false, "The player \"" + ..ownerName.."\" does not exist." + end + + minetest.log("action", name.." runs /set_owner. Owner = "..ownerName.. + " AreaName = "..areaName.. + " StartPos = "..minetest.pos_to_string(pos1).. + " EndPos = " ..minetest.pos_to_string(pos2)) + + local id = areas:add(ownerName, areaName, pos1, pos2, nil) + areas:save() + + minetest.chat_send_player(ownerName, + "You have been granted control over area #".. + id..". Type /list_areas to show your areas.") + return true, "Area protected. ID: "..id + end +}) + + +minetest.register_chatcommand("add_owner", { + params = " ", + description = "Give a player access to a sub-area beetween two" + .." positions that have already been protected," + .." Use set_owner if you don't want the parent to be set.", + func = function(name, param) + local pid, ownerName, areaName + = param:match('^(%d+) ([^ ]+) (.+)$') + + if not pid then + minetest.chat_send_player(name, "Incorrect usage, see /help add_owner") + return + end + + local pos1, pos2 = areas:getPos(name) + if not (pos1 and pos2) then + return false, "You need to select an area first." + end + + if not areas:player_exists(ownerName) then + return false, "The player \""..ownerName.."\" does not exist." + end + + minetest.log("action", name.." runs /add_owner. Owner = "..ownerName.. + " AreaName = "..areaName.." ParentID = "..pid.. + " StartPos = "..pos1.x..","..pos1.y..","..pos1.z.. + " EndPos = " ..pos2.x..","..pos2.y..","..pos2.z) + + -- Check if this new area is inside an area owned by the player + pid = tonumber(pid) + if (not areas:isAreaOwner(pid, name)) or + (not areas:isSubarea(pos1, pos2, pid)) then + return false, "You can't protect that area." + end + + local id = areas:add(ownerName, areaName, pos1, pos2, pid) + areas:save() + + minetest.chat_send_player(ownerName, + "You have been granted control over area #".. + id..". Type /list_areas to show your areas.") + return true, "Area protected. ID: "..id + end +}) + + +minetest.register_chatcommand("rename_area", { + params = " ", + description = "Rename a area that you own", + func = function(name, param) + local id, newName = param:match("^(%d+)%s(.+)$") + if not id then + return false, "Invalid usage, see /help rename_area." + end + + id = tonumber(id) + if not id then + return false, "That area doesn't exist." + end + + if not areas:isAreaOwner(id, name) then + return true, "You don't own that area." + end + + areas.areas[id].name = newName + areas:save() + return true, "Area renamed." + end +}) + + +minetest.register_chatcommand("find_areas", { + params = "", + description = "Find areas using a Lua regular expression", + privs = areas.adminPrivs, + func = function(name, param) + if param == "" then + return false, "A regular expression is required." + end + + -- Check expression for validity + local function testRegExp() + ("Test [1]: Player (0,0,0) (0,0,0)"):find(param) + end + if not pcall(testRegExp) then + return false, "Invalid regular expression." + end + + local matches = {} + for id, area in pairs(areas.areas) do + local str = areas:toString(id) + if str:find(param) then + table.insert(matches, str) + end + end + if #matches > 0 then + return true, table.concat(matches, "\n") + else + return true, "No matches found." + end + end +}) + + +minetest.register_chatcommand("list_areas", { + description = "List your areas, or all areas if you are an admin.", + func = function(name, param) + local admin = minetest.check_player_privs(name, areas.adminPrivs) + local areaStrings = {} + for id, area in pairs(areas.areas) do + if admin or areas:isAreaOwner(id, name) then + table.insert(areaStrings, areas:toString(id)) + end + end + if #areaStrings == 0 then + return true, "No visible areas." + end + return true, table.concat(areaStrings, "\n") + end +}) + + +minetest.register_chatcommand("recursive_remove_areas", { + params = "", + description = "Recursively remove areas using an id", + func = function(name, param) + local id = tonumber(param) + if not id then + return false, "Invalid usage, see" + .." /help recursive_remove_areas" + end + + if not areas:isAreaOwner(id, name) then + return false, "Area "..id.." does not exist or is" + .." not owned by you." + end + + areas:remove(id, true) + areas:save() + return true, "Removed area "..id.." and it's sub areas." + end +}) + + +minetest.register_chatcommand("remove_area", { + params = "", + description = "Remove an area using an id", + func = function(name, param) + local id = tonumber(param) + if not id then + return false, "Invalid usage, see /help remove_area" + end + + if not areas:isAreaOwner(id, name) then + return false, "Area "..id.." does not exist or" + .." is not owned by you." + end + + areas:remove(id) + areas:save() + return true, "Removed area "..id + end +}) + + +minetest.register_chatcommand("change_owner", { + params = " ", + description = "Change the owner of an area using it's ID", + func = function(name, param) + local id, newOwner = param:match("^(%d+)%s(%S+)$") + if not id then + return false, "Invalid usage, see" + .." /help change_owner." + end + + if not areas:player_exists(newOwner) then + return false, "The player \""..newOwner + .."\" does not exist." + end + + id = tonumber(id) + if not areas:isAreaOwner(id, name) then + return false, "Area "..id.." does not exist" + .." or is not owned by you." + end + areas.areas[id].owner = newOwner + areas:save() + minetest.chat_send_player(newOwner, + ("%s has given you control over the area %q (ID %d).") + :format(name, areas.areas[id].name, id)) + return true, "Owner changed." + end +}) + + +minetest.register_chatcommand("area_open", { + params = "", + description = "Toggle an area open (anyone can interact) or closed", + func = function(name, param) + local id = tonumber(param) + if not id then + return false, "Invalid usage, see /help area_open." + end + + if not areas:isAreaOwner(id, name) then + return false, "Area "..id.." does not exist" + .." or is not owned by you." + end + local open = not areas.areas[id].open + -- Save false as nil to avoid inflating the DB. + areas.areas[id].open = open or nil + areas:save() + return true, ("Area %s."):format(open and "opened" or "closed") + end +}) + + +if areas.factions_available then + minetest.register_chatcommand("area_faction_open", { + params = "", + description = "Toggle an area open/closed for members in your faction.", + func = function(name, param) + local id = tonumber(param) + if not id then + return false, "Invalid usage, see /help area_faction_open." + end + + if not areas:isAreaOwner(id, name) then + return false, "Area "..id.." does not exist" + .." or is not owned by you." + end + local open = not areas.areas[id].faction_open + -- Save false as nil to avoid inflating the DB. + areas.areas[id].faction_open = open or nil + areas:save() + return true, ("Area %s for faction members."):format(open and "opened" or "closed") + end + }) +end + + +minetest.register_chatcommand("move_area", { + params = "", + description = "Move (or resize) an area to the current positions.", + privs = areas.adminPrivs, + func = function(name, param) + local id = tonumber(param) + if not id then + return false, "Invalid usage, see /help move_area." + end + + local area = areas.areas[id] + if not area then + return false, "Area does not exist." + end + + local pos1, pos2 = areas:getPos(name) + if not pos1 then + return false, "You need to select an area first." + end + + areas:move(id, area, pos1, pos2) + areas:save() + + return true, "Area successfully moved." + end, +}) + + +minetest.register_chatcommand("area_info", { + description = "Get information about area configuration and usage.", + func = function(name, param) + local lines = {} + local privs = minetest.get_player_privs(name) + + -- Short (and fast to access) names + local cfg = areas.config + local self_prot = cfg.self_protection + local prot_priv = cfg.self_protection_privilege + local limit = cfg.self_protection_max_areas + local limit_high = cfg.self_protection_max_areas_high + local size_limit = cfg.self_protection_max_size + local size_limit_high = cfg.self_protection_max_size_high + + local has_high_limit = privs.areas_high_limit + local has_prot_priv = not prot_priv or privs[prot_priv] + local can_prot = privs.areas or (self_prot and has_prot_priv) + local max_count = can_prot and + (has_high_limit and limit_high or limit) or 0 + local max_size = has_high_limit and + size_limit_high or size_limit + + -- Privilege information + local self_prot_line = ("Self protection is %sabled"):format( + self_prot and "en" or "dis") + if self_prot and prot_priv then + self_prot_line = self_prot_line.. + (" %s have the neccessary privilege (%q).") + :format( + has_prot_priv and "and you" or + "but you don't", + prot_priv) + else + self_prot_line = self_prot_line.."." + end + table.insert(lines, self_prot_line) + if privs.admin_areas then + table.insert(lines, "You are an area".. + " administrator (\"areas\" privilege).") + elseif has_high_limit then + table.insert(lines, + "You have extended area protection".. + " limits (\"areas_high_limit\" privilege).") + end + + -- Area count + local area_num = 0 + for id, area in pairs(areas.areas) do + if area.owner == name then + area_num = area_num + 1 + end + end + local count_line = ("You have %d area%s"):format( + area_num, area_num == 1 and "" or "s") + if privs.admin_areas then + count_line = count_line.. + " and have no area protection limits." + elseif can_prot then + count_line = count_line..(", out of a maximum of %d.") + :format(max_count) + end + table.insert(lines, count_line) + + -- Area size limits + local function size_info(str, size) + table.insert(lines, ("%s spanning up to %dx%dx%d.") + :format(str, size.x, size.y, size.z)) + end + local function priv_limit_info(lpriv, lmax_count, lmax_size) + size_info(("Players with the %q privilege".. + " can protect up to %d areas"):format( + lpriv, lmax_count), lmax_size) + end + if self_prot then + if privs.admin_areas then + priv_limit_info(prot_priv, + limit, size_limit) + priv_limit_info("areas_high_limit", + limit_high, size_limit_high) + elseif has_prot_priv then + size_info("You can protect areas", max_size) + end + end + + return true, table.concat(lines, "\n") + end, +}) diff --git a/mods/areas/hud.lua b/mods/areas/hud.lua new file mode 100644 index 0000000..ffe764e --- /dev/null +++ b/mods/areas/hud.lua @@ -0,0 +1,72 @@ +-- This is inspired by the landrush mod by Bremaweb + +areas.hud = {} +areas.hud.refresh = 0 + +minetest.register_globalstep(function(dtime) + + areas.hud.refresh = areas.hud.refresh + dtime + if areas.hud.refresh > areas.config["tick"] then + areas.hud.refresh = 0 + else + return + end + + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local pos = vector.round(player:get_pos()) + pos = vector.apply(pos, function(p) + return math.max(math.min(p, 2147483), -2147483) + end) + local areaStrings = {} + + for id, area in pairs(areas:getAreasAtPos(pos)) do + local faction_info = area.faction_open and areas.factions_available and + factions.get_player_faction(area.owner) + area.faction_open = faction_info + table.insert(areaStrings, ("%s [%u] (%s%s%s)") + :format(area.name, id, area.owner, + area.open and ":open" or "", + faction_info and ":"..faction_info or "")) + end + + for i, area in pairs(areas:getExternalHudEntries(pos)) do + local str = "" + if area.name then str = area.name .. " " end + if area.id then str = str.."["..area.id.."] " end + if area.owner then str = str.."("..area.owner..")" end + table.insert(areaStrings, str) + end + + local areaString = "Areas:" + if #areaStrings > 0 then + areaString = areaString.."\n".. + table.concat(areaStrings, "\n") + end + local hud = areas.hud[name] + if not hud then + hud = {} + areas.hud[name] = hud + hud.areasId = player:hud_add({ + hud_elem_type = "text", + name = "Areas", + number = 0xFFFFFF, + position = {x=0, y=1}, + offset = {x=8, y=-8}, + text = areaString, + scale = {x=200, y=60}, + alignment = {x=1, y=-1}, + }) + hud.oldAreas = areaString + return + elseif hud.oldAreas ~= areaString then + player:hud_change(hud.areasId, "text", areaString) + hud.oldAreas = areaString + end + end +end) + +minetest.register_on_leaveplayer(function(player) + areas.hud[player:get_player_name()] = nil +end) + diff --git a/mods/areas/init.lua b/mods/areas/init.lua new file mode 100644 index 0000000..1b79309 --- /dev/null +++ b/mods/areas/init.lua @@ -0,0 +1,41 @@ +-- Areas mod by ShadowNinja +-- Based on node_ownership +-- License: LGPLv2+ + +areas = {} + +areas.factions_available = minetest.global_exists("factions") + +areas.adminPrivs = {admin_areas=true} +areas.startTime = os.clock() + +areas.modpath = minetest.get_modpath("areas") +dofile(areas.modpath.."/settings.lua") +dofile(areas.modpath.."/api.lua") +dofile(areas.modpath.."/internal.lua") +dofile(areas.modpath.."/chatcommands.lua") +dofile(areas.modpath.."/pos.lua") +dofile(areas.modpath.."/interact.lua") +dofile(areas.modpath.."/legacy.lua") +dofile(areas.modpath.."/hud.lua") + +areas:load() + +minetest.register_privilege("admin_areas", { + description = "Can administer areas.", + give_to_singleplayer = false +}) +minetest.register_privilege("areas_high_limit", { + description = "Can can more, bigger areas." +}) + +if not minetest.registered_privileges[areas.config.self_protection_privilege] then + minetest.register_privilege(areas.config.self_protection_privilege, { + description = "Can protect areas.", + }) +end + +if minetest.settings:get_bool("log_mods") then + local diffTime = os.clock() - areas.startTime + minetest.log("action", "areas loaded in "..diffTime.."s.") +end diff --git a/mods/areas/interact.lua b/mods/areas/interact.lua new file mode 100644 index 0000000..95f6607 --- /dev/null +++ b/mods/areas/interact.lua @@ -0,0 +1,25 @@ + +local old_is_protected = minetest.is_protected +function minetest.is_protected(pos, name) + if not areas:canInteract(pos, name) then + return true + end + return old_is_protected(pos, name) +end + +minetest.register_on_protection_violation(function(pos, name) + if not areas:canInteract(pos, name) then + local player = minetest.get_player_by_name(name) + if player then + local yaw = player:get_look_horizontal() + math.pi + if yaw > 2 * math.pi then + yaw = yaw - 2 * math.pi + end + player:set_look_horizontal(yaw) + player:set_look_vertical(-player:get_look_vertical()) + local owners = areas:getNodeOwners(pos) + minetest.chat_send_player(name,("%s is protected by %s."):format( + minetest.pos_to_string(pos), table.concat(owners, ", "))) + end + end +end) diff --git a/mods/areas/internal.lua b/mods/areas/internal.lua new file mode 100644 index 0000000..27f85ed --- /dev/null +++ b/mods/areas/internal.lua @@ -0,0 +1,305 @@ + +function areas:player_exists(name) + return minetest.get_auth_handler().get_auth(name) ~= nil +end + +local safe_file_write = minetest.safe_file_write +if safe_file_write == nil then + function safe_file_write(path, content) + local file, err = io.open(path, "w") + if err then + return err + end + file:write(content) + file:close() + end +end + +-- Save the areas table to a file +function areas:save() + local datastr = minetest.serialize(self.areas) + if not datastr then + minetest.log("error", "[areas] Failed to serialize area data!") + return + end + return safe_file_write(self.config.filename, datastr) +end + +-- Load the areas table from the save file +function areas:load() + local file, err = io.open(self.config.filename, "r") + if err then + self.areas = self.areas or {} + return err + end + self.areas = minetest.deserialize(file:read("*a")) + if type(self.areas) ~= "table" then + self.areas = {} + end + file:close() + self:populateStore() +end + +--- Checks an AreaStore ID. +-- Deletes the AreaStore (falling back to the iterative method) +-- and prints an error message if the ID is invalid. +-- @return Whether the ID was valid. +function areas:checkAreaStoreId(sid) + if not sid then + minetest.log("error", "AreaStore failed to find an ID for an " + .."area! Falling back to iterative area checking.") + self.store = nil + self.store_ids = nil + end + return sid and true or false +end + +-- Populates the AreaStore after loading, if needed. +function areas:populateStore() + if not rawget(_G, "AreaStore") then + return + end + local store = AreaStore() + local store_ids = {} + for id, area in pairs(areas.areas) do + local sid = store:insert_area(area.pos1, + area.pos2, tostring(id)) + if not self:checkAreaStoreId(sid) then + return + end + store_ids[id] = sid + end + self.store = store + self.store_ids = store_ids +end + +-- Finds the first usable index in a table +-- Eg: {[1]=false,[4]=true} -> 2 +local function findFirstUnusedIndex(t) + local i = 0 + repeat i = i + 1 + until t[i] == nil + return i +end + +--- Add a area. +-- @return The new area's ID. +function areas:add(owner, name, pos1, pos2, parent) + local id = findFirstUnusedIndex(self.areas) + self.areas[id] = { + name = name, + pos1 = pos1, + pos2 = pos2, + owner = owner, + parent = parent + } + + for i=1, #areas.registered_on_adds do + areas.registered_on_adds[i](id, self.areas[id]) + end + + -- Add to AreaStore + if self.store then + local sid = self.store:insert_area(pos1, pos2, tostring(id)) + if self:checkAreaStoreId(sid) then + self.store_ids[id] = sid + end + end + return id +end + +--- Remove a area, and optionally it's children recursively. +-- If a area is deleted non-recursively the children will +-- have the removed area's parent as their new parent. +function areas:remove(id, recurse) + if recurse then + -- Recursively find child entries and remove them + local cids = self:getChildren(id) + for _, cid in pairs(cids) do + self:remove(cid, true) + end + else + -- Update parents + local parent = self.areas[id].parent + local children = self:getChildren(id) + for _, cid in pairs(children) do + -- The subarea parent will be niled out if the + -- removed area does not have a parent + self.areas[cid].parent = parent + + end + end + + for i=1, #areas.registered_on_removes do + areas.registered_on_removes[i](id) + end + + -- Remove main entry + self.areas[id] = nil + + -- Remove from AreaStore + if self.store then + self.store:remove_area(self.store_ids[id]) + self.store_ids[id] = nil + end +end + +--- Move an area. +function areas:move(id, area, pos1, pos2) + area.pos1 = pos1 + area.pos2 = pos2 + + + for i=1, #areas.registered_on_moves do + areas.registered_on_moves[i](id, area, pos1, pos2) + end + + if self.store then + self.store:remove_area(areas.store_ids[id]) + local sid = self.store:insert_area(pos1, pos2, tostring(id)) + if self:checkAreaStoreId(sid) then + self.store_ids[id] = sid + end + end +end + +-- Checks if a area between two points is entirely contained by another area. +-- Positions must be sorted. +function areas:isSubarea(pos1, pos2, id) + local area = self.areas[id] + if not area then + return false + end + local ap1, ap2 = area.pos1, area.pos2 + local ap1x, ap1y, ap1z = ap1.x, ap1.y, ap1.z + local ap2x, ap2y, ap2z = ap2.x, ap2.y, ap2.z + local p1x, p1y, p1z = pos1.x, pos1.y, pos1.z + local p2x, p2y, p2z = pos2.x, pos2.y, pos2.z + if + (p1x >= ap1x and p1x <= ap2x) and + (p2x >= ap1x and p2x <= ap2x) and + (p1y >= ap1y and p1y <= ap2y) and + (p2y >= ap1y and p2y <= ap2y) and + (p1z >= ap1z and p1z <= ap2z) and + (p2z >= ap1z and p2z <= ap2z) then + return true + end +end + +-- Returns a table (list) of children of an area given it's identifier +function areas:getChildren(id) + local children = {} + for cid, area in pairs(self.areas) do + if area.parent and area.parent == id then + table.insert(children, cid) + end + end + return children +end + +-- Checks if the user has sufficient privileges. +-- If the player is not a administrator it also checks +-- if the area intersects other areas that they do not own. +-- Also checks the size of the area and if the user already +-- has more than max_areas. +function areas:canPlayerAddArea(pos1, pos2, name) + local privs = minetest.get_player_privs(name) + if privs.areas then + return true + end + + -- Check self protection privilege, if it is enabled, + -- and if the area is too big. + if not self.config.self_protection or + not privs[areas.config.self_protection_privilege] then + return false, "Self protection is disabled or you do not have" + .." the necessary privilege." + end + + local max_size = privs.areas_high_limit and + self.config.self_protection_max_size_high or + self.config.self_protection_max_size + if + (pos2.x - pos1.x) > max_size.x or + (pos2.y - pos1.y) > max_size.y or + (pos2.z - pos1.z) > max_size.z then + return false, "Area is too big." + end + + -- Check number of areas the user has and make sure it not above the max + local count = 0 + for _, area in pairs(self.areas) do + if area.owner == name then + count = count + 1 + end + end + local max_areas = privs.areas_high_limit and + self.config.self_protection_max_areas_high or + self.config.self_protection_max_areas + if count >= max_areas then + return false, "You have reached the maximum amount of" + .." areas that you are allowed to protect." + end + + -- Check intersecting areas + local can, id = self:canInteractInArea(pos1, pos2, name) + if not can then + local area = self.areas[id] + return false, ("The area intersects with %s [%u] (%s).") + :format(area.name, id, area.owner) + end + + return true +end + +-- Given a id returns a string in the format: +-- "name [id]: owner (x1, y1, z1) (x2, y2, z2) -> children" +function areas:toString(id) + local area = self.areas[id] + local message = ("%s [%d]: %s %s %s"):format( + area.name, id, area.owner, + minetest.pos_to_string(area.pos1), + minetest.pos_to_string(area.pos2)) + + local children = areas:getChildren(id) + if #children > 0 then + message = message.." -> "..table.concat(children, ", ") + end + return message +end + +-- Re-order areas in table by their identifiers +function areas:sort() + local sa = {} + for k, area in pairs(self.areas) do + if not area.parent then + table.insert(sa, area) + local newid = #sa + for _, subarea in pairs(self.areas) do + if subarea.parent == k then + subarea.parent = newid + table.insert(sa, subarea) + end + end + end + end + self.areas = sa +end + +-- Checks if a player owns an area or a parent of it +function areas:isAreaOwner(id, name) + local cur = self.areas[id] + if cur and minetest.check_player_privs(name, self.adminPrivs) then + return true + end + while cur do + if cur.owner == name then + return true + elseif cur.parent then + cur = self.areas[cur.parent] + else + return false + end + end + return false +end diff --git a/mods/areas/legacy.lua b/mods/areas/legacy.lua new file mode 100644 index 0000000..876b88d --- /dev/null +++ b/mods/areas/legacy.lua @@ -0,0 +1,139 @@ +-- This file contains functions to convert from +-- the old areas format and other compatability code. + +minetest.register_chatcommand("legacy_load_areas", { + params = "", + description = "Loads, converts, and saves the areas from" + .." a legacy save file.", + privs = {areas=true, server=true}, + func = function(name, param) + minetest.chat_send_player(name, "Converting areas...") + local version = tonumber(param) + if version == 0 then + local err = areas:node_ownership_load() + if err then + minetest.chat_send_player(name, "Error loading legacy file: "..err) + return + end + else + minetest.chat_send_player(name, "Invalid version number. (0 allowed)") + return + end + minetest.chat_send_player(name, "Legacy file loaded.") + + for k, area in pairs(areas.areas) do + -- New position format + area.pos1 = {x=area.x1, y=area.y1, z=area.z1} + area.pos2 = {x=area.x2, y=area.y2, z=area.z2} + + area.x1, area.y1, area.z1, + area.x2, area.y2, area.z2 = + nil, nil, nil, nil, nil, nil + + -- Area positions sorting + areas:sortPos(area.pos1, area.pos2) + + -- Add name + area.name = "unnamed" + + -- Remove ID + area.id = nil + end + minetest.chat_send_player(name, "Table format updated.") + + areas:save() + minetest.chat_send_player(name, "Converted areas saved. Done.") + end +}) + +function areas:node_ownership_load() + local filename = minetest.get_worldpath().."/owners.tbl" + local tables, err + tables, err = loadfile(filename) + if err then + return err + end + + tables = tables() + for idx = 1, #tables do + local tolinkv, tolinki = {}, {} + for i, v in pairs(tables[idx]) do + if type(v) == "table" and tables[v[1]] then + table.insert(tolinkv, {i, tables[v[1]]}) + end + if type(i) == "table" and tables[i[1]] then + table.insert(tolinki, {i, tables[i[1]]}) + end + end + -- link values, first due to possible changes of indices + for _, v in ipairs(tolinkv) do + tables[idx][v[1]] = v[2] + end + -- link indices + for _, v in ipairs(tolinki) do + tables[idx][v[2]], tables[idx][v[1]] = tables[idx][v[1]], nil + end + end + self.areas = tables[1] +end + +-- Returns the name of the first player that owns an area +function areas.getNodeOwnerName(pos) + for id, area in pairs(areas:getAreasAtPos(pos)) do + return area.owner + end + return false +end + +-- Checks if a node is owned by you +function areas.isNodeOwner(pos, name) + if minetest.check_player_privs(name, areas.adminPrivs) then + return true + end + for id, area in pairs(areas:getAreasAtPos(pos)) do + if name == area.owner then + return true + end + end + return false +end + +-- Checks if an area has an owner +function areas.hasOwner(pos) + for id, area in pairs(areas:getAreasAtPos(pos)) do + return true + end + return false +end + +IsPlayerNodeOwner = areas.isNodeOwner +GetNodeOwnerName = areas.getNodeOwnerName +HasOwner = areas.hasOwner + +-- This is entirely untested and may break in strange and new ways. +if areas.config.legacy_table then + owner_defs = setmetatable({}, { + __index = function(table, key) + local a = rawget(areas.areas, key) + if not a then return a end + local b = {} + for k, v in pairs(a) do b[k] = v end + b.x1, b.y1, b.z1 = b.pos1.x, b.pos1.y, b.pos1.z + b.x2, b.y1, b.z2 = b.pos2.x, b.pos2.y, b.pos2.z + b.pos1, b.pos2 = nil, nil + b.id = key + return b + end, + __newindex = function(table, key, value) + local a = value + a.pos1, a.pos2 = {x=a.x1, y=a.y1, z=a.z1}, + {x=a.x2, y=a.y2, z=a.z2} + a.x1, a.y1, a.z1, a.x2, a.y2, a.z2 = + nil, nil, nil, nil, nil, nil + a.name = a.name or "unnamed" + a.id = nil + return rawset(areas.areas, key, a) + end + }) +end + diff --git a/mods/areas/license.txt b/mods/areas/license.txt new file mode 100644 index 0000000..6ca8d8b --- /dev/null +++ b/mods/areas/license.txt @@ -0,0 +1,6 @@ +Code requiring player to have a land deed to protect an area added by Nathan Salapat. + +Copyright (C) 2013 ShadowNinja + +Licensed under the GNU LGPL version 2.1 or later. +See LICENSE.txt and http://www.gnu.org/licenses/lgpl-2.1.txt diff --git a/mods/areas/mod.conf b/mods/areas/mod.conf new file mode 100644 index 0000000..e694301 --- /dev/null +++ b/mods/areas/mod.conf @@ -0,0 +1,2 @@ +name = areas +optional_depends = playerfactions diff --git a/mods/areas/pos.lua b/mods/areas/pos.lua new file mode 100644 index 0000000..323d55d --- /dev/null +++ b/mods/areas/pos.lua @@ -0,0 +1,265 @@ + +-- I could depend on WorldEdit for this, but you need to have the 'worldedit' +-- permission to use those commands and you don't have +-- /area_pos{1,2} [X Y Z|X,Y,Z]. +-- Since this is mostly copied from WorldEdit it is mostly +-- licensed under the AGPL. (select_area is a exception) + +areas.marker1 = {} +areas.marker2 = {} +areas.set_pos = {} +areas.pos1 = {} +areas.pos2 = {} + +local LIMIT = 30992 -- this is due to MAPBLOCK_SIZE=16! + +local function posLimit(pos) + return { + x = math.max(math.min(pos.x, LIMIT), -LIMIT), + y = math.max(math.min(pos.y, LIMIT), -LIMIT), + z = math.max(math.min(pos.z, LIMIT), -LIMIT) + } +end + +minetest.register_chatcommand("select_area", { + params = "", + description = "Select a area by id.", + func = function(name, param) + local id = tonumber(param) + if not id then + return false, "Invalid usage, see /help select_area." + end + if not areas.areas[id] then + return false, "The area "..id.." does not exist." + end + + areas:setPos1(name, areas.areas[id].pos1) + areas:setPos2(name, areas.areas[id].pos2) + return true, "Area "..id.." selected." + end, +}) + +minetest.register_chatcommand("area_pos1", { + params = "[X Y Z|X,Y,Z]", + description = "Set area protection region position 1 to your" + .." location or the one specified", + privs = {}, + func = function(name, param) + local pos + local found, _, x, y, z = param:find( + "^(-?%d+)[, ](-?%d+)[, ](-?%d+)$") + if found then + pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)} + elseif param == "" then + local player = minetest.get_player_by_name(name) + if player then + pos = player:get_pos() + else + return false, "Unable to get position." + end + else + return false, "Invalid usage, see /help area_pos1." + end + pos = posLimit(vector.round(pos)) + areas:setPos1(name, pos) + return true, "Area position 1 set to " + ..minetest.pos_to_string(pos) + end, +}) + +minetest.register_chatcommand("area_pos2", { + params = "[X Y Z|X,Y,Z]", + description = "Set area protection region position 2 to your" + .." location or the one specified", + func = function(name, param) + local pos + local found, _, x, y, z = param:find( + "^(-?%d+)[, ](-?%d+)[, ](-?%d+)$") + if found then + pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)} + elseif param == "" then + local player = minetest.get_player_by_name(name) + if player then + pos = player:get_pos() + else + return false, "Unable to get position." + end + else + return false, "Invalid usage, see /help area_pos2." + end + pos = posLimit(vector.round(pos)) + areas:setPos2(name, pos) + return true, "Area position 2 set to " + ..minetest.pos_to_string(pos) + end, +}) + + +minetest.register_chatcommand("area_pos", { + params = "set/set1/set2/get", + description = "Set area protection region, position 1, or position 2" + .." by punching nodes, or display the region", + func = function(name, param) + if param == "set" then -- Set both area positions + areas.set_pos[name] = "pos1" + return true, "Select positions by punching two nodes." + elseif param == "set1" then -- Set area position 1 + areas.set_pos[name] = "pos1only" + return true, "Select position 1 by punching a node." + elseif param == "set2" then -- Set area position 2 + areas.set_pos[name] = "pos2" + return true, "Select position 2 by punching a node." + elseif param == "get" then -- Display current area positions + local pos1str, pos2str = "Position 1: ", "Position 2: " + if areas.pos1[name] then + pos1str = pos1str..minetest.pos_to_string(areas.pos1[name]) + else + pos1str = pos1str.."" + end + if areas.pos2[name] then + pos2str = pos2str..minetest.pos_to_string(areas.pos2[name]) + else + pos2str = pos2str.."" + end + return true, pos1str.."\n"..pos2str + else + return false, "Unknown subcommand: "..param + end + end, +}) + +function areas:getPos(playerName) + local pos1, pos2 = areas.pos1[playerName], areas.pos2[playerName] + if not (pos1 and pos2) then + return nil + end + -- Copy positions so that the area table doesn't contain multiple + -- references to the same position. + pos1, pos2 = vector.new(pos1), vector.new(pos2) + return areas:sortPos(pos1, pos2) +end + +function areas:setPos1(playerName, pos) + areas.pos1[playerName] = posLimit(pos) + areas.markPos1(playerName) +end + +function areas:setPos2(playerName, pos) + areas.pos2[playerName] = posLimit(pos) + areas.markPos2(playerName) +end + + +minetest.register_on_punchnode(function(pos, node, puncher) + local name = puncher:get_player_name() + -- Currently setting position + if name ~= "" and areas.set_pos[name] then + if areas.set_pos[name] == "pos1" then + areas.pos1[name] = pos + areas.markPos1(name) + areas.set_pos[name] = "pos2" + minetest.chat_send_player(name, + "Position 1 set to " + ..minetest.pos_to_string(pos)) + elseif areas.set_pos[name] == "pos1only" then + areas.pos1[name] = pos + areas.markPos1(name) + areas.set_pos[name] = nil + minetest.chat_send_player(name, + "Position 1 set to " + ..minetest.pos_to_string(pos)) + elseif areas.set_pos[name] == "pos2" then + areas.pos2[name] = pos + areas.markPos2(name) + areas.set_pos[name] = nil + minetest.chat_send_player(name, + "Position 2 set to " + ..minetest.pos_to_string(pos)) + end + end +end) + +-- Modifies positions `pos1` and `pos2` so that each component of `pos1` +-- is less than or equal to its corresponding component of `pos2`, +-- returning the two positions. +function areas:sortPos(pos1, pos2) + if pos1.x > pos2.x then + pos2.x, pos1.x = pos1.x, pos2.x + end + if pos1.y > pos2.y then + pos2.y, pos1.y = pos1.y, pos2.y + end + if pos1.z > pos2.z then + pos2.z, pos1.z = pos1.z, pos2.z + end + return pos1, pos2 +end + +-- Marks area position 1 +areas.markPos1 = function(name) + local pos = areas.pos1[name] + if areas.marker1[name] ~= nil then -- Marker already exists + areas.marker1[name]:remove() -- Remove marker + areas.marker1[name] = nil + end + if pos ~= nil then -- Add marker + areas.marker1[name] = minetest.add_entity(pos, "areas:pos1") + areas.marker1[name]:get_luaentity().active = true + end +end + +-- Marks area position 2 +areas.markPos2 = function(name) + local pos = areas.pos2[name] + if areas.marker2[name] ~= nil then -- Marker already exists + areas.marker2[name]:remove() -- Remove marker + areas.marker2[name] = nil + end + if pos ~= nil then -- Add marker + areas.marker2[name] = minetest.add_entity(pos, "areas:pos2") + areas.marker2[name]:get_luaentity().active = true + end +end + +minetest.register_entity("areas:pos1", { + initial_properties = { + visual = "cube", + visual_size = {x=1.1, y=1.1}, + textures = {"areas_pos1.png", "areas_pos1.png", + "areas_pos1.png", "areas_pos1.png", + "areas_pos1.png", "areas_pos1.png"}, + collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55}, + }, + on_step = function(self, dtime) + if self.active == nil then + self.object:remove() + end + end, + on_punch = function(self, hitter) + self.object:remove() + local name = hitter:get_player_name() + areas.marker1[name] = nil + end, +}) + +minetest.register_entity("areas:pos2", { + initial_properties = { + visual = "cube", + visual_size = {x=1.1, y=1.1}, + textures = {"areas_pos2.png", "areas_pos2.png", + "areas_pos2.png", "areas_pos2.png", + "areas_pos2.png", "areas_pos2.png"}, + collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55}, + }, + on_step = function(self, dtime) + if self.active == nil then + self.object:remove() + end + end, + on_punch = function(self, hitter) + self.object:remove() + local name = hitter:get_player_name() + areas.marker2[name] = nil + end, +}) + diff --git a/mods/areas/settings.lua b/mods/areas/settings.lua new file mode 100644 index 0000000..22af52c --- /dev/null +++ b/mods/areas/settings.lua @@ -0,0 +1,46 @@ +local world_path = minetest.get_worldpath() + +areas.config = {} + +local function setting(name, tp, default) + local full_name = "areas." .. name + local value + if tp == "bool" then + value = minetest.settings:get_bool(full_name) + default = value == nil and minetest.is_yes(default) + elseif tp == "string" then + value = minetest.settings:get(full_name) + elseif tp == "v3f" then + value = minetest.setting_get_pos(full_name) + default = value == nil and minetest.string_to_pos(default) + elseif tp == "float" or tp == "int" then + value = tonumber(minetest.settings:get(full_name)) + local v, other = default:match("^(%S+) (.+)") + default = value == nil and tonumber(other and v or default) + else + error("Cannot parse setting type " .. tp) + end + + if value == nil then + value = default + assert(default ~= nil, "Cannot parse default for " .. full_name) + end + --print("add", name, default, value) + areas.config[name] = value +end + +local file = io.open(areas.modpath .. "/settingtypes.txt", "r") +for line in file:lines() do + local name, tp, value = line:match("^areas%.(%S+) %(.*%) (%S+) (.*)") + if value then + setting(name, tp, value) + end +end +file:close() + +-------------- +-- Settings -- +-------------- + +setting("filename", "string", world_path.."/areas.dat") + diff --git a/mods/areas/settingtypes.txt b/mods/areas/settingtypes.txt new file mode 100644 index 0000000..1e5a01b --- /dev/null +++ b/mods/areas/settingtypes.txt @@ -0,0 +1,37 @@ +# This file is parsed in "settings.lua". Check regex first. + +# Static paths do not work well with settings +#areas.filename (Configuration file path) string (world_path)/areas.dat + +# Allow players with a privilege create their own areas using /protect +# within the specified size and amount limits. +areas.self_protection (Self protection) bool true + +# Self protection: Privilege required to protect an area +areas.self_protection_privilege (Self protection: Required privs) string areas + +# Refresh delay for the name displays in the HUD in seconds +areas.tick (HUD update delay) float 0.5 0 100 + +# Enable the legacy owner_defs metatable mode. Untested and possibly unstable +areas.legacy_table (Legacy owner_defs metatable) bool false + +[Self protection (normal)] + +# Self protection (normal): Maximal size of the protectable area +# Only enter positive whole numbers for the coordinate values or you'll mess up stuff. +areas.self_protection_max_size (Maximal area size) v3f (64, 128, 64) + +# Self protection (normal): Maximal amount of protected areas per player +areas.self_protection_max_areas (Maximal area count) int 4 + +[Self protection (high)] + +# Self protection (normal): Maximal size of the protectable area +# This setting applies for plyaers with the privilege 'areas_high_limit' +areas.self_protection_max_size_high (Maximal area size) v3f (512, 512, 512) + +# Self protection (normal): Maximal amount of protected areas per player +# Only enter positive whole numbers for the coordinate values or you'll mess up stuff. +# This setting applies for plyaers with the privilege 'areas_high_limit' +areas.self_protection_max_areas_high (Maximal area count) float 32 diff --git a/mods/areas/textures/areas_pos1.png b/mods/areas/textures/areas_pos1.png new file mode 100644 index 0000000..4c304aa Binary files /dev/null and b/mods/areas/textures/areas_pos1.png differ diff --git a/mods/areas/textures/areas_pos2.png b/mods/areas/textures/areas_pos2.png new file mode 100644 index 0000000..1502f16 Binary files /dev/null and b/mods/areas/textures/areas_pos2.png differ diff --git a/mods/autoshutdown/init.lua b/mods/autoshutdown/init.lua new file mode 100644 index 0000000..ccb2e1c --- /dev/null +++ b/mods/autoshutdown/init.lua @@ -0,0 +1,57 @@ + +--[[ + + Copyright 2017 Auke Kok + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject + to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +]]-- + +local def = 300 -- server must be empty for this long +local int = 15 -- check interval in seconds + +local to = def + +local function do_shutdown() + local i, _ = next(minetest.get_connected_players()) + if not i then + to = to - int + else + to = def + minetest.after(int, do_shutdown) + return + end + if to < 0 then + minetest.log("action", "autoshutdown") + minetest.request_shutdown() + else + minetest.after(int, do_shutdown) + end +end + +minetest.register_chatcommand("autoshutdown", { + params = "autoshutdown server", + description = "shut the server down after the last player leaves", + privs = {server = true}, + func = function(name, param) + do_shutdown() + return true, "autoshutdown issued" + end, +}) diff --git a/mods/autoshutdown/license.txt b/mods/autoshutdown/license.txt new file mode 100644 index 0000000..e69de29 diff --git a/mods/autoshutdown/mod.conf b/mods/autoshutdown/mod.conf new file mode 100644 index 0000000..df0c959 --- /dev/null +++ b/mods/autoshutdown/mod.conf @@ -0,0 +1,2 @@ +name = autoshutdown +description = Shut down the server after the last player leaves. diff --git a/mods/autoshutdown/readme.md b/mods/autoshutdown/readme.md new file mode 100644 index 0000000..84e5540 --- /dev/null +++ b/mods/autoshutdown/readme.md @@ -0,0 +1,11 @@ + +## autoshutdown mod + +Allows admins to schedule a shutdown when the last player leaves. + +The server shuts down a little time after the last player leaves, +to make sure all areas are slowly unloaded. + +To schedule an automatic shutdown, issue the `/autoshutdown` command +in chat. The shutdown will only happen once. + diff --git a/mods/awards/LICENSE.txt b/mods/awards/LICENSE.txt new file mode 100644 index 0000000..b9bc22e --- /dev/null +++ b/mods/awards/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2013-8 rubenwardy + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/mods/awards/README.md b/mods/awards/README.md new file mode 100644 index 0000000..e570f0e --- /dev/null +++ b/mods/awards/README.md @@ -0,0 +1,295 @@ +# Awards + +Adds awards/achievements to Minetest (plus a very good API). + +by [rubenwardy](https://rubenwardy.com), licensed under MIT. +With thanks to Wuzzy, kaeza, and MrIbby. + +Majority of awards are back ported from Calinou's old fork in Carbone, under same license. + + +# Introduction + +## Awards and Triggers + +An award is a single unlockable unit, registered like so: + +```lua +awards.register_award("mymod:award", { + description = "My Example Award", +}) +``` + +Awards are unlocked either using `awards.unlock()` or by a trigger being +fullfilled. A trigger is a condition which unlocks an award. Triggers are +registered at the same time as an award is registered: + +```lua +awards.register_award("mymod:award", { + description = "My Example Award", + trigger = { + type = "dig", + node = "default:stone", + target = 10, + }, +}) +``` + +The above trigger type is an example of a counted_key trigger: +rather than a single counter there's a counter per key - in this +case the key is the value of the `node` field. If you leave out +the key in a `counted_key` trigger, then the total will be used +instead. For example, here is an award which unlocks after you've +placed 10 nodes of any type: + +```lua +awards.register_award("mymod:award", { + description = "Place 10 nodes!", + trigger = { + type = "place", + target = 10, + }, +}) +``` + +You can also register an *Unlock Function*, which can return the name of an +award to unlock it: + +```lua +awards.register_award("mymod:award", { + title = "Lava Miner", + description = "Mine any block while being very close to lava.", +}) + +awards.register_on_dig(function(player, data) + local pos = player:get_pos() + if pos and (minetest.find_node_near(pos, 1, "default:lava_source") or + minetest.find_node_near(pos, 1, "default:lava_flowing")) then + return "mymod:award" + end + return nil +end) +``` + +The above is a bad example as you don't actually need the stats data given. +It would be better to register a `dignode` callback and call `awards.unlock()` +if the condition is met. + +## Trigger Types + +The trigger type is used to determine which event will cause the trigger will be +fulfilled. The awards mod comes with a number of predefined types, documented +in [Builtin Trigger Types](#builtin-trigger-types). + +Trigger types are registered like so: + +```lua +awards.register_trigger("chat", { + type = "counted", + progress = "@1/@2 chat messages", + auto_description = { "Send a chat message", "Chat @1 times" }, +}) + +minetest.register_on_chat_message(function(name, message) + local player = minetest.get_player_by_name(name) + if not player or string.find(message, "/") then + return + end + awards.notify_chat(player) +end) +``` + +A trigger type has a type as well, which determines how the data is stored and +also how the trigger is fulfilled. + +**Trigger Type Types:** + +* **custom** requires you handle the calling of awards.unlock() yourself. You also + need to implement on_register() yourself. You'll also probably want to implement + `on_register()` to catch awards registered with your trigger type. +* **counted** stores a single counter for each player which is incremented by calling + `trigger:notify(player)`. Good for homogenous actions like number of chat messages, + joins, and the like. +* **counted_key** stores a table of counters each indexed by a key. There is also + a total field (`__total`) which stores the sum of all counters. A counter is + incremented by calling `trigger:notify(player, key)`. This is good for things like + placing nodes or crafting items, where the key will be the item or node name. + If `key` is an item, then you should also add `key_is_item = true` to the + trigger type definition. + +As said, you could use a custom trigger if none of the other ones match your needs. +Here's an example. + +```lua +awards.register_trigger("foo", { + type = "custom", + progress = "@1/@2 foos", + auto_description = { "Do a foo", "Foo @1 times" }, +}) + +minetest.register_on_foo(function() + for _, trigger in pairs(awards.on.foo) do + -- trigger is either a trigger tables or + -- or an unlock function. + + -- some complex logic + if condition then + awards.unlock(trigger) + end + end +end) + +``` + +## Award Difficulty + +Difficulty is used to determine how awards are sorted in awards lists. + +If the award trigger is counted, ie: the trigger requires a `target` property, +then the difficulty multipler is timesd by `target` to get the overall difficulty. +If the award isn't a counted type then the difficulty multiplier is used as the +overal difficulty. Award difficulty affects how awards are sorted in a list - +more difficult awards are further down the list. + +In real terms, `difficulty` is a relative difficulty to do one unit of the trigger +if its counted, otherwise it's the relative difficulty of completely doing the +award (if not-counted). For the `dig` trigger type, 1 unit would be 1 node dug. + + +Actual code used to calculate award difficulty: + +```lua +local difficulty = def.difficulty or 1 +if def.trigger and def.trigger.target then + difficulty = difficulty * def.trigger.target +end +``` + + +# API + +* awards.register_award(name, def), the def table has the following fields: + * `title` - title of the award (defaults to name) + * `description` - longer description of the award, displayed in Awards tab + * `difficulty` - see [Award Difficulty](#award-difficulty). + * `requires` - list of awards that need to be unlocked before this one + is visible. + * `prizes` - list of items to give when you earn the award + * `secret` - boolean if this award is secret (i.e. showed on awards list) + * `sound` - `SimpleSoundSpec` table to play on unlock. + `false` to disable unlock sound. + * `icon` - the icon image, use default otherwise. + * `background` - the background image, use default otherwise. + * `trigger` - trigger definition, see [Builtin Trigger Types](#builtin-trigger-types). + * `on_unlock(name, def)` - callback on unlock. +* awards.register_trigger(name, def), the def table has the following fields: + * `type` - see [Trigger Types](#trigger-types). + * `progress` - used to format progress, defaults to "%1/%2". + * `auto_description` - a table of two elements. Each element is a format string. Element 1 is singular, element 2 is plural. Used for the award description (not title) if none is given. + * `on_register(award_def)` - called when an award registers with this type. + * "counted_key" only: + * `auto_description_total` - Used if the trigger is for the total. + * `get_key(self, def)` - get key for particular award, return nil for a total. + * `key_is_item` - true if the key is an item name. On notify(), + any watched groups will also be notified as `group:groupname` keys. +* awards.register_on_unlock(func(name, def)) + * name is the player name + * def is the award def. + * return true to cancel HUD +* awards.unlock(name, award) + * gives an award to a player + * name is the player name + +## Builtin Trigger Types + +Callbacks (register a function to be run) + +* dig type: Dig a node. + * node: the dug node type. If nil, all dug nodes are counted +* place type: Place a node. + * node: the placed node type. If nil, all placed nodes are counted +* craft type: Craft something. + * item: the crafted item type. If nil, all crafted items are counted +* death type: Die. + * reason: the death reason, one of the types in PlayerHPChangeReason (see lua_api.txt) + or nil for total deaths. +* chat type: Write a chat message. +* join type: Join the server. +* eat type: Eat an item. + * item: the eaten item type. If nil, all eaten items are counted + +(for all types) target - how many times to dig/place/craft/etc. + +Each type has a register function like so: + +* awards.register_on_TRIGGERTYPE(func(player, data)) + * data is the player stats data + * return award name or null + +### dig + +```lua +trigger = { + type = "dig", + node = "default:dirt", -- item, alias, or group + target = 50, +} +``` + +### place + +```lua +trigger = { + type = "place", + node = "default:dirt", -- item, alias, or group + target = 50, +} +``` + +### craft + +```lua +trigger = { + type = "craft", + item = "default:dirt", -- item, alias, or group + target = 50, +} +``` + +### death + +```lua +trigger = { + type = "death", + reason = "fall", + target = 5, +} +``` + +### chat + +```lua +trigger = { + type = "chat", + target = 100, +} +``` + +### join + +```lua +trigger = { + type = "join", + target = 100, +} +``` + +### eat + +```lua +trigger = { + type = "eat", + item = "default:apple", + target = 100, +} +``` diff --git a/mods/awards/init.lua b/mods/awards/init.lua new file mode 100644 index 0000000..98f054a --- /dev/null +++ b/mods/awards/init.lua @@ -0,0 +1,36 @@ +-- Copyright (c) 2013-18 rubenwardy. MIT. + +-- The global award namespace +awards = { + show_mode = "hud", + registered_triggers = {}, +} + +-- Internationalization support. +awards.gettext, awards.ngettext = dofile(minetest.get_modpath("awards").."/src/intllib.lua") + +-- Load files +dofile(minetest.get_modpath("awards").."/src/data.lua") +dofile(minetest.get_modpath("awards").."/src/api_awards.lua") +dofile(minetest.get_modpath("awards").."/src/api_triggers.lua") +dofile(minetest.get_modpath("awards").."/src/chat_commands.lua") +dofile(minetest.get_modpath("awards").."/src/gui.lua") +dofile(minetest.get_modpath("awards").."/src/triggers.lua") +dofile(minetest.get_modpath("awards").."/src/awards.lua") + +awards.load() +minetest.register_on_shutdown(awards.save) + + +-- Backwards compatibility +awards.give_achievement = awards.unlock +awards.getFormspec = awards.get_formspec +awards.showto = awards.show_to +awards.register_onDig = awards.register_on_dig +awards.register_onPlace = awards.register_on_place +awards.register_onDeath = awards.register_on_death +awards.register_onChat = awards.register_on_chat +awards.register_onJoin = awards.register_on_join +awards.register_onCraft = awards.register_on_craft +awards.def = awards.registered_awards +awards.register_achievement = awards.register_award diff --git a/mods/awards/locale/de.po b/mods/awards/locale/de.po new file mode 100644 index 0000000..443c1b3 --- /dev/null +++ b/mods/awards/locale/de.po @@ -0,0 +1,824 @@ +# German translations for PACKAGE package. +# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Wuzzy2, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 05:35-0300\n" +"PO-Revision-Date: 2017-02-21 04:19-0300\n" +"Last-Translator: Wuzzy2\n" +"Language-Team: German\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: api.lua +msgid "Secret Achievement Unlocked:" +msgstr "Geheime Auszeichnung erhalten:" + +#: api.lua +msgid "Achievement Unlocked:" +msgstr "Auszeichnung erhalten:" + +#: api.lua +#, lua-format +msgid "Secret Achievement Unlocked: %s" +msgstr "Geheime Auszeichnung erhalten: %s" + +#: api.lua +#, lua-format +msgid "Achievement Unlocked: %s" +msgstr "Auszeichnung erhalten: %s" + +#: api.lua +msgid "Secret Achievement Unlocked!" +msgstr "Geheime Auszeichnung erhalten!" + +#: api.lua +msgid "Achievement Unlocked!" +msgstr "Auszeichnung erhalten:" + +#: api.lua +msgid "Error: No awards available." +msgstr "Fehler: Keine Auszeichnungen vorhanden." + +#: api.lua +msgid "OK" +msgstr "OK" + +#: api.lua +msgid "(Secret Award)" +msgstr "(Geheime Auszeichnung)" + +#: api.lua +msgid "Unlock this award to find out what it is." +msgstr "Verdienen Sie sich diese Auszeichnung, um herauszufinden, was sie ist." + +#: api.lua +#, lua-format +msgid "%s (got)" +msgstr "%s (erhalten)" + +#: api.lua +msgid "You've disabled awards. Type /awards enable to reenable." +msgstr "" +"Sie haben die Auszeichnungen deaktiviert. Geben Sie »/awards enable« ein, um " +"sie wieder zu aktivieren." + +#: api.lua +msgid "You have not unlocked any awards." +msgstr "Sie haben noch keine Auszeichnungen." + +#: api.lua +#, lua-format +msgid "%s’s awards:" +msgstr "%ss Auszeichnungen:" + +#: api.lua chat_commands.lua +#, lua-format +msgid "%s: %s" +msgstr "%s: %s" + +#: sfinv.lua unified_inventory.lua +msgid "Awards" +msgstr "Auszeichnungen" + +#: triggers.lua +msgid "@1/@2 dug" +msgstr "@1/@2 abgebaut" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Mine: @2" +msgid_plural "Mine: @1×@2" +msgstr[0] "Bauen Sie einen Block ab: @2" +msgstr[1] "Bauen Sie Blöcke ab: @1×@2" + +#: triggers.lua +msgid "Mine @1 block." +msgid_plural "Mine @1 blocks." +msgstr[0] "Bauen Sie einen @1 Block ab." +msgstr[1] "Bauen Sie @1 Blöcke ab." + +#: triggers.lua +msgid "@1/@2 placed" +msgstr "@1/@2 platziert" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Place: @2" +msgid_plural "Place: @1×@2" +msgstr[0] "Platzieren Sie einen Block: @2" +msgstr[1] "Platzieren Sie Blöcke: @1×@2" + +#: triggers.lua +msgid "Place a block." +msgid_plural "Place @1 blocks." +msgstr[0] "Platzieren Sie einen Block." +msgstr[1] "Platzieren Sie @1 Blöcke." + +#: triggers.lua +msgid "@1/@2 eaten" +msgstr "@1/@2 gegessen" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Eat: @2" +msgid_plural "Eat: @1×@2" +msgstr[0] "Essen Sie: @2" +msgstr[1] "Essen Sie: @1×@2" + +#: triggers.lua +msgid "Eat an item." +msgid_plural "Eat @1 items." +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "@1/@2 deaths" +msgstr "@1/@2 Tode" + +#: triggers.lua +msgid "Die." +msgid_plural "Die @1 times." +msgstr[0] "Sterben Sie." +msgstr[1] "Sterben Sie @1 mal." + +#: triggers.lua +msgid "@1/@2 chat messages" +msgstr "@1/@2 Chatnachrichten" + +#: triggers.lua +msgid "Write something in chat." +msgid_plural "Write @1 chat messages." +msgstr[0] "Schreiben Sie etwas im Chat." +msgstr[1] "Schreiben Sie @1 Chatnachrichten." + +#: triggers.lua +msgid "@1/@2 game joins" +msgstr "@1/@2 Spielen beigetreten" + +#: triggers.lua +msgid "Join the game." +msgid_plural "Join the game @1 times." +msgstr[0] "Treten Sie dem Spiel bei." +msgstr[1] "Treten Sie dem Spiel @1 mal bei." + +#: triggers.lua +msgid "@1/@2 crafted" +msgstr "@1/@2 gefertigt" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Craft: @2" +msgid_plural "Craft: @1×@2" +msgstr[0] "Fertigen Sie an: @2" +msgstr[1] "Fertigen Sie an: @1×@2" + +#: triggers.lua +msgid "Craft an item." +msgid_plural "Craft @1 items." +msgstr[0] "" +msgstr[1] "" + +#: init.lua +msgid "Saint-Maclou" +msgstr "Saint-Maclou" + +#: init.lua +msgid "Place 20 coal checkers." +msgstr "Platzieren Sie 20 Kohlenschachbrettmuster." + +#: init.lua +msgid "Castorama" +msgstr "Gießmeister" + +#: init.lua +msgid "Place 20 iron checkers." +msgstr "Platzieren Sie 20 Eisenschachbrettmuster." + +#: init.lua +msgid "Sam the Trapper" +msgstr "Sam der Fallensteller" + +#: init.lua +msgid "Place 2 trap stones." +msgstr "Platzieren Sie 2 Fallensteine." + +#: init.lua +msgid "Backpacker" +msgstr "Rucksacktourist" + +#: init.lua +msgid "Craft 4 large bags." +msgstr "Fertigen Sie 4 große Taschen." + +#: init.lua +msgid "Pyromaniac" +msgstr "Pyromane" + +#: init.lua +msgid "Craft 8 times flint and steel." +msgstr "Fertigen Sie 8 mal einen Feuerstein und Stahl an." + +#: init.lua +msgid "Firefighter" +msgstr "Feuerwehr" + +#: init.lua +msgid "Put out 1000 fires." +msgstr "Löschen Sie 1000 Flammen." + +#: init.lua +msgid "Light It Up" +msgstr "Licht an!" + +#: init.lua +msgid "Place 100 torches." +msgstr "Platzieren Sie 100 Fackeln." + +#: init.lua +msgid "Well Lit" +msgstr "Gut ausgeleuchtet" + +#: init.lua +msgid "Place 1,000 torches." +msgstr "Platzieren Sie 1000 Fackeln." + +#: init.lua +msgid "Really Well Lit" +msgstr "Sehr gute Beleuchtung" + +#: init.lua +msgid "Craft 10 mese lamps." +msgstr "Fertigen Sie 10 Meselampen." + +#: init.lua +msgid "Outpost" +msgstr "Außenposten" + +#: init.lua +msgid "Craft 200 stone bricks." +msgstr "Fertigen Sie 200 Steinziegel." + +#: init.lua +msgid "Watchtower" +msgstr "Wachturm" + +#: init.lua +msgid "Craft 800 stone bricks." +msgstr "Fertigen Sie 800 Steinziegel an." + +#: init.lua +msgid "Fortress" +msgstr "Burg" + +#: init.lua +msgid "Craft 3,200 stone bricks." +msgstr "Fertigen Sie 3200 Steinziegel." + +#: init.lua +msgid "Desert Dweller" +msgstr "Wüstenbewohner" + +#: init.lua +msgid "Craft 400 desert stone bricks." +msgstr "Fertigen Sie 400 Wüstensteinziegel." + +#: init.lua +msgid "Pharaoh" +msgstr "Pharao" + +#: init.lua +msgid "Craft 100 sandstone bricks." +msgstr "Fertigen Sie 100 Sandsteinziegel." + +#: init.lua +msgid "Little Library" +msgstr "Kleine Bücherei" + +#: init.lua +msgid "Craft 7 bookshelves." +msgstr "Fertigen Sie 7 Bücherregale." + +#: init.lua +msgid "Lava and Water" +msgstr "Lava und Wasser" + +#: init.lua +msgid "Mine your first obsidian." +msgstr "Bauen Sie Ihr erstes Obsidian ab." + +#: init.lua +msgid "Obsessed with Obsidian" +msgstr "Von Obsidian besessen" + +#: init.lua +msgid "Mine 50 obsidian." +msgstr "Bauen Sie 50 Obsidian ab." + +#: init.lua +msgid "Lava Miner" +msgstr "Lavagräber" + +#: init.lua +msgid "Mine any block while being very close to lava." +msgstr "" +"Bauen Sie einen beliebigen Block ab, während Sie sehr nahe an der Lava " +"stehen." + +#: init.lua +msgid "On The Way" +msgstr "Auf dem Weg" + +#: init.lua +msgid "Place 100 rails." +msgstr "Platzieren Sie 100 Gleise." + +#: init.lua +msgid "First Day in the Woods" +msgstr "Erster Tag im Wald" + +#: init.lua +msgid "Dig 6 tree blocks." +msgstr "Bauen Sie 6 Baumblöcke ab." + +#: init.lua +msgid "Lumberjack" +msgstr "Holzfäller" + +#: init.lua +msgid "Dig 36 tree blocks." +msgstr "Bauen Sie 36 Baumblöcke ab." + +#: init.lua +msgid "Semi-pro Lumberjack" +msgstr "Fortgeschrittener Holzfäller" + +#: init.lua +msgid "Dig 216 tree blocks." +msgstr "Bauen Sie 216 Baumblöcke ab." + +#: init.lua +msgid "Professional Lumberjack" +msgstr "Profiholzfäller" + +#: init.lua +msgid "Dig 1,296 tree blocks." +msgstr "Bauen Sie 1296 Baumblöcke ab." + +#: init.lua +msgid "Junglebaby" +msgstr "Dschungelbaby" + +#: init.lua +msgid "Dig 100 jungle tree blocks." +msgstr "Bauen Sie 100 Dschungelbaumblöcke ab." + +#: init.lua +msgid "Jungleman" +msgstr "Dschungelmann" + +#: init.lua +msgid "Dig 1,000 jungle tree blocks." +msgstr "Bauen Sie 1000 Dschungelbaumblöcke ab." + +#: init.lua +msgid "First Mese Find" +msgstr "Erster Mesefund" + +#: init.lua +msgid "Mine your first mese ore." +msgstr "Bauen Sie Ihr erstes Meseerz ab." + +#: init.lua +msgid "Mese Mastery" +msgstr "Mesemeister" + +#: init.lua +msgid "Mine a mese block." +msgstr "Bauen Sie einen Meseblock ab." + +#: init.lua +msgid "You’re a copper" +msgstr "Du Kupfer!" + +#: init.lua +msgid "Dig 1,000 copper ores." +msgstr "Bauen Sie 1000 Kupfererze ab." + +#: init.lua +msgid "A Cat in a Pop-Tart?!" +msgstr "Eine Katze im Pop-Tart?!" + +#: init.lua +msgid "Mine a nyan cat." +msgstr "Bauen Sie eine Nyan Cat ab." + +#: init.lua +msgid "Mini Miner" +msgstr "Berganfänger" + +#: init.lua +msgid "Dig 100 stone blocks." +msgstr "Bauen Sie 100 Steinblöcke ab." + +#: init.lua +msgid "Hardened Miner" +msgstr "Abhehärteter Bergarbeiter" + +#: init.lua +msgid "Dig 1,000 stone blocks." +msgstr "Bauen Sie 1000 Steine ab." + +#: init.lua +msgid "Master Miner" +msgstr "Profibergarbeiter" + +#: init.lua +msgid "Dig 10,000 stone blocks." +msgstr "Bauen Sie 10000 Steine ab." + +#: init.lua +msgid "Marchand De Sable" +msgstr "" + +#: init.lua +msgid "Dig 1,000 sand." +msgstr "Bauen Sie 1000 Sand ab." + +#: init.lua +msgid "Crafter of Sticks" +msgstr "Stockmacher" + +#: init.lua +msgid "Craft 100 sticks." +msgstr "Fertigen Sie 100 Stöcke." + +#: init.lua +msgid "Jungle Discoverer" +msgstr "Dschungelerkunder" + +#: init.lua +msgid "Mine your first jungle grass." +msgstr "Bauen Sie Ihr erstes Dschungelgras ab." + +#: init.lua +msgid "Grasslands Discoverer" +msgstr "Prärieerkunder" + +#: init.lua +msgid "Mine some grass." +msgstr "Bauen Sie etwas Gras ab." + +#: init.lua +msgid "Savannah Discoverer" +msgstr "Savannenerkunder" + +#: init.lua +msgid "Mine some dry grass." +msgstr "Bauen Sie etwas trockenes Gras ab." + +#: init.lua +msgid "Desert Discoverer" +msgstr "Wüstenerkunder" + +#: init.lua +msgid "Mine your first cactus." +msgstr "Bauen Sie Ihren ersten Kaktus ab." + +#: init.lua +msgid "Far Lands" +msgstr "Ferne Lande" + +#: init.lua +msgid "Mine your first dry shrub." +msgstr "Bauen Sie Ihren ersten vertrockneten Strauch ab." + +#: init.lua +msgid "Glacier Discoverer" +msgstr "Gletschererkunder" + +#: init.lua +msgid "Mine your first ice." +msgstr "Bauen Sie Ihr erstes Eis ab." + +#: init.lua +msgid "Very Simple Snow Man" +msgstr "Sehr simpler Schneemann" + +#: init.lua +msgid "Place two snow blocks." +msgstr "Platzieren Sie zwei Schneeblöcke." + +#: init.lua +msgid "First Gold Find" +msgstr "Erster Goldfund" + +#: init.lua +msgid "Mine your first gold ore." +msgstr "Bauen Sie Ihr erstes Golderz ab." + +#: init.lua +msgid "Gold Rush" +msgstr "Goldrausch" + +#: init.lua +msgid "Mine 45 gold ores." +msgstr "Bauen Sie 18 Diamanterze ab." + +#: init.lua +msgid "Wow, I am Diamonds!" +msgstr "Wow, ich bin Diamanten!" + +#: init.lua +msgid "Mine your first diamond ore." +msgstr "Bauen Sie Ihr erstes Diamanterz ab." + +#: init.lua +msgid "Girl's Best Friend" +msgstr "Bester Freund der Mädchen" + +#: init.lua +msgid "Mine 18 diamond ores." +msgstr "Bauen Sie 18 Diamanterze ab." + +#: init.lua +msgid "Hardest Block on Earth" +msgstr "Härtester Block der Welt" + +#: init.lua +msgid "Craft a diamond block." +msgstr "Fertigen Sie einen Diamantblock an." + +#: init.lua +msgid "In the Dungeon" +msgstr "Im Verlies" + +#: init.lua +msgid "Mine a mossy cobblestone." +msgstr "Bauen Sie ein bemoostes Kopfsteinpflaster ab." + +#: init.lua +msgid "Smelter" +msgstr "Schmelzer" + +#: init.lua +msgid "Craft 10 furnaces." +msgstr "Fertigen Sie 10 Öfen." + +#: init.lua +msgid "Treasurer" +msgstr "Schatzmeister" + +#: init.lua +msgid "Craft 15 chests." +msgstr "Fertigen Sie 15 Truhen." + +#: init.lua +msgid "Bankier" +msgstr "Bankier" + +#: init.lua +msgid "Craft 30 locked chests." +msgstr "Fertigen Sie 30 abgeschlossene Truhen." + +#: init.lua +msgid "Bricker" +msgstr "Ziegler" + +#: init.lua +msgid "Craft 200 brick blocks." +msgstr "Fertigen Sie 200 Ziegelblöcke." + +#: init.lua +msgid "House of Obsidian" +msgstr "Haus aus Obsidian" + +#: init.lua +msgid "Craft 100 obsidian bricks." +msgstr "Fertigen Sie 100 Obsidianziegel." + +#: init.lua +msgid "Build a Cave" +msgstr "Höhlenbauer" + +#: init.lua +msgid "Place 100 stone." +msgstr "Platzieren Sie 100 Steine." + +#: init.lua +msgid "Long Ladder" +msgstr "Lange Leiter" + +#: init.lua +msgid "Place 400 wooden ladders." +msgstr "Platzieren Sie 400 Holzleitern." + +#: init.lua +msgid "Industrial Age" +msgstr "Industriezeitalter" + +#: init.lua +msgid "Place 40 steel ladders." +msgstr "Platzieren Sie 40 Stahlleitern." + +#: init.lua +msgid "Yummy!" +msgstr "Lecker!" + +#: init.lua +msgid "Eat 80 apples." +msgstr "Essen Sie 80 Äpfel." + +#: init.lua +msgid "Glasser" +msgstr "Glasmacher" + +#: init.lua +msgid "Craft 14 vessels shelves." +msgstr "Fertigen Sie 14 Gefäßregale." + +#: init.lua +msgid "Farming Skills Acquired" +msgstr "Landwirtschaft erlernt" + +#: init.lua +msgid "Harvest a fully grown wheat plant." +msgstr "Ernten Sie eine voll ausgewachsene Getreidepflanze." + +#: init.lua +msgid "Field Worker" +msgstr "Feldarbeiter" + +#: init.lua +msgid "Harvest 25 fully grown wheat plants." +msgstr "Ernten Sie 25 voll ausgewachsene Getreidepflanzen." + +#: init.lua +msgid "Aspiring Farmer" +msgstr "Aufstrebender Bauer" + +#: init.lua +msgid "Harvest 125 fully grown wheat plants." +msgstr "Ernten Sie 125 voll ausgewachsene Getreidepflanzen." + +#: init.lua +msgid "Wheat Magnate" +msgstr "Getreidemagnat" + +#: init.lua +msgid "Harvest 625 fully grown wheat plants." +msgstr "Ernten Sie 625 voll ausgewachsene Getreidepflanzen." + +#: init.lua +msgid "Baker" +msgstr "Bäcker" + +#: init.lua +msgid "Eat 10 loaves of bread." +msgstr "Essen Sie 10 Brote." + +#: init.lua +msgid "Wool Over Your Eyes" +msgstr "Wollige Augen" + +#: init.lua +msgid "Craft 250 white wool." +msgstr "Fertigen Sie 250 weiße Wolle." + +#: init.lua +msgid "Hotelier" +msgstr "Hotelier" + +#: init.lua +msgid "Craft 15 fancy beds." +msgstr "Fertigen Sie 15 schicke Betten." + +#: init.lua +msgid "Filthy Rich" +msgstr "Stinkreich" + +#: init.lua +msgid "Craft 24 gold block stairs." +msgstr "Fertigen Sie 24 Goldblockstufen." + +#: init.lua +msgid "Roses Are Red" +msgstr "Rosen sind rot" + +#: init.lua +msgid "Craft 400 red dyes." +msgstr "Fertigen Sie 400 rote Farbstoffe." + +#: init.lua +msgid "Dandelions are Yellow" +msgstr "Löwenzahn ist gelb" + +#: init.lua +msgid "Craft 400 yellow dyes." +msgstr "Fertigen Sie 400 gelbe Farbstoffe." + +#: init.lua +msgid "Geraniums are Blue" +msgstr "Geranien sind blau" + +#: init.lua +msgid "Craft 400 blue dyes." +msgstr "Fertigen Sie 400 blaue Farbstoffe." + +#: init.lua +msgid "White Color Stock" +msgstr "Weißer Farbstoffvorrat" + +#: init.lua +msgid "Craft 100 white dyes." +msgstr "Fertigen Sie 100 weiße Farbstoffe." + +#: init.lua +msgid "Tasty Mushrooms" +msgstr "Leckere Pilze" + +#: init.lua +msgid "Eat 3 brown mushrooms." +msgstr "Essen Sie 3 braune Pilze." + +#: init.lua +msgid "Mushroom Lover" +msgstr "Pilzfreund" + +#: init.lua +msgid "Eat 33 brown mushrooms." +msgstr "Essen Sie 33 braune Pilze." + +#: init.lua +msgid "Underground Mushroom Farmer" +msgstr "Unterirdischer Pilzbauer" + +#: init.lua +msgid "Eat 333 brown mushrooms." +msgstr "Essen Sie 333 braune Pilze." + +#: init.lua +msgid "Builder" +msgstr "Bauarbeiter" + +#: init.lua +msgid "Constructor" +msgstr "Konstrukteur" + +#: init.lua +msgid "Architect" +msgstr "Architekt" + +#: init.lua +msgid "Master Architect" +msgstr "Meisterarchitekt" + +#: chat_commands.lua +msgid "[c|clear|disable|enable]" +msgstr "[c|clear|disable|enable]" + +#: chat_commands.lua +msgid "Show, clear, disable or enable your achievements" +msgstr "Zeigen, löschen, deaktivieren oder aktivieren Sie Ihre Auszeichnungen" + +#: chat_commands.lua +msgid "" +"All your awards and statistics have been cleared. You can now start again." +msgstr "" +"All Ihre Auszeichnugen und Statistiken wurden zurückgesetzt. Sie können nun " +"von vorne anfangen." + +#: chat_commands.lua +msgid "You have disabled your achievements." +msgstr "Sie haben Ihre Auszeichnungen deaktiviert." + +#: chat_commands.lua +msgid "You have enabled your achievements." +msgstr "Sie haben Ihre Auszeichnungen aktiviert." + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Show details of an achievement" +msgstr "Details einer Auszeichnung anzeigen" + +#: chat_commands.lua +msgid "Achievement not found." +msgstr "Auszeichnung nicht gefunden." + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Get the achievements statistics for the given player or yourself" +msgstr "Die Statistik der Auszeichnungen eines Spielers zeigen" diff --git a/mods/awards/locale/es.po b/mods/awards/locale/es.po new file mode 100644 index 0000000..a2d5958 --- /dev/null +++ b/mods/awards/locale/es.po @@ -0,0 +1,825 @@ +# Spanish translations for PACKAGE package +# Traducciones al español para el paquete PACKAGE. +# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Diego Martínez , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 05:35-0300\n" +"PO-Revision-Date: 2017-02-20 22:17-0300\n" +"Last-Translator: Diego Martínez \n" +"Language-Team: Spanish\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: api.lua +msgid "Secret Achievement Unlocked:" +msgstr "Logro secreto desbloqueado:" + +#: api.lua +msgid "Achievement Unlocked:" +msgstr "Logro desbloqueado:" + +#: api.lua +#, lua-format +msgid "Secret Achievement Unlocked: %s" +msgstr "Logro secreto desbloqueado: %s" + +#: api.lua +#, lua-format +msgid "Achievement Unlocked: %s" +msgstr "Logro desbloqueado: %s" + +#: api.lua +msgid "Secret Achievement Unlocked!" +msgstr "Logro secreto desbloqueado!" + +#: api.lua +msgid "Achievement Unlocked!" +msgstr "Logro desbloqueado!" + +#: api.lua +msgid "Error: No awards available." +msgstr "Error: No hay logros disponibles." + +#: api.lua +msgid "OK" +msgstr "Aceptar" + +#: api.lua +msgid "(Secret Award)" +msgstr "(Logro secreto)" + +#: api.lua +msgid "Unlock this award to find out what it is." +msgstr "Desbloquea éste logro para saber qué es." + +#: api.lua +#, lua-format +msgid "%s (got)" +msgstr "%s (obtenido)" + +#: api.lua +msgid "You've disabled awards. Type /awards enable to reenable." +msgstr "" +"Has deshabilitado los logros. Escribe \"/awards enable\" para reactivar." + +#: api.lua +msgid "You have not unlocked any awards." +msgstr "No has desbloqueado ningún logro." + +#: api.lua +#, lua-format +msgid "%s’s awards:" +msgstr "Logros de %s:" + +#: api.lua chat_commands.lua +#, lua-format +msgid "%s: %s" +msgstr "%s: %s" + +#: sfinv.lua unified_inventory.lua +msgid "Awards" +msgstr "Logros" + +#: triggers.lua +msgid "@1/@2 dug" +msgstr "@1/@2 excavados" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Mine: @2" +msgid_plural "Mine: @1×@2" +msgstr[0] "Excavar: @2" +msgstr[1] "Excavar: @1×@2" + +#: triggers.lua +msgid "Mine @1 block." +msgid_plural "Mine @1 blocks." +msgstr[0] "Excavar un bloque." +msgstr[1] "Excavar @1 bloques." + +#: triggers.lua +msgid "@1/@2 placed" +msgstr "@1/@2 colocados" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Place: @2" +msgid_plural "Place: @1×@2" +msgstr[0] "Colocar: @2" +msgstr[1] "Colocar: @1×@2" + +#: triggers.lua +msgid "Place a block." +msgid_plural "Place @1 blocks." +msgstr[0] "Colocar un bloque." +msgstr[1] "Colocar @1 bloques." + +#: triggers.lua +msgid "@1/@2 eaten" +msgstr "@1/@2 comidos" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Eat: @2" +msgid_plural "Eat: @1×@2" +msgstr[0] "Comer: @2" +msgstr[1] "Comer: @1×@2" + +#: triggers.lua +msgid "Eat an item." +msgid_plural "Eat @1 items." +msgstr[0] "Comer un objeto." +msgstr[1] "Comer @1 objetos." + +#: triggers.lua +msgid "@1/@2 deaths" +msgstr "@1/@2 muertes" + +#: triggers.lua +msgid "Die." +msgid_plural "Die @1 times." +msgstr[0] "Morir." +msgstr[1] "Morir @1 veces." + +#: triggers.lua +msgid "@1/@2 chat messages" +msgstr "@1/@2 conversaciones" + +#: triggers.lua +msgid "Write something in chat." +msgid_plural "Write @1 chat messages." +msgstr[0] "Escribir algo." +msgstr[1] "Escribir @1 mensajes." + +#: triggers.lua +msgid "@1/@2 game joins" +msgstr "@1/@2 veces unido" + +#: triggers.lua +msgid "Join the game." +msgid_plural "Join the game @1 times." +msgstr[0] "Unirse al juego." +msgstr[1] "Unirse al juego @1 veces." + +#: triggers.lua +msgid "@1/@2 crafted" +msgstr "@1/@2 elaborado" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Craft: @2" +msgid_plural "Craft: @1×@2" +msgstr[0] "Elaborar: @2" +msgstr[1] "Elaborar: %1×@2" + +#: triggers.lua +msgid "Craft an item." +msgid_plural "Craft @1 items." +msgstr[0] "Elaborar un objeto." +msgstr[1] "Elaborar @1 objetos." + +#: init.lua +msgid "Saint-Maclou" +msgstr "Saint-Maclou" + +#: init.lua +msgid "Place 20 coal checkers." +msgstr "Colocar 20 baldosas de ajedrez de carbón." + +#: init.lua +msgid "Castorama" +msgstr "Castorama" + +#: init.lua +msgid "Place 20 iron checkers." +msgstr "Colocar 20 baldosas de ajedrez de hierro." + +#: init.lua +msgid "Sam the Trapper" +msgstr "Sam el Atrapador" + +#: init.lua +msgid "Place 2 trap stones." +msgstr "Colocar 2 piedras trampa." + +#: init.lua +msgid "Backpacker" +msgstr "Mochilero" + +#: init.lua +msgid "Craft 4 large bags." +msgstr "Elaborar 4 bolsas grandes." + +#: init.lua +msgid "Pyromaniac" +msgstr "Piromaníaco" + +#: init.lua +msgid "Craft 8 times flint and steel." +msgstr "Elaborar pedernal y hierro 8 veces." + +#: init.lua +msgid "Firefighter" +msgstr "Bombero" + +#: init.lua +msgid "Put out 1000 fires." +msgstr "Apagar 1000 incendios." + +#: init.lua +msgid "Light It Up" +msgstr "Ilumínalo" + +#: init.lua +msgid "Place 100 torches." +msgstr "Colocar 100 antorchas." + +#: init.lua +msgid "Well Lit" +msgstr "Bien Iluminado" + +#: init.lua +msgid "Place 1,000 torches." +msgstr "Colocar 1.000 antorchas." + +#: init.lua +msgid "Really Well Lit" +msgstr "Realmente Bien Iluminado" + +#: init.lua +msgid "Craft 10 mese lamps." +msgstr "Elaborar 10 lámparas de MESE." + +#: init.lua +msgid "Outpost" +msgstr "Puesto de avanzada" + +#: init.lua +msgid "Craft 200 stone bricks." +msgstr "Elaborar 200 ladrillos de piedra." + +#: init.lua +msgid "Watchtower" +msgstr "Torre del vigía" + +#: init.lua +msgid "Craft 800 stone bricks." +msgstr "Elaborar 800 ladrillos de piedra." + +#: init.lua +msgid "Fortress" +msgstr "Fortaleza" + +#: init.lua +msgid "Craft 3,200 stone bricks." +msgstr "Elaborar 3.200 ladrillos de piedra." + +#: init.lua +msgid "Desert Dweller" +msgstr "Morador Desértico" + +#: init.lua +msgid "Craft 400 desert stone bricks." +msgstr "Elaborar 400 ladrillos de piedra desértica." + +#: init.lua +msgid "Pharaoh" +msgstr "Faraón" + +#: init.lua +msgid "Craft 100 sandstone bricks." +msgstr "Elaborar 200 ladrillos de arenisca." + +#: init.lua +msgid "Little Library" +msgstr "Pequeña Biblioteca" + +#: init.lua +msgid "Craft 7 bookshelves." +msgstr "Elaborar 7 libreros." + +#: init.lua +msgid "Lava and Water" +msgstr "Lava y Agua" + +#: init.lua +msgid "Mine your first obsidian." +msgstr "Excavar tu primera obsidiana." + +#: init.lua +msgid "Obsessed with Obsidian" +msgstr "Obsesionado con la Obsidiana" + +#: init.lua +msgid "Mine 50 obsidian." +msgstr "Excavar 50 obsidianas." + +#: init.lua +msgid "Lava Miner" +msgstr "Minero de Lava" + +#: init.lua +msgid "Mine any block while being very close to lava." +msgstr "Excavar un bloque cerca de lava." + +#: init.lua +msgid "On The Way" +msgstr "En Camino" + +#: init.lua +msgid "Place 100 rails." +msgstr "Colocar 100 rieles." + +#: init.lua +msgid "First Day in the Woods" +msgstr "Primer Día en el Bosque" + +#: init.lua +msgid "Dig 6 tree blocks." +msgstr "Cortar 6 árboles." + +#: init.lua +msgid "Lumberjack" +msgstr "Leñador" + +#: init.lua +msgid "Dig 36 tree blocks." +msgstr "Cortar 36 árboles." + +#: init.lua +msgid "Semi-pro Lumberjack" +msgstr "Leñador semi-profesional" + +#: init.lua +msgid "Dig 216 tree blocks." +msgstr "Cortar 216 árboles." + +#: init.lua +msgid "Professional Lumberjack" +msgstr "Leñador profesional" + +#: init.lua +msgid "Dig 1,296 tree blocks." +msgstr "Cortar 1.296 árboles." + +#: init.lua +msgid "Junglebaby" +msgstr "Bebé de la Selva" + +#: init.lua +msgid "Dig 100 jungle tree blocks." +msgstr "Cortar 100 árboles selváticos." + +#: init.lua +msgid "Jungleman" +msgstr "Hombre de la Selva" + +#: init.lua +msgid "Dig 1,000 jungle tree blocks." +msgstr "Cortar 1.000 árboles selváticos." + +#: init.lua +msgid "First Mese Find" +msgstr "Primer Encuentro de MESE" + +#: init.lua +msgid "Mine your first mese ore." +msgstr "Excava tu primer mineral de MESE." + +#: init.lua +msgid "Mese Mastery" +msgstr "Maestría de MESE" + +#: init.lua +msgid "Mine a mese block." +msgstr "Excava tu primer bloque de MESE." + +#: init.lua +msgid "You’re a copper" +msgstr "Eres un cobre" + +#: init.lua +msgid "Dig 1,000 copper ores." +msgstr "Excavar 1.000 minerales de cobre" + +#: init.lua +msgid "A Cat in a Pop-Tart?!" +msgstr "¡¿Un Gato en un Pop-Tart?!" + +#: init.lua +msgid "Mine a nyan cat." +msgstr "Excavar un Gato Nyan." + +#: init.lua +msgid "Mini Miner" +msgstr "Mini Minero" + +#: init.lua +msgid "Dig 100 stone blocks." +msgstr "Excavar 100 bloques de piedra." + +#: init.lua +msgid "Hardened Miner" +msgstr "Minero Curtido" + +#: init.lua +msgid "Dig 1,000 stone blocks." +msgstr "Excavar 1.000 bloques de piedra." + +#: init.lua +msgid "Master Miner" +msgstr "Minero Maestro" + +#: init.lua +msgid "Dig 10,000 stone blocks." +msgstr "Excavar 10.000 bloques de piedra." + +#: init.lua +msgid "Marchand De Sable" +msgstr "Marchand De Sable" + +#: init.lua +msgid "Dig 1,000 sand." +msgstr "Cavar 1.000 bloques de arena." + +#: init.lua +msgid "Crafter of Sticks" +msgstr "Elaborador de Varitas" + +#: init.lua +msgid "Craft 100 sticks." +msgstr "Elaborar 100 varitas." + +#: init.lua +msgid "Jungle Discoverer" +msgstr "Descubridor de Selva" + +#: init.lua +msgid "Mine your first jungle grass." +msgstr "Cortar tu primer pasto de selva." + +#: init.lua +msgid "Grasslands Discoverer" +msgstr "Descubridor de Praderas" + +#: init.lua +msgid "Mine some grass." +msgstr "Cortar un poco de pasto." + +#: init.lua +msgid "Savannah Discoverer" +msgstr "Descubridor de Savana" + +#: init.lua +msgid "Mine some dry grass." +msgstr "Cortar un poco de pasto seco." + +#: init.lua +msgid "Desert Discoverer" +msgstr "Descubridor del Desierto" + +#: init.lua +msgid "Mine your first cactus." +msgstr "Cortar tu primer cácto." + +#: init.lua +msgid "Far Lands" +msgstr "Tierras Lejanas" + +#: init.lua +msgid "Mine your first dry shrub." +msgstr "Cortar tu primer arbusto seco" + +#: init.lua +msgid "Glacier Discoverer" +msgstr "Descubridor del Glaciar" + +#: init.lua +msgid "Mine your first ice." +msgstr "Romper tu primer bloque de hielo." + +#: init.lua +msgid "Very Simple Snow Man" +msgstr "Muñeco de Nieve Muy Simple" + +#: init.lua +msgid "Place two snow blocks." +msgstr "Colocar dos bloques de nieve." + +#: init.lua +msgid "First Gold Find" +msgstr "Primer Encuentro de Oro" + +#: init.lua +msgid "Mine your first gold ore." +msgstr "Excavar tu primer pepita de oro." + +#: init.lua +msgid "Gold Rush" +msgstr "Fiebre del Oro" + +#: init.lua +msgid "Mine 45 gold ores." +msgstr "Excavar 45 pepitas de oro." + +#: init.lua +msgid "Wow, I am Diamonds!" +msgstr "¡Guau, Soy Diamantes!" + +#: init.lua +msgid "Mine your first diamond ore." +msgstr "Excava tu primer diamante." + +#: init.lua +msgid "Girl's Best Friend" +msgstr "El Mejor Amigo de Las Mujeres" + +#: init.lua +msgid "Mine 18 diamond ores." +msgstr "Excava 10 diamantes." + +#: init.lua +msgid "Hardest Block on Earth" +msgstr "El Bloque Más Duro Sobre La Tierra" + +#: init.lua +msgid "Craft a diamond block." +msgstr "Elaborar un bloque de diamante." + +#: init.lua +msgid "In the Dungeon" +msgstr "En Las Mazmorras" + +#: init.lua +msgid "Mine a mossy cobblestone." +msgstr "Excavar unos adoquines musgosos." + +#: init.lua +msgid "Smelter" +msgstr "Fundidor" + +#: init.lua +msgid "Craft 10 furnaces." +msgstr "Elaborar 10 hornos." + +#: init.lua +msgid "Treasurer" +msgstr "Tesorero" + +#: init.lua +msgid "Craft 15 chests." +msgstr "Elaborar 15 cofres." + +#: init.lua +msgid "Bankier" +msgstr "Banquero" + +#: init.lua +msgid "Craft 30 locked chests." +msgstr "Elaborar 30 bloques cerrados." + +#: init.lua +msgid "Bricker" +msgstr "Ladrillero" + +#: init.lua +msgid "Craft 200 brick blocks." +msgstr "Elaborar 200 bloques de ladrillo." + +#: init.lua +msgid "House of Obsidian" +msgstr "Casa de Obsidiana" + +#: init.lua +msgid "Craft 100 obsidian bricks." +msgstr "Elaborar 100 ladrillos de obsidiana." + +#: init.lua +msgid "Build a Cave" +msgstr "Construye Una Cueva" + +#: init.lua +msgid "Place 100 stone." +msgstr "Coloca 100 piedras." + +#: init.lua +msgid "Long Ladder" +msgstr "Escalerilla Larga" + +#: init.lua +msgid "Place 400 wooden ladders." +msgstr "Coloca 400 escalerillas de madera." + +#: init.lua +msgid "Industrial Age" +msgstr "Era Industrial" + +#: init.lua +msgid "Place 40 steel ladders." +msgstr "Coloca 40 escalerillas de acero." + +#: init.lua +msgid "Yummy!" +msgstr "¡Qué Rico!" + +#: init.lua +msgid "Eat 80 apples." +msgstr "Come 80 manzanas." + +# Intentionally marked as fuzzy. +#: init.lua +#, fuzzy +msgid "Glasser" +msgstr "Vidriero" + +#: init.lua +msgid "Craft 14 vessels shelves." +msgstr "Elabora 14 estanterías para botellas." + +#: init.lua +msgid "Farming Skills Acquired" +msgstr "Habilidades de Granja Adquiridas" + +#: init.lua +msgid "Harvest a fully grown wheat plant." +msgstr "Cosecha una plantas de trigo madura." + +#: init.lua +msgid "Field Worker" +msgstr "Trabajador de Campo" + +#: init.lua +msgid "Harvest 25 fully grown wheat plants." +msgstr "Cosecha 25 plantas de trigo maduras." + +#: init.lua +msgid "Aspiring Farmer" +msgstr "Aspirante a Granjero" + +#: init.lua +msgid "Harvest 125 fully grown wheat plants." +msgstr "Cosecha 125 plantas de trigo maduras." + +#: init.lua +msgid "Wheat Magnate" +msgstr "Magnate del Maíz" + +#: init.lua +msgid "Harvest 625 fully grown wheat plants." +msgstr "Cosecha 625 plantas de trigo maduras." + +#: init.lua +msgid "Baker" +msgstr "Panadero" + +#: init.lua +msgid "Eat 10 loaves of bread." +msgstr "Come 10 rebanadas de pan." + +#: init.lua +msgid "Wool Over Your Eyes" +msgstr "Lana Sobre Tus Ojos" + +#: init.lua +msgid "Craft 250 white wool." +msgstr "Elabora 250 bloques de lana blanca." + +#: init.lua +msgid "Hotelier" +msgstr "Hotelero" + +#: init.lua +msgid "Craft 15 fancy beds." +msgstr "Elabora 15 camas de lujo." + +#: init.lua +msgid "Filthy Rich" +msgstr "Sucio Rico" + +#: init.lua +msgid "Craft 24 gold block stairs." +msgstr "Elabora 24 escaleras de bloque de oro." + +#: init.lua +msgid "Roses Are Red" +msgstr "Las Rosas Son Rojas" + +#: init.lua +msgid "Craft 400 red dyes." +msgstr "Elabora 400 colorantes rojos." + +#: init.lua +msgid "Dandelions are Yellow" +msgstr "Los Dientes de León Son Amarillos" + +#: init.lua +msgid "Craft 400 yellow dyes." +msgstr "Elabora 400 colorantes amarillos." + +#: init.lua +msgid "Geraniums are Blue" +msgstr "Los Geranios Son Azules" + +#: init.lua +msgid "Craft 400 blue dyes." +msgstr "Elabora 400 colorantes azules." + +#: init.lua +msgid "White Color Stock" +msgstr "Reserva de Color Blanco" + +#: init.lua +msgid "Craft 100 white dyes." +msgstr "Elabora 100 colorantes blancos." + +#: init.lua +msgid "Tasty Mushrooms" +msgstr "Ricos Hongos" + +#: init.lua +msgid "Eat 3 brown mushrooms." +msgstr "Come 3 hongos marrones." + +#: init.lua +msgid "Mushroom Lover" +msgstr "Amante de los Hongos" + +#: init.lua +msgid "Eat 33 brown mushrooms." +msgstr "Come 33 hongos marrones." + +#: init.lua +msgid "Underground Mushroom Farmer" +msgstr "Granjero de Hongos Subterráneo" + +#: init.lua +msgid "Eat 333 brown mushrooms." +msgstr "Come 333 hongos marrones." + +# Nota: "Builder" y "Constructor" se traducen a "Constructor", +# así que lo traduje de ésta manera para diferenciar. +#: init.lua +msgid "Builder" +msgstr "Hacedor" + +#: init.lua +msgid "Constructor" +msgstr "Constructor" + +#: init.lua +msgid "Architect" +msgstr "Arquitecto" + +#: init.lua +msgid "Master Architect" +msgstr "Maestro Arquitecto" + +#: chat_commands.lua +msgid "[c|clear|disable|enable]" +msgstr "[c|clear|disable|enable]" + +#: chat_commands.lua +msgid "Show, clear, disable or enable your achievements" +msgstr "Mostrar, limpiar, deshabilitar o habilitar tus logros" + +#: chat_commands.lua +msgid "" +"All your awards and statistics have been cleared. You can now start again." +msgstr "" +"Todos tus logros y estadísticas han sido borrados. Puedes iniciar nuevamente." + +#: chat_commands.lua +msgid "You have disabled your achievements." +msgstr "Has deshabilitado tus logros." + +#: chat_commands.lua +msgid "You have enabled your achievements." +msgstr "Has habilitado tus logros." + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Show details of an achievement" +msgstr "Muestra los detalles de un logro" + +#: chat_commands.lua +msgid "Achievement not found." +msgstr "Logro no encontrado." + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Get the achievements statistics for the given player or yourself" +msgstr "Obtener las estadísticas y logros del jugador dado" diff --git a/mods/awards/locale/fr.po b/mods/awards/locale/fr.po new file mode 100644 index 0000000..e173437 --- /dev/null +++ b/mods/awards/locale/fr.po @@ -0,0 +1,818 @@ +# French translations for PACKAGE package. +# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# xisd, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 05:50-0300\n" +"PO-Revision-Date: 2017-02-21 05:50-0300\n" +"Last-Translator: xisd\n" +"Language-Team: French\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: api.lua +msgid "Secret Achievement Unlocked:" +msgstr "Réussite Secrète Débloquée :" + +#: api.lua +msgid "Achievement Unlocked:" +msgstr "Réussite Débloquée :" + +#: api.lua +#, lua-format +msgid "Secret Achievement Unlocked: %s" +msgstr "Réussite Secrète Débloquée : %s" + +#: api.lua +#, lua-format +msgid "Achievement Unlocked: %s" +msgstr "Réussite Débloquée : %s" + +#: api.lua +msgid "Secret Achievement Unlocked!" +msgstr "Réussite Secrète Débloquée !" + +#: api.lua +msgid "Achievement Unlocked!" +msgstr "Réussite Débloquée !" + +#: api.lua +msgid "Error: No awards available." +msgstr "Erreur : Aucun trophée disponible" + +#: api.lua +msgid "OK" +msgstr "OK" + +#: api.lua +msgid "(Secret Award)" +msgstr "(Trophée Secret)" + +#: api.lua +msgid "Unlock this award to find out what it is." +msgstr "Débloque ce trophée pour découvrir ce que c'est." + +#: api.lua +#, lua-format +msgid "%s (got)" +msgstr "%s (obtenu)" + +#: api.lua +msgid "You've disabled awards. Type /awards enable to reenable." +msgstr "Vous avez désactivé les trophées. Tapez '/awards enable' pour les réactiver." + +#: api.lua +msgid "You have not unlocked any awards." +msgstr "Vous n'avez encore débloqué aucun trophée." + +#: api.lua +#, lua-format +msgid "%s’s awards:" +msgstr "Les trophées de %s :" + +#: api.lua chat_commands.lua +#, lua-format +msgid "%s: %s" +msgstr "%s : %s" + +#: sfinv.lua unified_inventory.lua +msgid "Awards" +msgstr "Trophées" + +#: triggers.lua +msgid "@1/@2 dug" +msgstr "@1/@2 creusés" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Mine: @2" +msgid_plural "Mine: @1×@2" +msgstr[0] "Mine : @2" +msgstr[1] "Mine : @1×@2" + +#: triggers.lua +msgid "Mine @1 block." +msgid_plural "Mine @1 blocks." +msgstr[0] "Creuse @1 bloc." +msgstr[1] "Creuse @1 blocs." + +#: triggers.lua +msgid "@1/@2 placed" +msgstr "@1/@2 placés" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Place: @2" +msgid_plural "Place: @1×@2" +msgstr[0] "Place : @2" +msgstr[1] "Place : @1×@2" + +#: triggers.lua +msgid "Place a block." +msgid_plural "Place @1 blocks." +msgstr[0] "Place un bloc." +msgstr[1] "Place @1 blocs." + +#: triggers.lua +msgid "@1/@2 eaten" +msgstr "@1/@2 Mangés" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Eat: @2" +msgid_plural "Eat: @1×@2" +msgstr[0] "Mange : @2" +msgstr[1] "Mange : @1×@2" + +#: triggers.lua +msgid "Eat an item." +msgid_plural "Eat @1 items." +msgstr[0] "Mange quelque chose." +msgstr[1] "Mange @1 aliments." + +#: triggers.lua +msgid "@1/@2 deaths" +msgstr "@1/@2 morts" + +#: triggers.lua +msgid "Die." +msgid_plural "Die @1 times." +msgstr[0] "Mort·e." +msgstr[1] "Mort·e %d fois." + +#: triggers.lua +msgid "@1/@2 chat messages" +msgstr "@1/@2 messages du chat" + +#: triggers.lua +msgid "Write something in chat." +msgid_plural "Write @1 chat messages." +msgstr[0] "Écrit quelque chose dans le chat." +msgstr[1] "Écrit @1 messages dans le chat." + +#: triggers.lua +msgid "@1/@2 game joins" +msgstr "@1/@2 connexions" + +#: triggers.lua +msgid "Join the game." +msgid_plural "Join the game @1 times." +msgstr[0] "Connecte toi au jeu." +msgstr[1] "Connecte toi au jeu @1 fois." + +#: triggers.lua +msgid "@1/@2 crafted" +msgstr "@1/@2 craftés" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Craft: @2" +msgid_plural "Craft: @1×@2" +msgstr[0] "Fabrique : @2" +msgstr[1] "Fabrique : @1×@2" + +#: triggers.lua +msgid "Craft an item." +msgid_plural "Craft @1 items." +msgstr[0] "Confectionne un objet." +msgstr[1] "Confectionne @1 objets." + +#: init.lua +msgid "Saint-Maclou" +msgstr "Saint-Maclou" + +#: init.lua +msgid "Place 20 coal checkers." +msgstr "Place 20 damiers de charbon." + +#: init.lua +msgid "Castorama" +msgstr "Castorama" + +#: init.lua +msgid "Place 20 iron checkers." +msgstr "Place 20 damiers de fer." + +#: init.lua +msgid "Sam the Trapper" +msgstr "Sam le Trappeur" + +#: init.lua +msgid "Place 2 trap stones." +msgstr "Place 2 pièges de pierre." + +#: init.lua +msgid "Backpacker" +msgstr "Randonneu·r·se" + +#: init.lua +msgid "Craft 4 large bags." +msgstr "Confectionne 4 grands sacs" + +#: init.lua +msgid "Pyromaniac" +msgstr "Pyromane" + +#: init.lua +msgid "Craft 8 times flint and steel." +msgstr "Fabrique 8 silex et aciers." + +#: init.lua +msgid "Firefighter" +msgstr "Pompier" + +#: init.lua +msgid "Put out 1000 fires." +msgstr "Éteint 1000 feux." + +#: init.lua +msgid "Light It Up" +msgstr "Eclairé·e" + +#: init.lua +msgid "Place 100 torches." +msgstr "Place 100 torches." + +#: init.lua +msgid "Well Lit" +msgstr "Bien Éclairé" + +#: init.lua +msgid "Place 1,000 torches." +msgstr "Place 1000 torches." + +#: init.lua +msgid "Really Well Lit" +msgstr "Vraiment Bien Éclairé" + +#: init.lua +msgid "Craft 10 mese lamps." +msgstr "Fabrique 10 lampes de mese." + +#: init.lua +msgid "Outpost" +msgstr "Poste Avancé" + +#: init.lua +msgid "Craft 200 stone bricks." +msgstr "Confectionne 200 briques de pierre." + +#: init.lua +msgid "Watchtower" +msgstr "Tour de Garde" + +#: init.lua +msgid "Craft 800 stone bricks." +msgstr "Confectionne 800 briques de pierre." + +#: init.lua +msgid "Fortress" +msgstr "Forteresse" + +#: init.lua +msgid "Craft 3,200 stone bricks." +msgstr "Confectionne 3200 briques de pierre." + +#: init.lua +msgid "Desert Dweller" +msgstr "Habitant·e du Désert" + +#: init.lua +msgid "Craft 400 desert stone bricks." +msgstr "Confectionne 400 briques de pierre du désert." + +#: init.lua +msgid "Pharaoh" +msgstr "Pharaon" + +#: init.lua +msgid "Craft 100 sandstone bricks." +msgstr "Confectionne 100 briques de roche de sable." + +#: init.lua +msgid "Little Library" +msgstr "Petite Bibliothèque" + +#: init.lua +msgid "Craft 7 bookshelves." +msgstr "Fabrique 7 bibliothèques." + +#: init.lua +msgid "Lava and Water" +msgstr "La Lave et l'Eau" + +#: init.lua +msgid "Mine your first obsidian." +msgstr "Mine ton premier bloc d'obsidienne." + +#: init.lua +msgid "Obsessed with Obsidian" +msgstr "Obsédé·e par l'obsidienne" + +#: init.lua +msgid "Mine 50 obsidian." +msgstr "Mine 50 pierres d'obsidienne." + +#: init.lua +msgid "Lava Miner" +msgstr "Mineu·r·se de lave" + +#: init.lua +msgid "Mine any block while being very close to lava." +msgstr "Mine n'importe quel bloc à proximité de la lave." + +#: init.lua +msgid "On The Way" +msgstr "Sur La Voie" + +#: init.lua +msgid "Place 100 rails." +msgstr "Place 100 rails." + +#: init.lua +msgid "First Day in the Woods" +msgstr "Premier Jour dans les Bois" + +#: init.lua +msgid "Dig 6 tree blocks." +msgstr "Creuse 6 blocs d'arbre." + +#: init.lua +msgid "Lumberjack" +msgstr "Bûcheron·ne" + +#: init.lua +msgid "Dig 36 tree blocks." +msgstr "Creuse 36 blocs d'arbre." + +#: init.lua +msgid "Semi-pro Lumberjack" +msgstr "Bûcheron.ne. Semi-Professionnel.le." + +#: init.lua +msgid "Dig 216 tree blocks." +msgstr "Creuse 216 blocs d'arbre." + +#: init.lua +msgid "Professional Lumberjack" +msgstr "Bûcheron·ne Professionnel·le" + +#: init.lua +msgid "Dig 1,296 tree blocks." +msgstr "Creuse 1296 blocs d'arbre." + +#: init.lua +msgid "Junglebaby" +msgstr "Enfant de la Jungle" + +#: init.lua +msgid "Dig 100 jungle tree blocks." +msgstr "Creuse 100 blocs d'arbres de jungle." + +#: init.lua +msgid "Jungleman" +msgstr "Personne de la Jungle" + +#: init.lua +msgid "Dig 1,000 jungle tree blocks." +msgstr "Creuse 1000 blocs d'arbre de jungle." + +#: init.lua +msgid "First Mese Find" +msgstr "Première Pépite : Mese" + +#: init.lua +msgid "Mine your first mese ore." +msgstr "Mine ton premier minerai de mese." + +#: init.lua +msgid "Mese Mastery" +msgstr "Maîtrise de Mese" + +#: init.lua +msgid "Mine a mese block." +msgstr "Mine un bloc de mese." + +#: init.lua +msgid "You’re a copper" +msgstr "Faîtes Jouer les Cuivres" + +#: init.lua +msgid "Dig 1,000 copper ores." +msgstr "Creuse 1000 minerais de cuivre." + +#: init.lua +msgid "A Cat in a Pop-Tart?!" +msgstr "Un Chat dans un Pop-Tart ?!" + +#: init.lua +msgid "Mine a nyan cat." +msgstr "Mine un nyan cat." + +#: init.lua +msgid "Mini Miner" +msgstr "Mini Mineu·r·se" + +#: init.lua +msgid "Dig 100 stone blocks." +msgstr "Creuse 100 blocs de pierre." + +#: init.lua +msgid "Hardened Miner" +msgstr "Mineu·r·se Endurci·e" + +#: init.lua +msgid "Dig 1,000 stone blocks." +msgstr "Creuse 1000 blocs de pierre." + +#: init.lua +msgid "Master Miner" +msgstr "Maître·sse Mineu·r·se" + +#: init.lua +msgid "Dig 10,000 stone blocks." +msgstr "Creuse 10000 blocs de pierre." + +#: init.lua +msgid "Marchand De Sable" +msgstr "Marchand·e De Sable" + +#: init.lua +msgid "Dig 1,000 sand." +msgstr "Creuse 1000 blocs de sable." + +#: init.lua +msgid "Crafter of Sticks" +msgstr "Fabriquant·e de Bâtons." + +#: init.lua +msgid "Craft 100 sticks." +msgstr "Confectionne 100 bâtons." + +#: init.lua +msgid "Jungle Discoverer" +msgstr "Explorat·eur·rice de la Jungle" + +#: init.lua +msgid "Mine your first jungle grass." +msgstr "Ramasse ta première herbe de jungle." + +#: init.lua +msgid "Grasslands Discoverer" +msgstr "Découvreu·r·se de prairies" + +#: init.lua +msgid "Mine some grass." +msgstr "Ramasse de l'herbe." + +#: init.lua +msgid "Savannah Discoverer" +msgstr "Explorat·eur·rice de la Savanne" + +#: init.lua +msgid "Mine some dry grass." +msgstr "Ramasse de l'herbe sèche." + +#: init.lua +msgid "Desert Discoverer" +msgstr "Expolrat·eur·rice du Désert." + +#: init.lua +msgid "Mine your first cactus." +msgstr "Mine ton premier catus." + +#: init.lua +msgid "Far Lands" +msgstr "Terres Lointaines" + +#: init.lua +msgid "Mine your first dry shrub." +msgstr "Coupe ton premier arbuste sec." + +#: init.lua +msgid "Glacier Discoverer" +msgstr "Découvreu·r·se de glacier" + +#: init.lua +msgid "Mine your first ice." +msgstr "Creuse ton premier bloc de glace." + +#: init.lua +msgid "Very Simple Snow Man" +msgstr "Bonhomme de Neige Rudimentaire" + +#: init.lua +msgid "Place two snow blocks." +msgstr "Place deux blocs de neige." + +#: init.lua +msgid "First Gold Find" +msgstr "Première Pépite : Or" + +#: init.lua +msgid "Mine your first gold ore." +msgstr "Mine ton premier minerai d'or." + +#: init.lua +msgid "Gold Rush" +msgstr "Ruée vers l'Or" + +#: init.lua +msgid "Mine 45 gold ores." +msgstr "Mine 45 minerais d'or." + +#: init.lua +msgid "Wow, I am Diamonds!" +msgstr "Wow, Je suis Diamants!" + +#: init.lua +msgid "Mine your first diamond ore." +msgstr "Mine ton premier diamant." + +#: init.lua +#, fuzzy +msgid "Girl's Best Friend" +msgstr "Girl's Best Friend" + +#: init.lua +msgid "Mine 18 diamond ores." +msgstr "Mine 18 diamants." + +#: init.lua +msgid "Hardest Block on Earth" +msgstr "Le Bloc le Plus Dur du Monde" + +#: init.lua +msgid "Craft a diamond block." +msgstr "Confectionne un bloc de diamant." + +#: init.lua +msgid "In the Dungeon" +msgstr "Dans le Donjon" + +#: init.lua +msgid "Mine a mossy cobblestone." +msgstr "Mine un bloc de pavés moussus." + +#: init.lua +msgid "Smelter" +msgstr "Fondeu·r·se" + +#: init.lua +msgid "Craft 10 furnaces." +msgstr "Construis 10 fours." + +#: init.lua +msgid "Treasurer" +msgstr "Trésori·er·ère" + +#: init.lua +msgid "Craft 15 chests." +msgstr "Fabrique 15 coffres." + +#: init.lua +msgid "Bankier" +msgstr "Banqui·er·ère" + +#: init.lua +msgid "Craft 30 locked chests." +msgstr "Fabrique 30 coffres Verrouillés." + +#: init.lua +msgid "Bricker" +msgstr "Briqueu·r·se" + +#: init.lua +msgid "Craft 200 brick blocks." +msgstr "Confectionne 200 blocs de brique." + +#: init.lua +msgid "House of Obsidian" +msgstr "La Maison de L'Obsidienne" + +#: init.lua +msgid "Craft 100 obsidian bricks." +msgstr "Confectionne 100 briques d'obsidienne." + +#: init.lua +msgid "Build a Cave" +msgstr "Construis une grotte" + +#: init.lua +msgid "Place 100 stone." +msgstr "Place 100 pierres." + +#: init.lua +msgid "Long Ladder" +msgstr "Longue Echelle" + +#: init.lua +msgid "Place 400 wooden ladders." +msgstr "Place 400 échelles en bois." + +#: init.lua +msgid "Industrial Age" +msgstr "Âge Industriel" + +#: init.lua +msgid "Place 40 steel ladders." +msgstr "Place 40 échelles métalliques." + +#: init.lua +msgid "Yummy!" +msgstr "Miam !" + +#: init.lua +msgid "Eat 80 apples." +msgstr "Mange 80 pommes." + +#: init.lua +msgid "Glasser" +msgstr "Verri·er·ère" + +#: init.lua +msgid "Craft 14 vessels shelves." +msgstr "Fabrique 14 vaisseliers." + +#: init.lua +msgid "Farming Skills Acquired" +msgstr "Compétences Paysannes Acquises" + +#: init.lua +msgid "Harvest a fully grown wheat plant." +msgstr "Récolte un plant de blé à maturité." + +#: init.lua +msgid "Field Worker" +msgstr "Travailleu·r·se Agricole" + +#: init.lua +msgid "Harvest 25 fully grown wheat plants." +msgstr "Récolte 25 plants de blé à maturité." + +#: init.lua +msgid "Aspiring Farmer" +msgstr "Apprenti·e Fermi·er·ère" + +#: init.lua +msgid "Harvest 125 fully grown wheat plants." +msgstr "Récolte 125 plants de blé à maturité." + +#: init.lua +msgid "Wheat Magnate" +msgstr "Magnat·e du Blé" + +#: init.lua +msgid "Harvest 625 fully grown wheat plants." +msgstr "Récolte 625 plants de blé à maturité." + +#: init.lua +msgid "Baker" +msgstr "Boulang·er·ère" + +#: init.lua +msgid "Eat 10 loaves of bread." +msgstr "Mange 10 miches de pain." + +#: init.lua +msgid "Wool Over Your Eyes" +msgstr "De la Laines dans Tes Yeux" + +#: init.lua +msgid "Craft 250 white wool." +msgstr "Confectionne 250 blocs de laine blanche." + +#: init.lua +msgid "Hotelier" +msgstr "Hoteli·er·ère" + +#: init.lua +msgid "Craft 15 fancy beds." +msgstr "Construis 15 lits chics." + +#: init.lua +msgid "Filthy Rich" +msgstr "Richissime" + +#: init.lua +msgid "Craft 24 gold block stairs." +msgstr "Construis 24 escaliers en or." + +#: init.lua +msgid "Roses Are Red" +msgstr "Les Roses Sont Rouges" + +#: init.lua +msgid "Craft 400 red dyes." +msgstr "Prépare 400 teintures rouges." + +#: init.lua +msgid "Dandelions are Yellow" +msgstr "Les Pissenlits sont Jaunes." + +#: init.lua +msgid "Craft 400 yellow dyes." +msgstr "Prépare 400 teintures jaunes." + +#: init.lua +msgid "Geraniums are Blue" +msgstr "Les Geraniums Sont Bleus" + +#: init.lua +msgid "Craft 400 blue dyes." +msgstr "Prépare 400 teintures bleues." + +#: init.lua +msgid "White Color Stock" +msgstr "Chaussettes Blanches" + +#: init.lua +msgid "Craft 100 white dyes." +msgstr "Prépare 100 teintures blanches." + +#: init.lua +msgid "Tasty Mushrooms" +msgstr "Délicieux Champignons" + +#: init.lua +msgid "Eat 3 brown mushrooms." +msgstr "Mange 3 champignons marrons." + +#: init.lua +msgid "Mushroom Lover" +msgstr "Adorat·eur·rice de Champignons" + +#: init.lua +msgid "Eat 33 brown mushrooms." +msgstr "Mange 33 champignons marrons." + +#: init.lua +msgid "Underground Mushroom Farmer" +msgstr "Culture de Champignons en Cave" + +#: init.lua +msgid "Eat 333 brown mushrooms." +msgstr "Mange 333 champignons marrons." + +#: init.lua +msgid "Builder" +msgstr "Bâtisseu·r·se" + +#: init.lua +msgid "Constructor" +msgstr "Construct·eur·rice" + +#: init.lua +msgid "Architect" +msgstr "Architecte" + +#: init.lua +msgid "Master Architect" +msgstr "Maître·sse Architecte" + +#: chat_commands.lua +msgid "[c|clear|disable|enable]" +msgstr "[c|clear|disable|enable]" + +#: chat_commands.lua +msgid "Show, clear, disable or enable your achievements" +msgstr "Affiche, réinitialise, désactive ou active vos réussites." + +#: chat_commands.lua +msgid "All your awards and statistics have been cleared. You can now start again." +msgstr "Tous vos trophées et statistiques ont été réinitialisés. Vous pouvez recommencer à nouveau." + +#: chat_commands.lua +msgid "You have disabled your achievements." +msgstr "Vous avez désactivé vos réussites." + +#: chat_commands.lua +msgid "You have enabled your achievements." +msgstr "Vous avez activé vos réussites." + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Show details of an achievement" +msgstr "Afficher les détails d'une réussite" + +#: chat_commands.lua +msgid "Achievement not found." +msgstr "Réussite non trouvée." + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Get the achievements statistics for the given player or yourself" +msgstr "Obtenez les statistiques des réussites d'un joueur donné ou de vous-même" diff --git a/mods/awards/locale/pt.po b/mods/awards/locale/pt.po new file mode 100644 index 0000000..e28b909 --- /dev/null +++ b/mods/awards/locale/pt.po @@ -0,0 +1,819 @@ +# Portuguese translations for Awards package. +# Copyright (C) 2018 +# This file is distributed under the same license as the Awards package. +# FIRST AUTHOR borgesdossantosbruno@gmail.com, 2018. +# BrunoMine, 2018 +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 05:50-0300\n" +"PO-Revision-Date: 2018-08-01 16:16-0300\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.0.6\n" +"Last-Translator: BrunoMine\n" +"Language: pt\n" + +#: api.lua +msgid "Secret Achievement Unlocked:" +msgstr "Conquista Secreta Desbloqueada:" + +#: api.lua +msgid "Achievement Unlocked:" +msgstr "Conquista Desbloqueada:" + +#: api.lua +#, lua-format +msgid "Secret Achievement Unlocked: %s" +msgstr "Conquista Secreta Desbloqueada: %s" + +#: api.lua +#, lua-format +msgid "Achievement Unlocked: %s" +msgstr "Conquista Desbloqueada: %s" + +#: api.lua +msgid "Secret Achievement Unlocked!" +msgstr "Conquista Secreta Desbloqueada!" + +#: api.lua +msgid "Achievement Unlocked!" +msgstr "Conquista Desbloqueada!" + +#: api.lua +msgid "Error: No awards available." +msgstr "Erro: Nenhuma conquista encontrada." + +#: api.lua +msgid "OK" +msgstr "OK" + +#: api.lua +msgid "(Secret Award)" +msgstr "(Conquista Secreta)" + +#: api.lua +msgid "Unlock this award to find out what it is." +msgstr "Desbloqueie essa conquista para descobrir o que significa." + +#: api.lua +#, lua-format +msgid "%s (got)" +msgstr "%s (obtido)" + +#: api.lua +msgid "You've disabled awards. Type /awards enable to reenable." +msgstr "Desabilitaste as conquistas. Digite /awards enable para reabilitar." + +#: api.lua +msgid "You have not unlocked any awards." +msgstr "Nenhuma conquista desbloqueada ainda." + +#: api.lua +#, lua-format +msgid "%s’s awards:" +msgstr "%s das conquistas:" + +#: api.lua chat_commands.lua +#, lua-format +msgid "%s: %s" +msgstr "%s: %s" + +#: sfinv.lua unified_inventory.lua +msgid "Awards" +msgstr "Conquistas" + +#: triggers.lua +msgid "@1/@2 dug" +msgstr "@1 de @2 obtidos" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Mine: @2" +msgid_plural "Mine: @1×@2" +msgstr[0] "Cavar: @2" +msgstr[1] "Minar: @1×@2" + +#: triggers.lua +msgid "Mine @1 block." +msgid_plural "Mine @1 blocks." +msgstr[0] "Cavar um bloco." +msgstr[1] "Cavar @1 blocos." + +#: triggers.lua +msgid "@1/@2 placed" +msgstr "@1 de @2 colocados" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Place: @2" +msgid_plural "Place: @1×@2" +msgstr[0] "Colocar: @2" +msgstr[1] "Place: @1×@2" + +#: triggers.lua +msgid "Place a block." +msgid_plural "Place @1 blocks." +msgstr[0] "Colocar um bloco." +msgstr[1] "Colocar @1 blocos." + +#: triggers.lua +msgid "@1/@2 eaten" +msgstr "@1 de @2 consumidos" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Eat: @2" +msgid_plural "Eat: @1×@2" +msgstr[0] "Consumir: @2" +msgstr[1] "Consumir: @1×@2" + +#: triggers.lua +msgid "Eat an item." +msgid_plural "Eat @1 items." +msgstr[0] "Consumir um item." +msgstr[1] "Consumir @1 itens." + +#: triggers.lua +msgid "@1/@2 deaths" +msgstr "@1 de @2 mortes" + +#: triggers.lua +msgid "Die." +msgid_plural "Die @1 times." +msgstr[0] "Morrer." +msgstr[1] "Morrer @1 vezes." + +#: triggers.lua +msgid "@1/@2 chat messages" +msgstr "@1 de @2" + +#: triggers.lua +msgid "Write something in chat." +msgid_plural "Write @1 chat messages." +msgstr[0] "Escrever algo no bate papo." +msgstr[1] "Escrever @1 mensagens no bate papo." + +#: triggers.lua +msgid "@1/@2 game joins" +msgstr "@1 de @2" + +#: triggers.lua +msgid "Join the game." +msgid_plural "Join the game @1 times." +msgstr[0] "Entre no jogo." +msgstr[1] "Entre no jogo @1 vezes." + +#: triggers.lua +msgid "@1/@2 crafted" +msgstr "@1 de @2 feitos" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Craft: @2" +msgid_plural "Craft: @1×@2" +msgstr[0] "Fazer @2" +msgstr[1] "Montar @2 @1 vezes" + +#: triggers.lua +msgid "Craft an item." +msgid_plural "Craft @1 items." +msgstr[0] "Fazer um item." +msgstr[1] "Fazer @1 itens." + +#: init.lua +msgid "Saint-Maclou" +msgstr "Saint-Maclou" + +#: init.lua +msgid "Place 20 coal checkers." +msgstr "" + +#: init.lua +msgid "Castorama" +msgstr "" + +#: init.lua +msgid "Place 20 iron checkers." +msgstr "" + +#: init.lua +msgid "Sam the Trapper" +msgstr "" + +#: init.lua +msgid "Place 2 trap stones." +msgstr "" + +#: init.lua +msgid "Backpacker" +msgstr "" + +#: init.lua +msgid "Craft 4 large bags." +msgstr "" + +#: init.lua +msgid "Pyromaniac" +msgstr "Piromaníaco" + +#: init.lua +msgid "Craft 8 times flint and steel." +msgstr "Montar acendedor de Ferro e Pederneira 8 vezes." + +#: init.lua +msgid "Firefighter" +msgstr "Bombeiro" + +#: init.lua +msgid "Put out 1000 fires." +msgstr "Apagar fogo 1000 vezes." + +#: init.lua +msgid "Light It Up" +msgstr "Ilumine Isso" + +#: init.lua +msgid "Place 100 torches." +msgstr "Colocar 100 tochas." + +#: init.lua +msgid "Well Lit" +msgstr "Bem Iluminado" + +#: init.lua +msgid "Place 1,000 torches." +msgstr "Colocar 1.000 tochas." + +#: init.lua +msgid "Really Well Lit" +msgstr "Realmente Bem Iluminado" + +#: init.lua +msgid "Craft 10 mese lamps." +msgstr "Fazer 10 lâmpadas de mese." + +#: init.lua +msgid "Outpost" +msgstr "Posto Avançado" + +#: init.lua +msgid "Craft 200 stone bricks." +msgstr "Fazer 200 tijolos de pedra." + +#: init.lua +msgid "Watchtower" +msgstr "Sentinela" + +#: init.lua +msgid "Craft 800 stone bricks." +msgstr "Fazer 800 tijolos de pedra." + +#: init.lua +msgid "Fortress" +msgstr "Fortaleza" + +#: init.lua +msgid "Craft 3,200 stone bricks." +msgstr "Fazer 3.200 tijolos de pedra." + +#: init.lua +msgid "Desert Dweller" +msgstr "Morador do Deserto" + +#: init.lua +msgid "Craft 400 desert stone bricks." +msgstr "Fazer 400 Tijolos de pedra do deserto." + +#: init.lua +msgid "Pharaoh" +msgstr "Faraó" + +#: init.lua +msgid "Craft 100 sandstone bricks." +msgstr "Fazer 100 tijolos de arenito." + +#: init.lua +msgid "Little Library" +msgstr "Pequena Biblioteca" + +#: init.lua +msgid "Craft 7 bookshelves." +msgstr "Fazer 7 estantes de livros." + +#: init.lua +msgid "Lava and Water" +msgstr "Lava e Ãgua" + +#: init.lua +msgid "Mine your first obsidian." +msgstr "Cavar sua primeira obsidiana." + +#: init.lua +msgid "Obsessed with Obsidian" +msgstr "Obcecado por Obsidiana" + +#: init.lua +msgid "Mine 50 obsidian." +msgstr "Minerar 50 obsidianas." + +#: init.lua +msgid "Lava Miner" +msgstr "Minerador de Lava" + +#: init.lua +msgid "Mine any block while being very close to lava." +msgstr "Minerar qualquer bloco enquanto estiver mergulhado em lava." + +#: init.lua +msgid "On The Way" +msgstr "No Caminho" + +#: init.lua +msgid "Place 100 rails." +msgstr "Colocar 100 trilhos." + +#: init.lua +msgid "First Day in the Woods" +msgstr "Primeiro dia na Floresta" + +#: init.lua +msgid "Dig 6 tree blocks." +msgstr "Cortar 6 blocos de árvore." + +#: init.lua +msgid "Lumberjack" +msgstr "Lenhador" + +#: init.lua +msgid "Dig 36 tree blocks." +msgstr "Cortar 36 blocos de árvore." + +#: init.lua +msgid "Semi-pro Lumberjack" +msgstr "Lenhador Semi-Profissional" + +#: init.lua +msgid "Dig 216 tree blocks." +msgstr "Cortar 216 blocos de árvore." + +#: init.lua +msgid "Professional Lumberjack" +msgstr "Lenhador Profissional" + +#: init.lua +msgid "Dig 1,296 tree blocks." +msgstr "Cortar 1.296 blocos de árvore." + +#: init.lua +msgid "Junglebaby" +msgstr "Bebê Selvagem" + +#: init.lua +msgid "Dig 100 jungle tree blocks." +msgstr "Cortar 100 blocos de árvore selvagem." + +#: init.lua +msgid "Jungleman" +msgstr "Homem Selvagem" + +#: init.lua +msgid "Dig 1,000 jungle tree blocks." +msgstr "Cortar 1.000 blocos de árvore selvagem." + +#: init.lua +msgid "First Mese Find" +msgstr "Primeiro Mese" + +#: init.lua +msgid "Mine your first mese ore." +msgstr "Cavar seu primeiro mese." + +#: init.lua +msgid "Mese Mastery" +msgstr "Mestre do Mese" + +#: init.lua +msgid "Mine a mese block." +msgstr "Cavar um bloco de mese." + +#: init.lua +msgid "You’re a copper" +msgstr "Sou um Cobre" + +#: init.lua +msgid "Dig 1,000 copper ores." +msgstr "Minerar 1.000 cobres." + +#: init.lua +msgid "A Cat in a Pop-Tart?!" +msgstr "Um Gato em um Pop-Tart?!" + +#: init.lua +msgid "Mine a nyan cat." +msgstr "Capturar um gato nyan." + +#: init.lua +msgid "Mini Miner" +msgstr "Mini Minerador" + +#: init.lua +msgid "Dig 100 stone blocks." +msgstr "Minerar 100 blocos de pedra." + +#: init.lua +msgid "Hardened Miner" +msgstr "Minerador Avançado" + +#: init.lua +msgid "Dig 1,000 stone blocks." +msgstr "Minerar 1.000 blocos de pedra." + +#: init.lua +msgid "Master Miner" +msgstr "Minerador Mestre" + +#: init.lua +msgid "Dig 10,000 stone blocks." +msgstr "Minerar 10.000 blocos de pedra." + +#: init.lua +msgid "Marchand De Sable" +msgstr "Vendedor de Areia" + +#: init.lua +msgid "Dig 1,000 sand." +msgstr "Cavar 1.000 blocos de areia." + +#: init.lua +msgid "Crafter of Sticks" +msgstr "Rachador de Lenha" + +#: init.lua +msgid "Craft 100 sticks." +msgstr "Lenhar 100 gravetos." + +#: init.lua +msgid "Jungle Discoverer" +msgstr "Desbravador Selvagem" + +#: init.lua +msgid "Mine your first jungle grass." +msgstr "Cortar seu primeiro mato selvagem." + +#: init.lua +msgid "Grasslands Discoverer" +msgstr "Descobridor do Gramado" + +#: init.lua +msgid "Mine some grass." +msgstr "Minerar algum mato" + +#: init.lua +msgid "Savannah Discoverer" +msgstr "Descobridor da Savana" + +#: init.lua +msgid "Mine some dry grass." +msgstr "Minerar algum mato seco." + +#: init.lua +msgid "Desert Discoverer" +msgstr "Descobridor do Deserto" + +#: init.lua +msgid "Mine your first cactus." +msgstr "Cortar seu primeiro cacto." + +#: init.lua +msgid "Far Lands" +msgstr "Terras Distantes" + +#: init.lua +msgid "Mine your first dry shrub." +msgstr "Minerar seu primeiro arbusto seco." + +#: init.lua +msgid "Glacier Discoverer" +msgstr "Descobridor Glacial" + +#: init.lua +msgid "Mine your first ice." +msgstr "Quebrar seu primeiro bloco de gelo." + +#: init.lua +msgid "Very Simple Snow Man" +msgstr "Homem de Neve Muito Simples" + +#: init.lua +msgid "Place two snow blocks." +msgstr "Colocar 2 blocos de neve." + +#: init.lua +msgid "First Gold Find" +msgstr "Achei Ouro" + +#: init.lua +msgid "Mine your first gold ore." +msgstr "Minerar sua primeira de ouro." + +#: init.lua +msgid "Gold Rush" +msgstr "Corriga do Ouro" + +#: init.lua +msgid "Mine 45 gold ores." +msgstr "Minerar 45 de ouro." + +#: init.lua +msgid "Wow, I am Diamonds!" +msgstr "Uau, Diamante!" + +#: init.lua +msgid "Mine your first diamond ore." +msgstr "Minerar seu primeiro diamante." + +#: init.lua +msgid "Girl's Best Friend" +msgstr "Melhor Amigo da Menina" + +#: init.lua +msgid "Mine 18 diamond ores." +msgstr "Minere 18 diamantes." + +#: init.lua +msgid "Hardest Block on Earth" +msgstr "O Bloco mais Duro da Terra" + +#: init.lua +msgid "Craft a diamond block." +msgstr "Montar um bloco de diamante." + +#: init.lua +msgid "In the Dungeon" +msgstr "Na Masmorra" + +#: init.lua +msgid "Mine a mossy cobblestone." +msgstr "Minerar um pedregulho com musgo." + +#: init.lua +msgid "Smelter" +msgstr "Fundidor" + +#: init.lua +msgid "Craft 10 furnaces." +msgstr "Montar 10 fornos." + +#: init.lua +msgid "Treasurer" +msgstr "Tesoureiro" + +#: init.lua +msgid "Craft 15 chests." +msgstr "Montar 10 baús." + +#: init.lua +msgid "Bankier" +msgstr "Banqueiro" + +#: init.lua +msgid "Craft 30 locked chests." +msgstr "Montar 30 baús trancados." + +#: init.lua +msgid "Bricker" +msgstr "Tijoleiro" + +#: init.lua +msgid "Craft 200 brick blocks." +msgstr "Fazer 200 blocos de tijolo." + +#: init.lua +msgid "House of Obsidian" +msgstr "Casa de Obsidiana" + +#: init.lua +msgid "Craft 100 obsidian bricks." +msgstr "Montar 100 tijolos de obsidiana." + +#: init.lua +msgid "Build a Cave" +msgstr "Montar uma Caverna" + +#: init.lua +msgid "Place 100 stone." +msgstr "Colocar 100 pedras." + +#: init.lua +msgid "Long Ladder" +msgstr "Longa Escadaria" + +#: init.lua +msgid "Place 400 wooden ladders." +msgstr "Colocar 400 escadas de madeira." + +#: init.lua +msgid "Industrial Age" +msgstr "Era Industrial" + +#: init.lua +msgid "Place 40 steel ladders." +msgstr "Colocar 40 escadas de ferro." + +#: init.lua +msgid "Yummy!" +msgstr "Humm!" + +#: init.lua +msgid "Eat 80 apples." +msgstr "Comer 80 maçãs." + +#: init.lua +msgid "Glasser" +msgstr "Vidraceiro" + +#: init.lua +msgid "Craft 14 vessels shelves." +msgstr "Montar 14 estantes de frascos." + +#: init.lua +msgid "Farming Skills Acquired" +msgstr "Conhecimento de Cultivo Adquirido" + +#: init.lua +msgid "Harvest a fully grown wheat plant." +msgstr "Colher um trigo totalmente crescido." + +#: init.lua +msgid "Field Worker" +msgstr "Trabalhador do Campo" + +#: init.lua +msgid "Harvest 25 fully grown wheat plants." +msgstr "Colher 25 plantas trigos totalmente crescidos." + +#: init.lua +msgid "Aspiring Farmer" +msgstr "Fazendeiro Aspirante" + +#: init.lua +msgid "Harvest 125 fully grown wheat plants." +msgstr "Colher 125 plantas trigos totalmente crescidos." + +#: init.lua +msgid "Wheat Magnate" +msgstr "Magnata do Trigo" + +#: init.lua +msgid "Harvest 625 fully grown wheat plants." +msgstr "Colher 625 plantas trigos totalmente crescidos." + +#: init.lua +msgid "Baker" +msgstr "Padeiro" + +#: init.lua +msgid "Eat 10 loaves of bread." +msgstr "Comer 10 pães." + +#: init.lua +msgid "Wool Over Your Eyes" +msgstr "Lã Sobre Meus Olhos" + +#: init.lua +msgid "Craft 250 white wool." +msgstr "Tecer 250 lãs branca." + +#: init.lua +msgid "Hotelier" +msgstr "Hoteleiro" + +#: init.lua +msgid "Craft 15 fancy beds." +msgstr "Montar 15 camas chiques." + +#: init.lua +msgid "Filthy Rich" +msgstr "Muito Rico" + +#: init.lua +msgid "Craft 24 gold block stairs." +msgstr "Montar 24 escadas de bloco de ouro." + +#: init.lua +msgid "Roses Are Red" +msgstr "Rosas São Vermelhas" + +#: init.lua +msgid "Craft 400 red dyes." +msgstr "Fazer 400 tintas vermelhas." + +#: init.lua +msgid "Dandelions are Yellow" +msgstr "Dentes-de-Leões são Amarelos" + +#: init.lua +msgid "Craft 400 yellow dyes." +msgstr "Fazer 400 tintas amarelas." + +#: init.lua +msgid "Geraniums are Blue" +msgstr "Gerânios são Azuis" + +#: init.lua +msgid "Craft 400 blue dyes." +msgstr "Fazer 400 tintas azuis." + +#: init.lua +msgid "White Color Stock" +msgstr "Estoque de Cor Branca" + +#: init.lua +msgid "Craft 100 white dyes." +msgstr "Fazer 100 tintas brancas." + +#: init.lua +msgid "Tasty Mushrooms" +msgstr "Cogumelos Deliciosos" + +#: init.lua +msgid "Eat 3 brown mushrooms." +msgstr "Comer 3 cogumelos marrons." + +#: init.lua +msgid "Mushroom Lover" +msgstr "Amante de Cogumelo" + +#: init.lua +msgid "Eat 33 brown mushrooms." +msgstr "Comer 33 cogumelos marrons." + +#: init.lua +msgid "Underground Mushroom Farmer" +msgstr "Fazendeiro Subterrâneo de Cogumelos" + +#: init.lua +msgid "Eat 333 brown mushrooms." +msgstr "Comer 333 cogumelos marrons." + +#: init.lua +msgid "Builder" +msgstr "Construtor" + +#: init.lua +msgid "Constructor" +msgstr "Empreiteiro" + +#: init.lua +msgid "Architect" +msgstr "Arquiteto" + +#: init.lua +msgid "Master Architect" +msgstr "Arquiteto Mestre" + +#: chat_commands.lua +msgid "[c|clear|disable|enable]" +msgstr "[c|clear|disable|enable]" + +#: chat_commands.lua +msgid "Show, clear, disable or enable your achievements" +msgstr "Exibir, limpar, desabilitar ou habilitar suas conquistas" + +#: chat_commands.lua +msgid "All your awards and statistics have been cleared. You can now start again." +msgstr "Todas as suas conquistas e estatísticas foram limpas. Agora podes iniciar novamente." + +#: chat_commands.lua +msgid "You have disabled your achievements." +msgstr "Suas conquistas foram desabilitadas." + +#: chat_commands.lua +msgid "You have enabled your achievements." +msgstr "Suas conquistas foram habilitadas." + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Show details of an achievement" +msgstr "Mostra detalhes de uma conquista" + +#: chat_commands.lua +msgid "Achievement not found." +msgstr "Conquista não encontrada." + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Get the achievements statistics for the given player or yourself" +msgstr "Ver as estatísticas de conquistas de um jogador ou suas próprias" diff --git a/mods/awards/locale/template.pot b/mods/awards/locale/template.pot new file mode 100644 index 0000000..970ae7c --- /dev/null +++ b/mods/awards/locale/template.pot @@ -0,0 +1,819 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 05:50-0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#: api.lua +msgid "Secret Achievement Unlocked:" +msgstr "" + +#: api.lua +msgid "Achievement Unlocked:" +msgstr "" + +#: api.lua +#, lua-format +msgid "Secret Achievement Unlocked: %s" +msgstr "" + +#: api.lua +#, lua-format +msgid "Achievement Unlocked: %s" +msgstr "" + +#: api.lua +msgid "Secret Achievement Unlocked!" +msgstr "" + +#: api.lua +msgid "Achievement Unlocked!" +msgstr "" + +#: api.lua +msgid "Error: No awards available." +msgstr "" + +#: api.lua +msgid "OK" +msgstr "" + +#: api.lua +msgid "(Secret Award)" +msgstr "" + +#: api.lua +msgid "Unlock this award to find out what it is." +msgstr "" + +#: api.lua +#, lua-format +msgid "%s (got)" +msgstr "" + +#: api.lua +msgid "You've disabled awards. Type /awards enable to reenable." +msgstr "" + +#: api.lua +msgid "You have not unlocked any awards." +msgstr "" + +#: api.lua +#, lua-format +msgid "%s’s awards:" +msgstr "" + +#: api.lua chat_commands.lua +#, lua-format +msgid "%s: %s" +msgstr "" + +#: sfinv.lua unified_inventory.lua +msgid "Awards" +msgstr "" + +#: triggers.lua +msgid "@1/@2 dug" +msgstr "" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Mine: @2" +msgid_plural "Mine: @1×@2" +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "Mine @1 block." +msgid_plural "Mine @1 blocks." +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "@1/@2 placed" +msgstr "" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Place: @2" +msgid_plural "Place: @1×@2" +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "Place a block." +msgid_plural "Place @1 blocks." +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "@1/@2 eaten" +msgstr "" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Eat: @2" +msgid_plural "Eat: @1×@2" +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "Eat an item." +msgid_plural "Eat @1 items." +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "@1/@2 deaths" +msgstr "" + +#: triggers.lua +msgid "Die." +msgid_plural "Die @1 times." +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "@1/@2 chat messages" +msgstr "" + +#: triggers.lua +msgid "Write something in chat." +msgid_plural "Write @1 chat messages." +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "@1/@2 game joins" +msgstr "" + +#: triggers.lua +msgid "Join the game." +msgid_plural "Join the game @1 times." +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "@1/@2 crafted" +msgstr "" + +#. Translators: @1 is count, @2 is description. +#: triggers.lua +msgid "Craft: @2" +msgid_plural "Craft: @1×@2" +msgstr[0] "" +msgstr[1] "" + +#: triggers.lua +msgid "Craft an item." +msgid_plural "Craft @1 items." +msgstr[0] "" +msgstr[1] "" + +#: init.lua +msgid "Saint-Maclou" +msgstr "" + +#: init.lua +msgid "Place 20 coal checkers." +msgstr "" + +#: init.lua +msgid "Castorama" +msgstr "" + +#: init.lua +msgid "Place 20 iron checkers." +msgstr "" + +#: init.lua +msgid "Sam the Trapper" +msgstr "" + +#: init.lua +msgid "Place 2 trap stones." +msgstr "" + +#: init.lua +msgid "Backpacker" +msgstr "" + +#: init.lua +msgid "Craft 4 large bags." +msgstr "" + +#: init.lua +msgid "Pyromaniac" +msgstr "" + +#: init.lua +msgid "Craft 8 times flint and steel." +msgstr "" + +#: init.lua +msgid "Firefighter" +msgstr "" + +#: init.lua +msgid "Put out 1000 fires." +msgstr "" + +#: init.lua +msgid "Light It Up" +msgstr "" + +#: init.lua +msgid "Place 100 torches." +msgstr "" + +#: init.lua +msgid "Well Lit" +msgstr "" + +#: init.lua +msgid "Place 1,000 torches." +msgstr "" + +#: init.lua +msgid "Really Well Lit" +msgstr "" + +#: init.lua +msgid "Craft 10 mese lamps." +msgstr "" + +#: init.lua +msgid "Outpost" +msgstr "" + +#: init.lua +msgid "Craft 200 stone bricks." +msgstr "" + +#: init.lua +msgid "Watchtower" +msgstr "" + +#: init.lua +msgid "Craft 800 stone bricks." +msgstr "" + +#: init.lua +msgid "Fortress" +msgstr "" + +#: init.lua +msgid "Craft 3,200 stone bricks." +msgstr "" + +#: init.lua +msgid "Desert Dweller" +msgstr "" + +#: init.lua +msgid "Craft 400 desert stone bricks." +msgstr "" + +#: init.lua +msgid "Pharaoh" +msgstr "" + +#: init.lua +msgid "Craft 100 sandstone bricks." +msgstr "" + +#: init.lua +msgid "Little Library" +msgstr "" + +#: init.lua +msgid "Craft 7 bookshelves." +msgstr "" + +#: init.lua +msgid "Lava and Water" +msgstr "" + +#: init.lua +msgid "Mine your first obsidian." +msgstr "" + +#: init.lua +msgid "Obsessed with Obsidian" +msgstr "" + +#: init.lua +msgid "Mine 50 obsidian." +msgstr "" + +#: init.lua +msgid "Lava Miner" +msgstr "" + +#: init.lua +msgid "Mine any block while being very close to lava." +msgstr "" + +#: init.lua +msgid "On The Way" +msgstr "" + +#: init.lua +msgid "Place 100 rails." +msgstr "" + +#: init.lua +msgid "First Day in the Woods" +msgstr "" + +#: init.lua +msgid "Dig 6 tree blocks." +msgstr "" + +#: init.lua +msgid "Lumberjack" +msgstr "" + +#: init.lua +msgid "Dig 36 tree blocks." +msgstr "" + +#: init.lua +msgid "Semi-pro Lumberjack" +msgstr "" + +#: init.lua +msgid "Dig 216 tree blocks." +msgstr "" + +#: init.lua +msgid "Professional Lumberjack" +msgstr "" + +#: init.lua +msgid "Dig 1,296 tree blocks." +msgstr "" + +#: init.lua +msgid "Junglebaby" +msgstr "" + +#: init.lua +msgid "Dig 100 jungle tree blocks." +msgstr "" + +#: init.lua +msgid "Jungleman" +msgstr "" + +#: init.lua +msgid "Dig 1,000 jungle tree blocks." +msgstr "" + +#: init.lua +msgid "First Mese Find" +msgstr "" + +#: init.lua +msgid "Mine your first mese ore." +msgstr "" + +#: init.lua +msgid "Mese Mastery" +msgstr "" + +#: init.lua +msgid "Mine a mese block." +msgstr "" + +#: init.lua +msgid "You’re a copper" +msgstr "" + +#: init.lua +msgid "Dig 1,000 copper ores." +msgstr "" + +#: init.lua +msgid "A Cat in a Pop-Tart?!" +msgstr "" + +#: init.lua +msgid "Mine a nyan cat." +msgstr "" + +#: init.lua +msgid "Mini Miner" +msgstr "" + +#: init.lua +msgid "Dig 100 stone blocks." +msgstr "" + +#: init.lua +msgid "Hardened Miner" +msgstr "" + +#: init.lua +msgid "Dig 1,000 stone blocks." +msgstr "" + +#: init.lua +msgid "Master Miner" +msgstr "" + +#: init.lua +msgid "Dig 10,000 stone blocks." +msgstr "" + +#: init.lua +msgid "Marchand De Sable" +msgstr "" + +#: init.lua +msgid "Dig 1,000 sand." +msgstr "" + +#: init.lua +msgid "Crafter of Sticks" +msgstr "" + +#: init.lua +msgid "Craft 100 sticks." +msgstr "" + +#: init.lua +msgid "Jungle Discoverer" +msgstr "" + +#: init.lua +msgid "Mine your first jungle grass." +msgstr "" + +#: init.lua +msgid "Grasslands Discoverer" +msgstr "" + +#: init.lua +msgid "Mine some grass." +msgstr "" + +#: init.lua +msgid "Savannah Discoverer" +msgstr "" + +#: init.lua +msgid "Mine some dry grass." +msgstr "" + +#: init.lua +msgid "Desert Discoverer" +msgstr "" + +#: init.lua +msgid "Mine your first cactus." +msgstr "" + +#: init.lua +msgid "Far Lands" +msgstr "" + +#: init.lua +msgid "Mine your first dry shrub." +msgstr "" + +#: init.lua +msgid "Glacier Discoverer" +msgstr "" + +#: init.lua +msgid "Mine your first ice." +msgstr "" + +#: init.lua +msgid "Very Simple Snow Man" +msgstr "" + +#: init.lua +msgid "Place two snow blocks." +msgstr "" + +#: init.lua +msgid "First Gold Find" +msgstr "" + +#: init.lua +msgid "Mine your first gold ore." +msgstr "" + +#: init.lua +msgid "Gold Rush" +msgstr "" + +#: init.lua +msgid "Mine 45 gold ores." +msgstr "" + +#: init.lua +msgid "Wow, I am Diamonds!" +msgstr "" + +#: init.lua +msgid "Mine your first diamond ore." +msgstr "" + +#: init.lua +msgid "Girl's Best Friend" +msgstr "" + +#: init.lua +msgid "Mine 18 diamond ores." +msgstr "" + +#: init.lua +msgid "Hardest Block on Earth" +msgstr "" + +#: init.lua +msgid "Craft a diamond block." +msgstr "" + +#: init.lua +msgid "In the Dungeon" +msgstr "" + +#: init.lua +msgid "Mine a mossy cobblestone." +msgstr "" + +#: init.lua +msgid "Smelter" +msgstr "" + +#: init.lua +msgid "Craft 10 furnaces." +msgstr "" + +#: init.lua +msgid "Treasurer" +msgstr "" + +#: init.lua +msgid "Craft 15 chests." +msgstr "" + +#: init.lua +msgid "Bankier" +msgstr "" + +#: init.lua +msgid "Craft 30 locked chests." +msgstr "" + +#: init.lua +msgid "Bricker" +msgstr "" + +#: init.lua +msgid "Craft 200 brick blocks." +msgstr "" + +#: init.lua +msgid "House of Obsidian" +msgstr "" + +#: init.lua +msgid "Craft 100 obsidian bricks." +msgstr "" + +#: init.lua +msgid "Build a Cave" +msgstr "" + +#: init.lua +msgid "Place 100 stone." +msgstr "" + +#: init.lua +msgid "Long Ladder" +msgstr "" + +#: init.lua +msgid "Place 400 wooden ladders." +msgstr "" + +#: init.lua +msgid "Industrial Age" +msgstr "" + +#: init.lua +msgid "Place 40 steel ladders." +msgstr "" + +#: init.lua +msgid "Yummy!" +msgstr "" + +#: init.lua +msgid "Eat 80 apples." +msgstr "" + +#: init.lua +msgid "Glasser" +msgstr "" + +#: init.lua +msgid "Craft 14 vessels shelves." +msgstr "" + +#: init.lua +msgid "Farming Skills Acquired" +msgstr "" + +#: init.lua +msgid "Harvest a fully grown wheat plant." +msgstr "" + +#: init.lua +msgid "Field Worker" +msgstr "" + +#: init.lua +msgid "Harvest 25 fully grown wheat plants." +msgstr "" + +#: init.lua +msgid "Aspiring Farmer" +msgstr "" + +#: init.lua +msgid "Harvest 125 fully grown wheat plants." +msgstr "" + +#: init.lua +msgid "Wheat Magnate" +msgstr "" + +#: init.lua +msgid "Harvest 625 fully grown wheat plants." +msgstr "" + +#: init.lua +msgid "Baker" +msgstr "" + +#: init.lua +msgid "Eat 10 loaves of bread." +msgstr "" + +#: init.lua +msgid "Wool Over Your Eyes" +msgstr "" + +#: init.lua +msgid "Craft 250 white wool." +msgstr "" + +#: init.lua +msgid "Hotelier" +msgstr "" + +#: init.lua +msgid "Craft 15 fancy beds." +msgstr "" + +#: init.lua +msgid "Filthy Rich" +msgstr "" + +#: init.lua +msgid "Craft 24 gold block stairs." +msgstr "" + +#: init.lua +msgid "Roses Are Red" +msgstr "" + +#: init.lua +msgid "Craft 400 red dyes." +msgstr "" + +#: init.lua +msgid "Dandelions are Yellow" +msgstr "" + +#: init.lua +msgid "Craft 400 yellow dyes." +msgstr "" + +#: init.lua +msgid "Geraniums are Blue" +msgstr "" + +#: init.lua +msgid "Craft 400 blue dyes." +msgstr "" + +#: init.lua +msgid "White Color Stock" +msgstr "" + +#: init.lua +msgid "Craft 100 white dyes." +msgstr "" + +#: init.lua +msgid "Tasty Mushrooms" +msgstr "" + +#: init.lua +msgid "Eat 3 brown mushrooms." +msgstr "" + +#: init.lua +msgid "Mushroom Lover" +msgstr "" + +#: init.lua +msgid "Eat 33 brown mushrooms." +msgstr "" + +#: init.lua +msgid "Underground Mushroom Farmer" +msgstr "" + +#: init.lua +msgid "Eat 333 brown mushrooms." +msgstr "" + +#: init.lua +msgid "Builder" +msgstr "" + +#: init.lua +msgid "Constructor" +msgstr "" + +#: init.lua +msgid "Architect" +msgstr "" + +#: init.lua +msgid "Master Architect" +msgstr "" + +#: chat_commands.lua +msgid "[c|clear|disable|enable]" +msgstr "" + +#: chat_commands.lua +msgid "Show, clear, disable or enable your achievements" +msgstr "" + +#: chat_commands.lua +msgid "" +"All your awards and statistics have been cleared. You can now start again." +msgstr "" + +#: chat_commands.lua +msgid "You have disabled your achievements." +msgstr "" + +#: chat_commands.lua +msgid "You have enabled your achievements." +msgstr "" + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Show details of an achievement" +msgstr "" + +#: chat_commands.lua +msgid "Achievement not found." +msgstr "" + +#: chat_commands.lua +msgid "" +msgstr "" + +#: chat_commands.lua +msgid "Get the achievements statistics for the given player or yourself" +msgstr "" diff --git a/mods/awards/mod.conf b/mods/awards/mod.conf new file mode 100644 index 0000000..e3e83d6 --- /dev/null +++ b/mods/awards/mod.conf @@ -0,0 +1,8 @@ +name = awards +title = Awards +author = rubenwardy +description = Adds awards to Minetest, and an API to register new ones. +optional_depends = intllib,sfinv,unified_inventory,default,stairs,farming,dye,beds,wool,vessels,moreblocks,fire,flowers,nyancat +license = MIT +forum = https://forum.minetest.net/viewtopic.php?t=4870 +version = 3.0.0 diff --git a/mods/awards/screenshot.png b/mods/awards/screenshot.png new file mode 100644 index 0000000..ab9e19e Binary files /dev/null and b/mods/awards/screenshot.png differ diff --git a/mods/awards/sounds/awards_got_generic.ogg b/mods/awards/sounds/awards_got_generic.ogg new file mode 100644 index 0000000..3ae982b Binary files /dev/null and b/mods/awards/sounds/awards_got_generic.ogg differ diff --git a/mods/awards/src/api_awards.lua b/mods/awards/src/api_awards.lua new file mode 100644 index 0000000..5385d1b --- /dev/null +++ b/mods/awards/src/api_awards.lua @@ -0,0 +1,179 @@ +-- Copyright (c) 2013-18 rubenwardy. MIT. + +local S = awards.gettext + +function awards.register_award(name, def) + def.name = name + + -- Add Triggers + if def.trigger and def.trigger.type then + local tdef = awards.registered_triggers[def.trigger.type] + assert(tdef, "Trigger not found: " .. def.trigger.type) + tdef:on_register(def) + end + + function def:can_unlock(data) + if not self.requires then + return true + end + + for i=1, #self.requires do + if not data.unlocked[self.requires[i]] then + return false + end + end + return true + end + + -- Add Award + awards.registered_awards[name] = def + + local tdef = awards.registered_awards[name] + if def.description == nil and tdef.getDefaultDescription then + def.description = tdef:getDefaultDescription() + end +end + + +-- This function is called whenever a target condition is met. +-- It checks if a player already has that award, and if they do not, +-- it gives it to them +---------------------------------------------- +--awards.unlock(name, award) +-- name - the name of the player +-- award - the name of the award to give +function awards.unlock(name, award) + -- Access Player Data + local data = awards.player(name) + local awdef = awards.registered_awards[award] + assert(awdef, "Unable to unlock an award which doesn't exist!") + + if data.disabled or + (data.unlocked[award] and data.unlocked[award] == award) then + return + end + + if not awdef:can_unlock(data) then + minetest.log("warning", "can_unlock returned false in unlock of " .. + award .. " for " .. name) + return + end + + -- Unlock Award + minetest.log("action", name.." has unlocked award "..name) + data.unlocked[award] = award + awards.save() + + -- Give Prizes + if awdef and awdef.prizes then + for i = 1, #awdef.prizes do + local itemstack = ItemStack(awdef.prizes[i]) + if not itemstack:is_empty() then + local receiverref = minetest.get_player_by_name(name) + if receiverref then + receiverref:get_inventory():add_item("main", itemstack) + end + end + end + end + + -- Run callbacks + if awdef.on_unlock and awdef.on_unlock(name, awdef) then + return + end + for _, callback in pairs(awards.on_unlock) do + if callback(name, awdef) then + return + end + end + + -- Get Notification Settings + local title = awdef.title or award + local desc = awdef.description or "" + local background = awdef.background or "awards_bg_default.png" + local icon = awdef.icon or "awards_unknown.png" + local sound = awdef.sound + if sound == nil then + -- Explicit check for nil because sound could be `false` to disable it + sound = {name="awards_got_generic", gain=0.25} + end + + -- Do Notification + if sound then + -- Enforce sound delay to prevent sound spamming + local lastsound = data.lastsound + if lastsound == nil or os.difftime(os.time(), lastsound) >= 1 then + minetest.sound_play(sound, {to_player=name}) + data.lastsound = os.time() + end + end + + if awards.show_mode == "chat" then + local chat_announce + if awdef.secret then + chat_announce = S("Secret Award Unlocked: %s") + else + chat_announce = S("Award Unlocked: %s") + end + -- use the chat console to send it + minetest.chat_send_player(name, string.format(chat_announce, title)) + if desc~="" then + minetest.chat_send_player(name, desc) + end + else + local player = minetest.get_player_by_name(name) + local one = player:hud_add({ + hud_elem_type = "image", + name = "award_bg", + scale = {x = 2, y = 1}, + text = background, + position = {x = 0.5, y = 0.05}, + offset = {x = 0, y = 138}, + alignment = {x = 0, y = -1} + }) + local hud_announce + if awdef.secret then + hud_announce = S("Secret Award Unlocked!") + else + hud_announce = S("Award Unlocked!") + end + local two = player:hud_add({ + hud_elem_type = "text", + name = "award_au", + number = 0xFFFFFF, + scale = {x = 100, y = 20}, + text = hud_announce, + position = {x = 0.5, y = 0.05}, + offset = {x = 0, y = 45}, + alignment = {x = 0, y = -1} + }) + local three = player:hud_add({ + hud_elem_type = "text", + name = "award_title", + number = 0xFFFFFF, + scale = {x = 100, y = 20}, + text = title, + position = {x = 0.5, y = 0.05}, + offset = {x = 0, y = 100}, + alignment = {x = 0, y = -1} + }) + local four = player:hud_add({ + hud_elem_type = "image", + name = "award_icon", + scale = {x = 2, y = 2}, -- adjusted for 32x32 from x/y = 4 + text = icon, + position = {x = 0.5, y = 0.05}, + offset = {x = -200.5, y = 126}, + alignment = {x = 0, y = -1} + }) + minetest.after(4, function() + local player2 = minetest.get_player_by_name(name) + if player2 then + player2:hud_remove(one) + player2:hud_remove(two) + player2:hud_remove(three) + player2:hud_remove(four) + end + end) + end +end diff --git a/mods/awards/src/api_triggers.lua b/mods/awards/src/api_triggers.lua new file mode 100644 index 0000000..454c79e --- /dev/null +++ b/mods/awards/src/api_triggers.lua @@ -0,0 +1,218 @@ +-- Copyright (c) 2013-18 rubenwardy. MIT. + +local S, NS = awards.gettext, awards.ngettext + +awards.registered_awards = {} +awards.on = {} +awards.on_unlock = {} + +local default_def = {} + +function default_def:run_callbacks(player, data, table_func) + for i = 1, #self.on do + local res = nil + local entry = self.on[i] + if type(entry) == "function" then + res = entry(player, data) + elseif type(entry) == "table" and entry.award then + res = table_func(entry) + end + + if res then + awards.unlock(player:get_player_name(), res) + end + end +end + +function awards.register_trigger(tname, tdef) + assert(type(tdef) == "table", + "Passing a callback to register_trigger is not supported in 3.0") + + tdef.name = tname + for key, value in pairs(default_def) do + tdef[key] = value + end + + if tdef.type == "counted" then + local old_reg = tdef.on_register + + function tdef:on_register(def) + local tmp = { + award = def.name, + target = def.trigger.target, + } + tdef.register(tmp) + + function def.getProgress(_, data) + local done = math.min(data[tname] or 0, tmp.target) + return { + perc = done / tmp.target, + label = S(tdef.progress, done, tmp.target), + } + end + + function def.getDefaultDescription(_) + local n = def.trigger.target + return NS(tdef.auto_description[1], tdef.auto_description[2], n, n) + end + + if old_reg then + return old_reg(tdef, def) + end + end + + function tdef.notify(player) + assert(player and player.is_player and player:is_player()) + local name = player:get_player_name() + local data = awards.player(name) + + -- Increment counter + local currentVal = (data[tname] or 0) + 1 + data[tname] = currentVal + + tdef:run_callbacks(player, data, function(entry) + if entry.target and entry.award and currentVal and + currentVal >= entry.target then + return entry.award + end + end) + end + + awards["notify_" .. tname] = tdef.notify + + elseif tdef.type == "counted_key" then + if tdef.key_is_item then + tdef.watched_groups = {} + end + + -- On award register + local old_reg = tdef.on_register + function tdef:on_register(def) + -- Register trigger + local tmp = { + award = def.name, + key = tdef:get_key(def), + target = def.trigger.target, + } + tdef.register(tmp) + + -- If group, add it to watch list + if tdef.key_is_item and tmp.key and tmp.key:sub(1, 6) == "group:" then + tdef.watched_groups[tmp.key:sub(7, #tmp.key)] = true + end + + -- Called to get progress values and labels + function def.getProgress(_, data) + data[tname] = data[tname] or {} + + local done + if tmp.key then + done = data[tname][tmp.key] or 0 + else + done = data[tname].__total or 0 + end + done = math.min(done, tmp.target) + + return { + perc = done / tmp.target, + label = S(tdef.progress, done, tmp.target), + } + end + + -- Build description if none is specificed by the award + function def.getDefaultDescription(_) + local n = def.trigger.target + if tmp.key then + local nname = tmp.key + return NS(tdef.auto_description[1], + tdef.auto_description[2], n, n, nname) + else + return NS(tdef.auto_description_total[1], + tdef.auto_description_total[2], n, n) + end + end + + -- Call on_register in trigger type definition + if old_reg then + return old_reg(tdef, def) + end + end + + function tdef.notify(player, key, n) + n = n or 1 + + if tdef.key_is_item and key:sub(1, 6) ~= "group:" then + local itemdef = minetest.registered_items[key] + if itemdef then + for groupname, _ in pairs(itemdef.groups or {}) do + if tdef.watched_groups[groupname] then + tdef.notify(player, "group:" .. groupname, n) + end + end + end + end + + assert(player and player.is_player and player:is_player() and key) + local name = player:get_player_name() + local data = awards.player(name) + + -- Increment counter + data[tname] = data[tname] or {} + local currentVal = (data[tname][key] or 0) + n + data[tname][key] = currentVal + if key:sub(1, 6) ~= "group:" then + data[tname].__total = (data[tname].__total or 0) + n + end + + tdef:run_callbacks(player, data, function(entry) + local current + if entry.key == key then + current = currentVal + elseif entry.key == nil then + current = data[tname].__total + else + return + end + + if current >= entry.target then + return entry.award + end + end) + end + + awards["notify_" .. tname] = tdef.notify + + elseif tdef.type and tdef.type ~= "custom" then + error("Unrecognised trigger type " .. tdef.type) + end + + awards.registered_triggers[tname] = tdef + + tdef.on = {} + tdef.register = function(func) + table.insert(tdef.on, func) + end + + -- Backwards compat + awards.on[tname] = tdef.on + awards['register_on_' .. tname] = tdef.register + return tdef +end + +function awards.increment_item_counter(data, field, itemname, count) + itemname = minetest.registered_aliases[itemname] or itemname + data[field][itemname] = (data[field][itemname] or 0) + 1 +end + +function awards.get_item_count(data, field, itemname) + itemname = minetest.registered_aliases[itemname] or itemname + return data[field][itemname] or 0 +end + +function awards.get_total_keyed_count(data, field) + return data[field].__total or 0 +end + +function awards.register_on_unlock(func) + table.insert(awards.on_unlock, func) +end diff --git a/mods/awards/src/awards.lua b/mods/awards/src/awards.lua new file mode 100644 index 0000000..5312ec5 --- /dev/null +++ b/mods/awards/src/awards.lua @@ -0,0 +1,1110 @@ +-- Copyright (c) 2013-18 rubenwardy and Wuzzy. MIT. + +local S = awards.gettext + + +-- Saint-Maclou +if minetest.get_modpath("moreblocks") then + awards.register_award("award_saint_maclou",{ + title = S("Saint-Maclou"), + description = S("Place 20 coal checkers."), + icon = "awards_saint_maclou.png", + trigger = { + type = "place", + node = "moreblocks:coal_checker", + target = 20 + } + }) + + -- Castorama + awards.register_award("award_castorama",{ + title = S("Castorama"), + description = S("Place 20 iron checkers."), + icon = "awards_castorama.png", + trigger = { + type = "place", + node = "moreblocks:iron_checker", + target = 20 + } + }) + + -- Sam the Trapper + awards.register_award("award_sam_the_trapper",{ + title = S("Sam the Trapper"), + description = S("Place 2 trap stones."), + icon = "awards_sam_the_trapper.png", + trigger = { + type = "place", + node = "moreblocks:trap_stone", + target = 2 + } + }) +end + +-- This award can't be part of Unified Inventory, it would make a circular dependency +if minetest.get_modpath("unified_inventory") then + if minetest.get_all_craft_recipes("unified_inventory:bag_large") ~= nil then + awards.register_award("awards_ui_bags", { + title = S("Backpacker"), + description = S("Craft 4 large bags."), + icon = "awards_backpacker.png", + trigger = { + type = "craft", + item = "unified_inventory:bag_large", + target = 4 + } + }) + end +end + +if minetest.get_modpath("fire") then + awards.register_award("awards_pyro", { + title = S("Pyromaniac"), + description = S("Craft 8 times flint and steel."), + icon = "awards_pyromaniac.png", + trigger = { + type = "craft", + item = "fire:flint_and_steel", + target = 8 + } + }) + if minetest.settings:get_bool("disable_fire") ~= true then + awards.register_award("awards_firefighter", { + title = S("Firefighter"), + description = S("Put out 1000 fires."), + icon = "awards_firefighter.png", + trigger = { + type = "dig", + node = "fire:basic_flame", + target = 1000 + } + }) + end + + + -- Burned to death + awards.register_award("award_burn", { + title = S("You're a witch!"), + description = S("Burn to death in a fire."), + secret = true, + }) + awards.register_on_death(function(player,data) + local pos = player:getpos() + if pos and minetest.find_node_near(pos, 2, "fire:basic_flame") ~= nil then + return "award_burn" + end + return nil + end) +end + +-- You Suck! +awards.register_award("award_you_suck", { + title = S("You Suck!"), + description = S("Die 100 times."), + trigger = { + type = "death", + target = 100 + }, + secret = true, +}) + +-- Die hi +awards.register_award("award_deep_down", { + title = S("Death in the Deeps"), + description = S("Die below -10000"), + secret = true, +}) +awards.register_on_death(function(player,data) + local pos = player:getpos() + if pos and pos.y < -10000 then + return "award_deep_down" + end + return nil +end) + +-- Die near diamond ore +awards.register_award("award_no_screen", { + title = S("In space, no one can hear you scream"), + description = S("Die above 10000"), + secret = true, +}) +awards.register_on_death(function(player,data) + local pos = player:getpos() + if pos and pos.y > 10000 then + return "award_no_screen" + end + return nil +end) + +if minetest.get_modpath("default") then + -- Light it up + awards.register_award("award_lightitup",{ + title = S("Light It Up"), + description = S("Place 100 torches."), + icon = "awards_light_it_up.png^awards_level1.png", + difficulty = 0.01, + trigger = { + type = "place", + node = "default:torch", + target = 100 + } + }) + + -- Light ALL the things! + awards.register_award("award_well_lit",{ + title = S("Well Lit"), + icon = "awards_well_lit.png^awards_level2.png", + description = S("Place 1,000 torches."), + difficulty = 0.01, + trigger = { + type = "place", + node = "default:torch", + target = 1000 + } + }) + + awards.register_award("award_meselamp",{ + title = S("Really Well Lit"), + description = S("Craft 10 mese lamps."), + icon = "awards_really_well_lit.png", + difficulty = 0.2, + trigger = { + type = "craft", + item = "default:meselamp", + target = 10 + } + }) + + awards.register_award("awards_stonebrick", { + title = S("Outpost"), + description = S("Craft 200 stone bricks."), + icon = "awards_outpost.png^awards_level1.png", + difficulty = 0.08, + trigger = { + type = "craft", + item = "default:stonebrick", + target = 200 + } + }) + + awards.register_award("awards_stonebrick2", { + title = S("Watchtower"), + description = S("Craft 800 stone bricks."), + icon = "awards_watchtower.png^awards_level2.png", + difficulty = 0.08, + trigger = { + type = "craft", + item = "default:stonebrick", + target = 800 + } + }) + + awards.register_award("awards_stonebrick3", { + title = S("Fortress"), + description = S("Craft 3,200 stone bricks."), + icon = "awards_fortress.png^awards_level3.png", + difficulty = 0.08, + trigger = { + type = "craft", + item = "default:stonebrick", + target = 3200 + } + }) + + awards.register_award("awards_desert_stonebrick", { + title = S("Desert Dweller"), + description = S("Craft 400 desert stone bricks."), + icon = "awards_desert_dweller.png", + difficulty = 0.09, + trigger = { + type = "craft", + item = "default:desert_stonebrick", + target = 400 + } + }) + + awards.register_award("awards_desertstonebrick", { + title = S("Pharaoh"), + description = S("Craft 100 sandstone bricks."), + icon = "awards_pharaoh.png", + difficulty = 0.09, + trigger = { + type = "craft", + item = "default:sandstonebrick", + target = 100 + } + }) + + awards.register_award("awards_bookshelf", { + title = S("Little Library"), + description = S("Craft 7 bookshelves."), + icon = "awards_little_library.png", + difficulty = 0.2, + trigger = { + type = "craft", + item = "default:bookshelf", + target = 7 + } + }) + + awards.register_award("awards_obsidian", { + title = S("Lava and Water"), + description = S("Mine your first obsidian."), + icon = "awards_lava_and_water.png^awards_level1.png", + background = "awards_bg_mining.png", + difficulty = 1.5, + trigger = { + type = "dig", + node = "default:obsidian", + target = 1 + } + }) + + -- Obsessed with Obsidian + awards.register_award("award_obsessed_with_obsidian",{ + title = S("Obsessed with Obsidian"), + description = S("Mine 50 obsidian."), + icon = "awards_obsessed_with_obsidian.png^awards_level2.png", + background = "awards_bg_mining.png", + difficulty = 1.5, + trigger = { + type = "dig", + node = "default:obsidian", + target = 50 + } + }) + + -- Proof that player has found lava + awards.register_award("award_lavaminer",{ + title = S("Lava Miner"), + description = S("Mine any block while being very close to lava."), + icon = "awards_lava_miner.png", + background = "awards_bg_mining.png", + difficulty = 1, + }) + awards.register_on_dig(function(player,data) + local pos = player:get_pos() + if pos and (minetest.find_node_near(pos, 1, "default:lava_source") or + minetest.find_node_near(pos, 1, "default:lava_flowing")) then + return "award_lavaminer" + end + return nil + end) + + -- On the way + awards.register_award("award_on_the_way", { + title = S("On The Way"), + description = S("Place 100 rails."), + icon = "awards_on_the_way.png", + difficulty = 0.1, + trigger = { + type = "place", + node = "default:rail", + target = 100 + } + }) + + awards.register_award("award_lumberjack_firstday", { + title = S("First Day in the Woods"), + description = S("Dig 6 tree blocks."), + icon = "awards_first_day_in_the_woods.png^awards_level1.png", + difficulty = 0.03, + trigger = { + type = "dig", + node = "default:tree", + target = 6 + } + }) + + -- Lumberjack + awards.register_award("award_lumberjack", { + title = S("Lumberjack"), + description = S("Dig 36 tree blocks."), + icon = "awards_lumberjack.png^awards_level2.png", + difficulty = 0.03, + trigger = { + type = "dig", + node = "default:tree", + target = 36 + } + }) + + -- Semi-pro Lumberjack + awards.register_award("award_lumberjack_semipro", { + title = S("Semi-pro Lumberjack"), + description = S("Dig 216 tree blocks."), + icon = "awards_semi_pro_lumberjack.png^awards_level3.png", + difficulty = 0.03, + trigger = { + type = "dig", + node = "default:tree", + target = 216 + } + }) + + -- Professional Lumberjack + awards.register_award("award_lumberjack_professional", { + title = S("Professional Lumberjack"), + description = S("Dig 1,296 tree blocks."), + icon = "awards_professional_lumberjack.png^awards_level4.png", + difficulty = 0.03, + trigger = { + type = "dig", + node = "default:tree", + target = 1296 + } + }) + + -- Junglebaby + awards.register_award("award_junglebaby", { + title = S("Junglebaby"), + description = S("Dig 100 jungle tree blocks."), + icon = "awards_junglebaby.png^awards_level1.png", + difficulty = 0.05, + trigger = { + type = "dig", + node = "default:jungletree", + target = 100 + } + }) + + -- Jungleman + awards.register_award("award_jungleman", { + title = S("Jungleman"), + description = S("Dig 1,000 jungle tree blocks."), + icon = "awards_jungleman.png^awards_level2.png", + difficulty = 0.05, + trigger = { + type = "dig", + node = "default:jungletree", + target = 1000 + } + }) + + -- Found some Mese! + awards.register_award("award_mesefind", { + title = S("First Mese Find"), + description = S("Mine your first mese ore."), + icon = "awards_first_mese_find.png", + background = "awards_bg_mining.png", + difficulty = 1, + trigger = { + type = "dig", + node = "default:stone_with_mese", + target = 1 + } + }) + + -- Mese Block + awards.register_award("award_meseblock", { + secret = true, + title = S("Mese Mastery"), + description = S("Mine a mese block."), + icon = "awards_mese_mastery.png", + background = "awards_bg_mining.png", + difficulty = 1.1, + trigger = { + type = "dig", + node = "default:mese", + target = 1 + } + }) + + -- You're a copper + awards.register_award("award_youre_a_copper", { + title = S("You’re a copper"), + description = S("Dig 1,000 copper ores."), + icon = "awards_youre_a_copper.png", + background = "awards_bg_mining.png", + difficulty = 0.2, + trigger = { + type = "dig", + node = "default:stone_with_copper", + target = 1000 + } + }) + + -- Mini Miner + awards.register_award("award_mine2", { + title = S("Mini Miner"), + description = S("Dig 100 stone blocks."), + icon = "awards_mini_miner.png^awards_level1.png", + background = "awards_bg_mining.png", + difficulty = 0.02, + trigger = { + type = "dig", + node = "default:stone", + target = 100 + } + }) + + -- Hardened Miner + awards.register_award("award_mine3", { + title = S("Hardened Miner"), + description = S("Dig 1,000 stone blocks."), + icon = "awards_hardened_miner.png^awards_level2.png", + background = "awards_bg_mining.png", + difficulty = 0.02, + trigger = { + type = "dig", + node = "default:stone", + target = 1000 + } + }) + + -- Master Miner + awards.register_award("award_mine4", { + title = S("Master Miner"), + description = S("Dig 10,000 stone blocks."), + icon = "awards_master_miner.png^awards_level3.png", + background = "awards_bg_mining.png", + difficulty = 0.02, + trigger = { + type = "dig", + node = "default:stone", + target = 10000 + } + }) + + -- Marchand de sable + awards.register_award("award_marchand_de_sable", { + title = S("Marchand De Sable"), + description = S("Dig 1,000 sand."), + icon = "awards_marchand_de_sable.png", + background = "awards_bg_mining.png", + difficulty = 0.05, + trigger = { + type = "dig", + node = "default:sand", + target = 1000 + } + }) + + awards.register_award("awards_crafter_of_sticks", { + title = S("Crafter of Sticks"), + description = S("Craft 100 sticks."), + icon = "awards_crafter_of_sticks.png", + difficulty = 0.01, + trigger = { + type = "craft", + item = "default:stick", + target = 100 + } + }) + + awards.register_award("awards_junglegrass", { + title = S("Jungle Discoverer"), + description = S("Mine your first jungle grass."), + icon = "awards_jungle_discoverer.png", + difficulty = 0.009, + trigger = { + type = "dig", + node = "default:junglegrass", + target = 1 + } + }) + + awards.register_award("awards_grass", { + title = S("Grasslands Discoverer"), + description = S("Mine some grass."), + icon = "awards_grasslands_discoverer.png", + difficulty = 0.009, + trigger = { + type = "dig", + node = "default:grass_1", + target = 1 + } + }) + + awards.register_award("awards_dry_grass", { + title = S("Savannah Discoverer"), + description = S("Mine some dry grass."), + icon = "awards_savannah_discoverer.png", + difficulty = 0.009, + trigger = { + type = "dig", + node = "default:dry_grass_3", + target = 1 + } + }) + + awards.register_award("awards_cactus", { + title = S("Desert Discoverer"), + description = S("Mine your first cactus."), + icon = "awards_desert_discoverer.png", + difficulty = 0.03, + trigger = { + type = "dig", + node = "default:cactus", + target = 1 + } + }) + + awards.register_award("awards_dry_shrub", { + title = S("Far Lands"), + description = S("Mine your first dry shrub."), + icon = "awards_far_lands.png", + difficulty = 0.009, + trigger = { + type = "dig", + node = "default:dry_shrub", + target = 1 + } + }) + + awards.register_award("awards_ice", { + title = S("Glacier Discoverer"), + description = S("Mine your first ice."), + icon = "awards_glacier_discoverer.png", + difficulty = 0.02, + trigger = { + type = "dig", + node = "default:ice", + target = 1 + } + }) + + -- Proof that player visited snowy lands + awards.register_award("awards_snowblock", { + title = S("Very Simple Snow Man"), + description = S("Place two snow blocks."), + icon = "awards_very_simple_snow_man.png", + difficulty = 0.02, + trigger = { + type = "place", + node = "default:snowblock", + target = 2 + } + }) + + awards.register_award("awards_gold_ore", { + title = S("First Gold Find"), + description = S("Mine your first gold ore."), + icon = "awards_first_gold_find.png^awards_level1.png", + background = "awards_bg_mining.png", + difficulty = 0.9, + trigger = { + type = "dig", + node = "default:stone_with_gold", + target = 1 + } + }) + + awards.register_award("awards_gold_rush", { + title = S("Gold Rush"), + description = S("Mine 45 gold ores."), + icon = "awards_gold_rush.png^awards_level2.png", + background = "awards_bg_mining.png", + difficulty = 0.9, + trigger = { + type = "dig", + node = "default:stone_with_gold", + target = 45 + } + }) + + awards.register_award("awards_diamond_ore", { + title = S("Wow, I am Diamonds!"), + description = S("Mine your first diamond ore."), + icon = "awards_wow_i_am_diamonds.png^awards_level1.png", + difficulty = 1, + trigger = { + type = "dig", + node = "default:stone_with_diamond", + target = 1 + } + }) + + awards.register_award("awards_diamond_rush", { + title = S("Girl's Best Friend"), + description = S("Mine 18 diamond ores."), + icon = "awards_girls_best_friend.png^awards_level2.png", + background = "awards_bg_mining.png", + difficulty = 1, + trigger = { + type = "dig", + node = "default:stone_with_diamond", + target = 18 + } + }) + + awards.register_award("awards_diamondblock", { + title = S("Hardest Block on Earth"), + description = S("Craft a diamond block."), + icon = "awards_hardest_block_on_earth.png", + difficulty = 1.1, + trigger = { + type = "craft", + item = "default:diamondblock", + target = 1 + } + }) + + awards.register_award("awards_mossycobble", { + title = S("In the Dungeon"), + description = S("Mine a mossy cobblestone."), + icon = "awards_in_the_dungeon.png", + difficulty = 0.9, + trigger = { + type = "dig", + node = "default:mossycobble", + target = 1 + } + }) + + awards.register_award("award_furnace", { + title = S("Smelter"), + description = S("Craft 10 furnaces."), + icon = "awards_smelter.png", + difficulty = 0.08, + trigger = { + type = "craft", + item= "default:furnace", + target = 10 + } + }) + + awards.register_award("award_chest", { + title = S("Treasurer"), + description = S("Craft 15 chests."), + icon = "awards_treasurer.png", + difficulty = 0.08, + trigger = { + type = "craft", + item= "default:chest", + target = 15 + } + }) + + awards.register_award("award_chest2", { + title = S("Banker"), + description = S("Craft 30 locked chests."), + icon = "awards_banker.png", + difficulty = 0.08, + trigger = { + type = "craft", + item= "default:chest_locked", + target = 30 + } + }) + + awards.register_award("award_brick", { + title = S("Bricker"), + description = S("Craft 200 brick blocks."), + icon = "awards_bricker.png", + difficulty = 0.03, + trigger = { + type = "craft", + item= "default:brick", + target = 200 + } + }) + + awards.register_award("award_obsidianbrick", { + title = S("House of Obsidian"), + description = S("Craft 100 obsidian bricks."), + icon = "awards_house_of_obsidian.png", + difficulty = 0.4, + trigger = { + type = "craft", + item= "default:obsidianbrick", + target = 100 + } + }) + + awards.register_award("award_placestone", { + title = S("Build a Cave"), + description = S("Place 100 stone."), + icon = "awards_build_a_cave.png", + difficulty = 0.1, + trigger = { + type = "place", + node = "default:stone", + target = 100 + } + }) + + awards.register_award("award_woodladder", { + title = S("Long Ladder"), + description = S("Place 400 wooden ladders."), + icon = "awards_long_ladder.png", + difficulty = 0.1, + trigger = { + type = "place", + node = "default:ladder_wood", + target = 400 + } + }) + + awards.register_award("award_steelladder", { + title = S("Industrial Age"), + description = S("Place 40 steel ladders."), + icon = "awards_industrial_age.png", + difficulty = 1, + trigger = { + type = "place", + node = "default:ladder_steel", + target = 40 + } + }) + + awards.register_award("award_apples", { + title = S("Yummy!"), + description = S("Eat 80 apples."), + icon = "awards_yummy.png", + difficulty = 0.1, + trigger = { + type = "eat", + item = "default:apple", + target = 80 + } + }) + + -- Died in flowing lava + awards.register_award("award_in_the_flow", { + title = S("In the Flow"), + description = S("Die in flowing lava."), + secret = true, + }) + awards.register_on_death(function(player,data) + local pos = player:getpos() + if pos and (minetest.find_node_near(pos, 2, "default:lava_flowing") ~= nil or + minetest.find_node_near(pos, 2, "default:lava_source") ~= nil) then + return "award_in_the_flow" + end + return nil + end) + + -- Die near diamond ore + awards.register_award("award_this_is_sad", { + title = S("This is Sad"), + description = S("Die near diamond ore."), + secret = true, + }) + awards.register_on_death(function(player,data) + local pos = player:getpos() + if pos and minetest.find_node_near(pos, 5, "default:stone_with_diamond") ~= nil then + return "award_this_is_sad" + end + return nil + end) +end + +if minetest.get_modpath("bones") then + -- Die near bones + awards.register_award("award_the_stack", { + title = S("Graveyard"), + description = S("Die near bones."), + secret = true, + }) + awards.register_on_death(function(player,data) + local pos = player:getpos() + if pos and minetest.find_node_near(pos, 5, "bones:bones") ~= nil then + return "award_the_stack" + end + return nil + end) +end + +if minetest.get_modpath("vessels") then + awards.register_award("award_vessels_shelf", { + title = S("Glasser"), + icon = "awards_glasser.png", + description = S("Craft 14 vessels shelves."), + trigger = { + type = "craft", + item= "vessels:shelf", + target = 14 + } + }) +end + +if minetest.get_modpath("farming") then + awards.register_award("awards_farmer", { + title = S("Farming Skills Acquired"), + description = S("Harvest a fully grown wheat plant."), + icon = "awards_farming_skills_acquired.png^awards_level1.png", + trigger = { + type = "dig", + node = "farming:wheat_8", + target = 1 + } + }) + awards.register_award("awards_farmer2", { + title = S("Field Worker"), + description = S("Harvest 25 fully grown wheat plants."), + icon = "awards_field_worker.png^awards_level2.png", + trigger = { + type = "dig", + node = "farming:wheat_8", + target = 25 + } + }) + + awards.register_award("awards_farmer3", { + title = S("Aspiring Farmer"), + description = S("Harvest 125 fully grown wheat plants."), + icon = "awards_aspiring_farmer.png^awards_level3.png", + trigger = { + type = "dig", + node = "farming:wheat_8", + target = 125 + } + }) + + awards.register_award("awards_farmer4", { + title = S("Wheat Magnate"), + description = S("Harvest 625 fully grown wheat plants."), + icon = "awards_wheat_magnate.png^awards_level4.png", + trigger = { + type = "dig", + node = "farming:wheat_8", + target = 625 + } + }) + + awards.register_award("award_bread", { + title = S("Baker"), + description = S("Eat 10 loaves of bread."), + icon = "awards_baker.png", + trigger = { + type = "eat", + item = "farming:bread", + target = 10 + } + }) + +end + +if minetest.get_modpath("wool") and minetest.get_modpath("farming") then + awards.register_award("awards_wool", { + title = S("Wool Over Your Eyes"), + description = S("Craft 250 white wool."), + icon = "awards_wool_over_your_eyes.png", + trigger = { + type = "craft", + item = "wool:white", + target = 250 + } + }) +end + +if minetest.get_modpath("beds") then + awards.register_award("award_bed", { + title = S("Hotelier"), + description = S("Place 15 fancy beds."), + icon = "awards_hotelier.png", + trigger = { + type = "place", + item= "beds:fancy_bed_bottom", + target = 15 + } + }) +end + +if minetest.get_modpath("stairs") then + awards.register_award("award_stairs_goldblock", { + title = S("Filthy Rich"), + description = S("Craft 24 gold block stairs."), + icon = "awards_filthy_rich.png", + trigger = { + type = "craft", + item= "stairs:stair_goldblock", + target = 24 + } + }) +end + +if minetest.get_modpath("dye") then + awards.register_award("awards_dye_red", { + title = S("Roses Are Red"), + description = S("Craft 400 red dyes."), + icon = "awards_roses_are_red.png", + trigger = { + type = "craft", + item = "dye:red", + target = 400 + } + }) + + awards.register_award("awards_dye_yellow", { + title = S("Dandelions are Yellow"), + description = S("Craft 400 yellow dyes."), + icon = "awards_dandelions_are_yellow.png", + trigger = { + type = "craft", + item = "dye:yellow", + target = 400 + } + }) + + awards.register_award("awards_dye_blue", { + title = S("Geraniums are Blue"), + description = S("Craft 400 blue dyes."), + icon = "awards_geraniums_are_blue.png", + trigger = { + type = "craft", + item= "dye:blue", + target = 400 + } + }) + + awards.register_award("awards_dye_white", { + title = S("White Color Stock"), + description = S("Craft 100 white dyes."), + icon = "awards_white_color_stock.png", + trigger = { + type = "craft", + item= "dye:white", + target = 100 + } + }) +end + +if minetest.get_modpath("flowers") then + awards.register_award("awards_brown_mushroom1", { + title = S("Tasty Mushrooms"), + description = S("Eat 3 brown mushrooms."), + icon = "awards_tasty_mushrooms.png^awards_level1.png", + trigger = { + type = "eat", + item= "flowers:mushroom_brown", + target = 3, + } + }) + awards.register_award("awards_brown_mushroom2", { + title = S("Mushroom Lover"), + description = S("Eat 33 brown mushrooms."), + icon = "awards_mushroom_lover.png^awards_level2.png", + trigger = { + type = "eat", + item= "flowers:mushroom_brown", + target = 33, + } + }) + awards.register_award("awards_brown_mushroom3", { + title = S("Underground Mushroom Farmer"), + description = S("Eat 333 brown mushrooms."), + icon = "awards_underground_mushroom_farmer.png^awards_level3.png", + trigger = { + type = "eat", + item= "flowers:mushroom_brown", + target = 333, + } + }) +end + +-- This ensures the following code is executed after all items have been registered +minetest.after(0, function() + -- Check whether there is at least one node which can be built by the player + local building_is_possible = false + for _, def in pairs(minetest.registered_nodes) do + if (def.description and def.pointable ~= false and not def.groups.not_in_creative_inventory) then + building_is_possible = true + break + end + end + + -- The following awards require at least one node which can be built + if not building_is_possible then + return + end + + awards.register_award("awards_builder1", { + title = S("Builder"), + icon = "awards_builder.png^awards_level1.png", + trigger = { + type = "place", + target = 1000, + }, + }) + awards.register_award("awards_builder2", { + title = S("Engineer"), + icon = "awards_engineer.png^awards_level2.png", + trigger = { + type = "place", + target = 5000, + }, + }) + awards.register_award("awards_builder3", { + title = S("Architect"), + icon = "awards_architect.png^awards_level3.png", + trigger = { + type = "place", + target = 10000, + }, + }) + awards.register_award("awards_builder4", { + title = S("Master Architect"), + icon = "awards_master_architect.png^awards_level4.png", + trigger = { + type = "place", + target = 25000, + }, + }) +end) + +if minetest.get_modpath("nyancat") then + -- Found a Nyan cat! + awards.register_award("award_nyanfind", { + secret = true, + title = S("A Cat in a Pop-Tart?!"), + description = S("Mine a nyan cat."), + icon = "awards_a_cat_in_a_pop_tart.png", + trigger = { + type = "dig", + node = "nyancat:nyancat", + target = 1 + } + }) +end + +if minetest.get_modpath("pipeworks") then + awards.register_award("award_pipeworks_transporter", { + title = S("Item transporter"), + description = S("Place 10000 tubes."), + difficulty = 0.05, + trigger = { + type = "place", + node = "pipeworks:tube_1", + target = 2000, + } + }) + + awards.register_award("award_pipeworks_automator", { + title = S("Factory"), + description = S("Place 5 autocrafters."), + difficulty = 3, + trigger = { + type = "place", + node = "pipeworks:autocrafter", + target = 5, + } + }) +end + +if minetest.get_modpath("mesecons") then + awards.register_award("awards_mesecons", { + title = S("Electical Engineer"), + description = S("Place 500 mesecon wires."), + difficulty = 0.2, + trigger = { + type = "place", + node = "pipeworks:tube_1", + target = 500, + } + }) +end + +if minetest.get_modpath("basic_materials") then + awards.register_award("awards_oil", { + title = S("Oil Typhoon"), + description = S("Craft 100 times flint and steel."), + + trigger = { + type = "craft", + item = "basic_materials:oil_extract", + target = 500, + } + }) +end diff --git a/mods/awards/src/chat_commands.lua b/mods/awards/src/chat_commands.lua new file mode 100644 index 0000000..9c1580e --- /dev/null +++ b/mods/awards/src/chat_commands.lua @@ -0,0 +1,61 @@ +-- Copyright (c) 2013-18 rubenwardy. MIT. + +local S = awards.gettext + +minetest.register_chatcommand("awards", { + params = S("[c|clear|disable|enable]"), + description = S("Show, clear, disable or enable your awards"), + func = function(name, param) + if param == "clear" then + awards.clear_player(name) + minetest.chat_send_player(name, + S("All your awards and statistics have been cleared. You can now start again.")) + elseif param == "disable" then + awards.disable(name) + minetest.chat_send_player(name, S("You have disabled awards.")) + elseif param == "enable" then + awards.enable(name) + minetest.chat_send_player(name, S("You have enabled awards.")) + elseif param == "c" then + awards.show_to(name, name, nil, true) + else + awards.show_to(name, name, nil, false) + end + + if (param == "disable" or param == "enable") and minetest.global_exists("sfinv") then + local player = minetest.get_player_by_name(name) + if player then + sfinv.set_player_inventory_formspec(player) + end + end + end +}) + +minetest.register_chatcommand("awd", { + params = S(""), + description = S("Show details of an award"), + func = function(name, param) + local def = awards.registered_awards[param] + if def then + minetest.chat_send_player(name, string.format(S("%s: %s"), def.title, def.description)) + else + minetest.chat_send_player(name, S("Award not found.")) + end + end +}) + +minetest.register_chatcommand("awpl", { + privs = { + server = true + }, + params = S(""), + description = S("Get the awards statistics for the given player or yourself"), + func = function(name, param) + if not param or param == "" then + param = name + end + minetest.chat_send_player(name, param) + local player = awards.player(param) + minetest.chat_send_player(name, dump(player)) + end +}) diff --git a/mods/awards/src/data.lua b/mods/awards/src/data.lua new file mode 100644 index 0000000..27ae5e3 --- /dev/null +++ b/mods/awards/src/data.lua @@ -0,0 +1,111 @@ + +local storage = minetest.get_mod_storage() +local __player_data + +-- Table Save Load Functions +function awards.save() + storage:set_string("player_data", minetest.write_json(__player_data)) +end + +local function convert_data() + minetest.log("warning", "Importing awards data from previous version") + + local old_players = __player_data + __player_data = {} + for name, data in pairs(old_players) do + while name.name do + name = name.name + end + data.name = name + print("Converting data for " .. name) + + -- Just rename counted + local counted = { + chats = "chat", + deaths = "death", + joins = "join", + } + for from, to in pairs(counted) do + data[to] = data[from] + data[from] = nil + end + + data.death = { + unknown = data.death, + __total = data.death, + } + + -- Convert item db to new format + local counted_items = { + count = "dig", + place = "place", + craft = "craft", + } + for from, to in pairs(counted_items) do + local ret = {} + + local count = 0 + if data[from] then + for modname, items in pairs(data[from]) do + for itemname, value in pairs(items) do + itemname = modname .. ":" .. itemname + local key = minetest.registered_aliases[itemname] or itemname + ret[key] = value + count = count + value + end + end + end + + ret.__total = count + data[from] = nil + data[to] = ret + end + + __player_data[name] = data + end +end + +function awards.load() + local old_save_path = minetest.get_worldpath().."/awards.txt" + local file = io.open(old_save_path, "r") + if file then + local table = minetest.deserialize(file:read("*all")) + if type(table) == "table" then + __player_data = table + convert_data() + else + __player_data = {} + end + file:close() + os.rename(old_save_path, minetest.get_worldpath().."/awards.bk.txt") + awards.save() + else + __player_data = minetest.parse_json(storage:get_string("player_data")) or {} + end +end + +function awards.player(name) + assert(type(name) == "string") + local data = __player_data[name] or {} + __player_data[name] = data + + data.name = data.name or name + data.unlocked = data.unlocked or {} + return data +end + +function awards.player_or_nil(name) + return __player_data[name] +end + +function awards.enable(name) + awards.player(name).disabled = nil +end + +function awards.disable(name) + awards.player(name).disabled = true +end + +function awards.clear_player(name) + __player_data[name] = {} +end diff --git a/mods/awards/src/gui.lua b/mods/awards/src/gui.lua new file mode 100644 index 0000000..8faca84 --- /dev/null +++ b/mods/awards/src/gui.lua @@ -0,0 +1,285 @@ +-- Copyright (c) 2013-18 rubenwardy. MIT. + +local S = awards.gettext + +local function order_awards(name) + local hash_is_unlocked = {} + local retval = {} + + local data = awards.player(name) + if data and data.unlocked then + for awardname, _ in pairs(data.unlocked) do + local def = awards.registered_awards[awardname] + if def then + hash_is_unlocked[awardname] = true + local score = -100000 + + local difficulty = def.difficulty or 1 + if def.trigger and def.trigger.target then + difficulty = difficulty * def.trigger.target + end + score = score + difficulty + + retval[#retval + 1] = { + name = awardname, + def = def, + unlocked = true, + started = true, + score = score, + } + end + end + end + + for _, def in pairs(awards.registered_awards) do + if not hash_is_unlocked[def.name] and def:can_unlock(data) then + local started = false + local score = def.difficulty or 1 + if def.secret then + score = 1000000 + elseif def.trigger and def.trigger.target and def.getProgress then + local progress = def:getProgress(data).perc + score = score * (1 - progress) * def.trigger.target + if progress < 0.001 then + score = score + 100 + else + started = true + end + else + score = 100 + end + + retval[#retval + 1] = { + name = def.name, + def = def, + unlocked = false, + started = started, + score = score, + } + end + end + + table.sort(retval, function(a, b) + return a.score < b.score + end) + return retval +end + +function awards.get_formspec(name, to, sid) + local formspec = "" + local awards_list = order_awards(name) + local data = awards.player(name) + + if #awards_list == 0 then + formspec = formspec .. "label[3.9,1.5;"..minetest.formspec_escape(S("Error: No achivements available.")).."]" + formspec = formspec .. "button_exit[4.2,2.3;3,1;close;"..minetest.formspec_escape(S("OK")).."]" + return formspec + end + sid = awards_list[sid] and sid or 1 + + -- Sidebar + local sitem = awards_list[sid] + local sdef = sitem.def + if sdef and sdef.secret and not sitem.unlocked then + formspec = formspec .. "label[1,2.75;".. + minetest.formspec_escape(S("(Secret Award)")).."]".. + "image[1,0;3,3;awards_unknown.png]" + if sdef and sdef.description then + formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;".. + minetest.formspec_escape( + S("Unlock this award to find out what it is."))..";]" + end + else + local title = sitem.name + if sdef and sdef.title then + title = sdef.title + end + local status = "%s" + if sitem.unlocked then + status = S("%s (unlocked)") + end + + formspec = formspec .. "textarea[0.5,3.1;4.8,1.45;;" .. + string.format(status, minetest.formspec_escape(title)) .. + ";]" + + if sdef and sdef.icon then + formspec = formspec .. "image[0.45,0;3.5,3.5;" .. sdef.icon .. "]" -- adjusted values from 0.6,0;3,3 + end + local barwidth = 3.95 + local perc = nil + local label = nil + if sdef.getProgress and data then + local res = sdef:getProgress(data) + perc = res.perc + label = res.label + end + if perc then + if perc > 1 then + perc = 1 + end + formspec = formspec .. "background[0,8.24;" .. barwidth ..",0.4;awards_progress_gray.png;false]" + formspec = formspec .. "background[0,8.24;" .. (barwidth * perc) ..",0.4;awards_progress_green.png;false]" + if label then + formspec = formspec .. "label[1.6,8.15;" .. minetest.formspec_escape(label) .. "]" + end + end + if sdef and sdef.description then + formspec = formspec .. "box[-0.05,3.75;3.9,4.2;#000]" + formspec = formspec .. "textarea[0.25,3.75;3.9,4.2;;" .. + minetest.formspec_escape(sdef.description) .. ";]" + end + end + + -- Create list box + formspec = formspec .. "textlist[4,0;3.8,8.6;awards;" + local first = true + for _, award in pairs(awards_list) do + local def = award.def + if def then + if not first then + formspec = formspec .. "," + end + first = false + + if def.secret and not award.unlocked then + formspec = formspec .. "#707070"..minetest.formspec_escape(S("(Secret Award)")) + else + local title = award.name + if def and def.title then + title = def.title + end + -- title = title .. " [" .. award.score .. "]" + if award.unlocked then + formspec = formspec .. minetest.formspec_escape(title) + elseif award.started then + formspec = formspec .. "#c0c0c0".. minetest.formspec_escape(title) + else + formspec = formspec .. "#a0a0a0".. minetest.formspec_escape(title) + end + end + end + end + return formspec .. ";"..sid.."]" +end + + +function awards.show_to(name, to, sid, text) + if name == "" or name == nil then + name = to + end + local data = awards.player(to) + if name == to and data.disabled then + minetest.chat_send_player(name, S("You've disabled awards. Type /awards enable to reenable.")) + return + end + if text then + local awards_list = order_awards(name) + if #awards_list == 0 then + minetest.chat_send_player(to, S("Error: No award available.")) + return + elseif not data or not data.unlocked then + minetest.chat_send_player(to, S("You have not unlocked any awards.")) + return + end + minetest.chat_send_player(to, string.format(S("%s’s awards:"), name)) + + for str, _ in pairs(data.unlocked) do + local def = awards.registered_awards[str] + if def then + if def.title then + if def.description then + minetest.chat_send_player(to, string.format(S("%s: %s"), def.title, def.description)) + else + minetest.chat_send_player(to, def.title) + end + else + minetest.chat_send_player(to, str) + end + end + end + else + local deco = "" + if minetest.global_exists("default") then + deco = default.gui_bg .. default.gui_bg_img + end + -- Show formspec to user + minetest.show_formspec(to,"awards:awards", + "size[8,8.6]" .. deco .. + awards.get_formspec(name, to, sid)) + end +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "awards:awards" then + return false + end + if fields.quit then + return true + end + local name = player:get_player_name() + if fields.awards then + local event = minetest.explode_textlist_event(fields.awards) + if event.type == "CHG" then + awards.show_to(name, name, event.index, false) + end + end + + return true +end) + +if minetest.get_modpath("sfinv") then + sfinv.register_page("awards:awards", { + title = S("Awards"), + on_enter = function(self, player, context) + context.awards_idx = 1 + end, + is_in_nav = function(self, player, context) + local data = awards.player(player:get_player_name()) + return not data.disabled + end, + get = function(self, player, context) + local name = player:get_player_name() + return sfinv.make_formspec(player, context, + awards.get_formspec(name, name, context.awards_idx), + false) + end, + on_player_receive_fields = function(self, player, context, fields) + if fields.awards then + local event = minetest.explode_textlist_event(fields.awards) + if event.type == "CHG" then + context.awards_idx = event.index + sfinv.set_player_inventory_formspec(player, context) + end + end + end + }) + + local function check_and_reshow(name) + local player = minetest.get_player_by_name(name) + if not player then + return + end + + local context = sfinv.get_or_create_context(player) + if context.page ~= "awards:awards" then + return + end + + sfinv.set_player_inventory_formspec(player, context) + end + + awards.register_on_unlock(check_and_reshow) +end + +if minetest.get_modpath("unified_inventory") ~= nil then + unified_inventory.register_button("awards", { + type = "image", + image = "awards_ui_icon.png", + tooltip = S("Awards"), + action = function(player) + local name = player:get_player_name() + awards.show_to(name, name, nil, false) + end, + }) +end diff --git a/mods/awards/src/intllib.lua b/mods/awards/src/intllib.lua new file mode 100644 index 0000000..c7af2c2 --- /dev/null +++ b/mods/awards/src/intllib.lua @@ -0,0 +1,44 @@ +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/awards/src/triggers.lua b/mods/awards/src/triggers.lua new file mode 100644 index 0000000..33f779a --- /dev/null +++ b/mods/awards/src/triggers.lua @@ -0,0 +1,141 @@ +-- AWARDS +-- +-- Copyright (C) 2013-2015 rubenwardy +-- This program 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 program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU Lesser General Public License for more details. +-- You should have received a copy of the GNU Lesser General Public License along +-- with this program; if not, write to the Free Software Foundation, Inc., +-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +-- + + +awards.register_trigger("chat", { + type = "counted", + progress = "@1/@2 chat messages", + auto_description = { "Send a chat message", "Chat @1 times" }, +}) +minetest.register_on_chat_message(function(name, message) + local player = minetest.get_player_by_name(name) + if not player or string.find(message, "/") then + return + end + + awards.notify_chat(player) +end) + + +awards.register_trigger("join", { + type = "counted", + progress = "@1/@2 joins", + auto_description = { "Join once", "Join @1 times" }, +}) +minetest.register_on_joinplayer(awards.notify_join) + + +awards.register_trigger("death", { + type = "counted_key", + progress = "@1/@2 deaths", + auto_description = { "Die once of @2", "Die @1 times of @2" }, + auto_description_total = { "Die @1 times.", "Mine @1 times" }, + get_key = function(self, def) + return def.trigger.reason + end, +}) +minetest.register_on_dieplayer(function(player, reason) + if reason then + reason = reason.type + else + reason = "unknown" + end + awards.notify_death(player, reason) +end) + + +awards.register_trigger("dig", { + type = "counted_key", + progress = "@1/@2 dug", + auto_description = { "Mine: @2", "Mine: @1×@2" }, + auto_description_total = { "Mine @1 block.", "Mine @1 blocks." }, + get_key = function(self, def) + return minetest.registered_aliases[def.trigger.node] or def.trigger.node + end, + key_is_item = true, +}) +minetest.register_on_dignode(function(pos, node, player) + if not player or not pos or not node then + return + end + + local node_name = node.name + node_name = minetest.registered_aliases[node_name] or node_name + awards.notify_dig(player, node_name) +end) + + +awards.register_trigger("place", { + type = "counted_key", + progress = "@1/@2 placed", + auto_description = { "Place: @2", "Place: @1×@2" }, + auto_description_total = { "Place @1 block.", "Place @1 blocks." }, + get_key = function(self, def) + return minetest.registered_aliases[def.trigger.node] or def.trigger.node + end, + key_is_item = true, +}) +minetest.register_on_placenode(function(pos, node, player) + if not player or not pos or not node then + return + end + + local node_name = node.name + node_name = minetest.registered_aliases[node_name] or node_name + awards.notify_place(player, node_name) +end) + + +awards.register_trigger("craft", { + type = "counted_key", + progress = "@1/@2 crafted", + auto_description = { "Craft: @2", "Craft: @1×@2" }, + auto_description_total = { "Craft @1 item", "Craft @1 items." }, + get_key = function(self, def) + return minetest.registered_aliases[def.trigger.item] or def.trigger.item + end, + key_is_item = true, +}) +minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) + if not player or itemstack:is_empty() then + return + end + + local itemname = itemstack:get_name() + itemname = minetest.registered_aliases[itemname] or itemname + awards.notify_craft(player, itemname, itemstack:get_count()) +end) + + +awards.register_trigger("eat", { + type = "counted_key", + progress = "@1/@2 eaten", + auto_description = { "Eat @2", "Eat @1×@2" }, + auto_description_total = { "Eat @1 item", "Eat @1 items." }, + get_key = function(self, def) + return minetest.registered_aliases[def.trigger.item] or def.trigger.item + end, + key_is_item = true, +}) +minetest.register_on_item_eat(function(_, _, itemstack, player, _) + if not player or itemstack:is_empty() then + return + end + + local itemname = itemstack:get_name() + itemname = minetest.registered_aliases[itemname] or itemname + awards.notify_eat(player, itemname, itemstack:get_count()) +end) diff --git a/mods/awards/textures/_Gimp/awards_Pyromaniac.xcf b/mods/awards/textures/_Gimp/awards_Pyromaniac.xcf new file mode 100644 index 0000000..3a2dcf5 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_Pyromaniac.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_a_cat_in_a_pop_tart.xcf b/mods/awards/textures/_Gimp/awards_a_cat_in_a_pop_tart.xcf new file mode 100644 index 0000000..793a479 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_a_cat_in_a_pop_tart.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_architect.xcf b/mods/awards/textures/_Gimp/awards_architect.xcf new file mode 100644 index 0000000..7937372 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_architect.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_aspiring_farmer.xcf b/mods/awards/textures/_Gimp/awards_aspiring_farmer.xcf new file mode 100644 index 0000000..803ac3b Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_aspiring_farmer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_backpacker.xcf b/mods/awards/textures/_Gimp/awards_backpacker.xcf new file mode 100644 index 0000000..45d957b Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_backpacker.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_baker.xcf b/mods/awards/textures/_Gimp/awards_baker.xcf new file mode 100644 index 0000000..6b99dfb Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_baker.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_banker.xcf b/mods/awards/textures/_Gimp/awards_banker.xcf new file mode 100644 index 0000000..f8e2014 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_banker.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_bricker.xcf b/mods/awards/textures/_Gimp/awards_bricker.xcf new file mode 100644 index 0000000..5a24f86 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_bricker.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_build_a_cave.xcf b/mods/awards/textures/_Gimp/awards_build_a_cave.xcf new file mode 100644 index 0000000..d5b9e0a Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_build_a_cave.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_builder.xcf b/mods/awards/textures/_Gimp/awards_builder.xcf new file mode 100644 index 0000000..6b33fd5 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_builder.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_castorama.xcf b/mods/awards/textures/_Gimp/awards_castorama.xcf new file mode 100644 index 0000000..1a114b2 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_castorama.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_crafter_of_sticks.xcf b/mods/awards/textures/_Gimp/awards_crafter_of_sticks.xcf new file mode 100644 index 0000000..70eb2d6 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_crafter_of_sticks.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_dandelions_are_yellow.xcf b/mods/awards/textures/_Gimp/awards_dandelions_are_yellow.xcf new file mode 100644 index 0000000..a161242 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_dandelions_are_yellow.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_desert_discoverer.xcf b/mods/awards/textures/_Gimp/awards_desert_discoverer.xcf new file mode 100644 index 0000000..e5e51e0 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_desert_discoverer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_desert_dweller.xcf b/mods/awards/textures/_Gimp/awards_desert_dweller.xcf new file mode 100644 index 0000000..9a43ffb Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_desert_dweller.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_engineer.xcf b/mods/awards/textures/_Gimp/awards_engineer.xcf new file mode 100644 index 0000000..0e07f24 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_engineer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_far_lands.xcf b/mods/awards/textures/_Gimp/awards_far_lands.xcf new file mode 100644 index 0000000..1f9797a Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_far_lands.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_farming_skills_acquired.xcf b/mods/awards/textures/_Gimp/awards_farming_skills_acquired.xcf new file mode 100644 index 0000000..3fbedd6 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_farming_skills_acquired.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_field_worker.xcf b/mods/awards/textures/_Gimp/awards_field_worker.xcf new file mode 100644 index 0000000..61b3cad Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_field_worker.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_filthy_rich.xcf b/mods/awards/textures/_Gimp/awards_filthy_rich.xcf new file mode 100644 index 0000000..9693359 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_filthy_rich.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_firefighter.xcf b/mods/awards/textures/_Gimp/awards_firefighter.xcf new file mode 100644 index 0000000..2e245f4 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_firefighter.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_first_day_in_the_woods.xcf b/mods/awards/textures/_Gimp/awards_first_day_in_the_woods.xcf new file mode 100644 index 0000000..f2c90ef Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_first_day_in_the_woods.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_first_gold_find.xcf b/mods/awards/textures/_Gimp/awards_first_gold_find.xcf new file mode 100644 index 0000000..39c8c22 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_first_gold_find.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_first_mese_find.xcf b/mods/awards/textures/_Gimp/awards_first_mese_find.xcf new file mode 100644 index 0000000..7ba420a Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_first_mese_find.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_fortress.xcf b/mods/awards/textures/_Gimp/awards_fortress.xcf new file mode 100644 index 0000000..c17a8a4 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_fortress.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_geraniums_are_blue.xcf b/mods/awards/textures/_Gimp/awards_geraniums_are_blue.xcf new file mode 100644 index 0000000..f48c57f Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_geraniums_are_blue.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_girls_best_friend.xcf b/mods/awards/textures/_Gimp/awards_girls_best_friend.xcf new file mode 100644 index 0000000..c727bd4 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_girls_best_friend.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_glacier_discoverer.xcf b/mods/awards/textures/_Gimp/awards_glacier_discoverer.xcf new file mode 100644 index 0000000..2a504aa Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_glacier_discoverer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_glasser.xcf b/mods/awards/textures/_Gimp/awards_glasser.xcf new file mode 100644 index 0000000..97c8575 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_glasser.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_gold_rush.xcf b/mods/awards/textures/_Gimp/awards_gold_rush.xcf new file mode 100644 index 0000000..0fbc8a5 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_gold_rush.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_grasslands_discoverer.xcf b/mods/awards/textures/_Gimp/awards_grasslands_discoverer.xcf new file mode 100644 index 0000000..35fa979 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_grasslands_discoverer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_hardened_miner.xcf b/mods/awards/textures/_Gimp/awards_hardened_miner.xcf new file mode 100644 index 0000000..ffbd68f Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_hardened_miner.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_hardest_block_on_earth.xcf b/mods/awards/textures/_Gimp/awards_hardest_block_on_earth.xcf new file mode 100644 index 0000000..89d1fbf Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_hardest_block_on_earth.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_hotelier.xcf b/mods/awards/textures/_Gimp/awards_hotelier.xcf new file mode 100644 index 0000000..788f4ce Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_hotelier.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_house_of_obsidian.xcf b/mods/awards/textures/_Gimp/awards_house_of_obsidian.xcf new file mode 100644 index 0000000..01e8660 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_house_of_obsidian.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_in_the_dungeon.xcf b/mods/awards/textures/_Gimp/awards_in_the_dungeon.xcf new file mode 100644 index 0000000..88ede74 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_in_the_dungeon.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_industrial_age.xcf b/mods/awards/textures/_Gimp/awards_industrial_age.xcf new file mode 100644 index 0000000..daee558 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_industrial_age.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_jungle_discoverer.xcf b/mods/awards/textures/_Gimp/awards_jungle_discoverer.xcf new file mode 100644 index 0000000..92e74fd Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_jungle_discoverer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_junglebaby.xcf b/mods/awards/textures/_Gimp/awards_junglebaby.xcf new file mode 100644 index 0000000..58e83fd Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_junglebaby.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_jungleman.xcf b/mods/awards/textures/_Gimp/awards_jungleman.xcf new file mode 100644 index 0000000..7b64747 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_jungleman.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_lava_and_water.xcf b/mods/awards/textures/_Gimp/awards_lava_and_water.xcf new file mode 100644 index 0000000..bfa7d14 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_lava_and_water.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_lava_miner.xcf b/mods/awards/textures/_Gimp/awards_lava_miner.xcf new file mode 100644 index 0000000..0c2684c Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_lava_miner.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_level1.xcf b/mods/awards/textures/_Gimp/awards_level1.xcf new file mode 100644 index 0000000..09d53df Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_level1.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_level2.xcf b/mods/awards/textures/_Gimp/awards_level2.xcf new file mode 100644 index 0000000..170ebc4 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_level2.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_level3.xcf b/mods/awards/textures/_Gimp/awards_level3.xcf new file mode 100644 index 0000000..dbf3480 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_level3.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_level4.xcf b/mods/awards/textures/_Gimp/awards_level4.xcf new file mode 100644 index 0000000..ddbba7d Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_level4.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_level5.xcf b/mods/awards/textures/_Gimp/awards_level5.xcf new file mode 100644 index 0000000..bc6a38b Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_level5.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_level6.xcf b/mods/awards/textures/_Gimp/awards_level6.xcf new file mode 100644 index 0000000..99d3e1a Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_level6.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_level7.xcf b/mods/awards/textures/_Gimp/awards_level7.xcf new file mode 100644 index 0000000..269a8d1 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_level7.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_light_it_up.xcf b/mods/awards/textures/_Gimp/awards_light_it_up.xcf new file mode 100644 index 0000000..ceb8693 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_light_it_up.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_little_library.xcf b/mods/awards/textures/_Gimp/awards_little_library.xcf new file mode 100644 index 0000000..7f3a36a Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_little_library.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_long_ladder.xcf b/mods/awards/textures/_Gimp/awards_long_ladder.xcf new file mode 100644 index 0000000..4642d8a Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_long_ladder.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_lumberjack.xcf b/mods/awards/textures/_Gimp/awards_lumberjack.xcf new file mode 100644 index 0000000..884a2e9 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_lumberjack.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_marchand_de_sable.xcf b/mods/awards/textures/_Gimp/awards_marchand_de_sable.xcf new file mode 100644 index 0000000..9f07ad2 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_marchand_de_sable.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_master_architect.xcf b/mods/awards/textures/_Gimp/awards_master_architect.xcf new file mode 100644 index 0000000..147a764 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_master_architect.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_master_miner.xcf b/mods/awards/textures/_Gimp/awards_master_miner.xcf new file mode 100644 index 0000000..7f49780 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_master_miner.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_mese_mastery.xcf b/mods/awards/textures/_Gimp/awards_mese_mastery.xcf new file mode 100644 index 0000000..3e041ac Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_mese_mastery.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_mini_miner.xcf b/mods/awards/textures/_Gimp/awards_mini_miner.xcf new file mode 100644 index 0000000..69bbe8a Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_mini_miner.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_mushroom_lover.xcf b/mods/awards/textures/_Gimp/awards_mushroom_lover.xcf new file mode 100644 index 0000000..7b1b838 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_mushroom_lover.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_obsessed_with_obsidian.xcf b/mods/awards/textures/_Gimp/awards_obsessed_with_obsidian.xcf new file mode 100644 index 0000000..7e25536 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_obsessed_with_obsidian.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_on_the_way.xcf b/mods/awards/textures/_Gimp/awards_on_the_way.xcf new file mode 100644 index 0000000..658c116 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_on_the_way.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_outpost.xcf b/mods/awards/textures/_Gimp/awards_outpost.xcf new file mode 100644 index 0000000..0204ef5 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_outpost.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_pharaoh.xcf b/mods/awards/textures/_Gimp/awards_pharaoh.xcf new file mode 100644 index 0000000..14feb90 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_pharaoh.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_professional_lumberjack.xcf b/mods/awards/textures/_Gimp/awards_professional_lumberjack.xcf new file mode 100644 index 0000000..ee1be0b Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_professional_lumberjack.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_really_well_lit.xcf b/mods/awards/textures/_Gimp/awards_really_well_lit.xcf new file mode 100644 index 0000000..b3747cf Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_really_well_lit.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_roses_are_red.xcf b/mods/awards/textures/_Gimp/awards_roses_are_red.xcf new file mode 100644 index 0000000..eec49b9 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_roses_are_red.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_saint_maclou.xcf b/mods/awards/textures/_Gimp/awards_saint_maclou.xcf new file mode 100644 index 0000000..d998363 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_saint_maclou.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_sam_the_trapper.xcf b/mods/awards/textures/_Gimp/awards_sam_the_trapper.xcf new file mode 100644 index 0000000..ea1f208 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_sam_the_trapper.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_savannah_discoverer.xcf b/mods/awards/textures/_Gimp/awards_savannah_discoverer.xcf new file mode 100644 index 0000000..1f7cd36 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_savannah_discoverer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_semi_pro_lumberjack.xcf b/mods/awards/textures/_Gimp/awards_semi_pro_lumberjack.xcf new file mode 100644 index 0000000..0a0c426 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_semi_pro_lumberjack.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_smelter.xcf b/mods/awards/textures/_Gimp/awards_smelter.xcf new file mode 100644 index 0000000..9bc2c7f Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_smelter.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_tasty_mushrooms.xcf b/mods/awards/textures/_Gimp/awards_tasty_mushrooms.xcf new file mode 100644 index 0000000..ad28538 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_tasty_mushrooms.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_template.xcf b/mods/awards/textures/_Gimp/awards_template.xcf new file mode 100644 index 0000000..371b3f3 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_template.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_treasurer.xcf b/mods/awards/textures/_Gimp/awards_treasurer.xcf new file mode 100644 index 0000000..1f857f8 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_treasurer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_ui_icon.xcf b/mods/awards/textures/_Gimp/awards_ui_icon.xcf new file mode 100644 index 0000000..8ad704b Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_ui_icon.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_underground_mushroom_farmer.xcf b/mods/awards/textures/_Gimp/awards_underground_mushroom_farmer.xcf new file mode 100644 index 0000000..fb53f08 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_underground_mushroom_farmer.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_unknown.xcf b/mods/awards/textures/_Gimp/awards_unknown.xcf new file mode 100644 index 0000000..b71bb16 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_unknown.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_very_simple_snow_man.xcf b/mods/awards/textures/_Gimp/awards_very_simple_snow_man.xcf new file mode 100644 index 0000000..ce7ac1d Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_very_simple_snow_man.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_watchtower.xcf b/mods/awards/textures/_Gimp/awards_watchtower.xcf new file mode 100644 index 0000000..2fbe2e3 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_watchtower.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_well_lit.xcf b/mods/awards/textures/_Gimp/awards_well_lit.xcf new file mode 100644 index 0000000..bc3fbab Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_well_lit.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_wheat_magnate.xcf b/mods/awards/textures/_Gimp/awards_wheat_magnate.xcf new file mode 100644 index 0000000..0fb20ec Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_wheat_magnate.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_white_color_stock.xcf b/mods/awards/textures/_Gimp/awards_white_color_stock.xcf new file mode 100644 index 0000000..010fac1 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_white_color_stock.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_wool_over_your_eyes.xcf b/mods/awards/textures/_Gimp/awards_wool_over_your_eyes.xcf new file mode 100644 index 0000000..19bc54c Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_wool_over_your_eyes.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_wow_i_am_diamonds.xcf b/mods/awards/textures/_Gimp/awards_wow_i_am_diamonds.xcf new file mode 100644 index 0000000..98c2cbe Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_wow_i_am_diamonds.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_youre_a_copper.xcf b/mods/awards/textures/_Gimp/awards_youre_a_copper.xcf new file mode 100644 index 0000000..ba06034 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_youre_a_copper.xcf differ diff --git a/mods/awards/textures/_Gimp/awards_yummy.xcf b/mods/awards/textures/_Gimp/awards_yummy.xcf new file mode 100644 index 0000000..862bbe8 Binary files /dev/null and b/mods/awards/textures/_Gimp/awards_yummy.xcf differ diff --git a/mods/awards/textures/_Read Me.txt b/mods/awards/textures/_Read Me.txt new file mode 100644 index 0000000..c7f5dcf --- /dev/null +++ b/mods/awards/textures/_Read Me.txt @@ -0,0 +1,428 @@ + __________ .___ _____ + \______ \ ____ _____ __| _/ / \ ____ + | _// __ \\__ \ / __ | / \ / \_/ __ \ + | | \ ___/ / __ \_/ /_/ | / Y \ ___/ + |____|_ /\___ >____ /\____ | \____|__ /\___ > + \/ \/ \/ \/ \/ \/ + + and license info + + Below is a listing of the Award icon source and attribution/licence info. + CC BY-SA 3.0 - https://creativecommons.org/licenses/by-sa/3.0/ + CC0 - https://creativecommons.org/share-your-work/public-domain/cc0/ + +A Cat in a Pop Tart?! -- CC0 + Inspiration art RinRinDaishi on Deviant art + https://www.deviantart.com/rinrindaishi/art/Nyancat-Bed-335515771 + see _RinrinDaishi_message.png + Icon drawn by Sirrobzeroone from scratch + +Architect -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Stone Wall (cobble) texture - Neuromancer/Brane Praefect + Rest - Sirrobzeroone + +Aspiring Farmer -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Dirt Texture (default_dirt.png) - Random-Geek/Neuromancer + Fence texture - Paramat/Blockmen + Wheat Texture - PilzAdam/BlockMen/MasterGollum/Gambit + Rest - Sirrobzeroone + +Backpacker -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Binoculars - Paramat + Wool Texture - Cisoun + Rest - Sirrobzeroone + +Baker -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Stone Wall texture - Neuromancer/Brane Praefect + Furnace - Neuromancer + Rest - Sirrobzeroone + +Banker -- CC BY-SA 3.0 + Wood Pine Floor (default_pinewood.png) - Paramat + Chest - BlockMen + Rest - Sirrobzeroone + +Bricker -- CC BY-SA 3.0 + Brick Texture - Calinou + Rest - Sirrobzeroone + +Build a Cave -- CC BY-SA 3.0 + Stone (default_stone.png) - Cisoun + Grass texture (default_grass.png) - Paramat + Rest - Sirrobzeroone + +Builder -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Wool Texture - Cisoun + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Rest - Sirrobzeroone + +Castorama -- CC0 (Public Domain) + All - Sirrobzeroone + +Crafter of Sticks -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Grass Tall (default_grass_*.png) - Gambit + Rest - Sirrobzeroone + +Dandelions are Yellow -- CC0 (Public Domain) + All - Openclipart Library/Sirrobzeroone + +Desert Discoverer -- CC BY-SA 3.0 + Sand (default_desert_sand.png) - VanessaE + Dry Shrub (default_dry_shrub.png) - celeron55 + Sun () - Celeron55 + Rest - Sirrobzeroone + +Desert Dweller -- CC BY-SA 3.0 + Sand (default_desert_sand.png) - VanessaE + Rest - Sirrobzeroone + +Engineer -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Rest - Sirrobzeroone + +Far Lands -- CC BY-SA 3.0 + Water (default_water.png) - Cisoun + Tree Bark (default_tree.png) - Cisoun + Tree Wood (default_wood.png) - BlockMen + Tree Leaves (default_leaves.png) - Cisoun + Sun () - Celeron55 + Rest - Sirrobzeroone + +Farming Skills Acquired -- CC BY-SA 3.0 + Wheat Texture - PilzAdam/BlockMen/MasterGollum/Gambit + Dirt Texture (default_dirt.png) - Random-Geek/Neuromancer + Grass texture (default_grass.png) - Paramat + Sun () - Celeron55 + Rest - Sirrobzeroone + +Field Worker -- CC BY-SA 3.0 + Wheat Texture - PilzAdam/BlockMen/MasterGollum/Gambit + Dirt Texture (default_dirt.png) - Random-Geek/Neuromancer + Rest - Sirrobzeroone + +Filthy Rich -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Rest - Sirrobzeroone + +Firefighter -- CC0 (Public Domain) + All - Sirrobzeroone + +First Day in the Woods -- CC BY-SA 3.0 + Tree Bark (default_tree.png) - Cisoun + Grass texture (default_grass.png) - Paramat + Grass Tall (default_grass_*.png) - Gambit + Axe (default_tool_*.png) - BlockMen + Rest - Sirrobzeroone + +First Gold Find -- CC BY-SA 3.0 + Gold Nugget (default_gold_lump.png) - Gambit + Stone (default_stone.png) - Cisoun + Rest - Sirrobzeroone + +First Mese Find -- CC BY-SA 3.0 + Stone (default_stone.png) - Cisoun + Mese Crystal (default_mese_crystal.png) - VanessaE + Rest - Sirrobzeroone + +Fortress -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Tree Bark (default_tree.png) - Cisoun + Tree Leaves (default_leaves.png) - Cisoun + Rest - Sirrobzeroone + +Geraniums are Blue -- CC BY-SA 3.0 + Geranium (flowers_geranium.png) + Wool Texture - Cisoun + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Tree Wood (default_wood.png) - BlockMen + Rest - Sirrobzeroone + +Girl's Best Friend -- CC BY-SA 3.0 + Diamond (default_diamond.png) - BlockMen + Rest - Sirrobzeroone + +Glacier Discoverer -- CC BY-SA 3.0 + Ice (default_ice.png) - as197 + Snow (default_snow.png) - Gambit + Rest - Sirrobzeroone + +Glasser -- CC BY-SA 3.0 + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Tree Wood (default_wood.png) - BlockMen + Rest - Sirrobzeroone + +Gold Rush -- CC BY-SA 3.0 + Stone Blocks (default_stone_block.png) - Paramat + Tree Bark (default_tree.png) - Cisoun + Stone (default_stone.png) - Cisoun + Gold Nugget (default_gold_lump.png) - Gambit + Torch (default_torch_on_floor.png) - VanessaE + Rail (carts_rail_*) - Hexafraction/Sofar + Cart (carts_cart_side.png) - Gambit + Rest - Sirrobzeroone + +Grasslands Discoverer -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Dirt Texture (default_dirt.png) - Random-Geek/Neuromancer + Sun () - Celeron55 + Bluberry (default_blueberries.png) - Random-Geek + Viola (flowers_viola.png) - RHRhino/Gambit/yyt16384/Paramat + Rest - Sirrobzeroone + +Hardened Miner -- CC BY-SA 3.0 + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Rest - Sirrobzeroone + +Hardest Block on Earth -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Tree Bark (default_tree.png) - Cisoun + Tree Leaves (default_leaves.png) - Cisoun + Diamond Block (default_diamond_block.png) - Gambit + Rest - Sirrobzeroone + +Hotelier -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Tree Wood (default_wood.png) - BlockMen + Tree Bark (default_tree.png) - Cisoun + Wood Pine Floor (default_pinewood.png) - Paramat + Wood Acacia Floor (default_acacia_wood.png) - Paramat + Rest - Sirrobzeroone + +House of Obsidian -- CC BY-SA 3.0 + Wood Acacia Floor (default_acacia_wood.png) - Paramat + Grass texture (default_grass.png) - Paramat + Tree Bark (default_tree.png) - Cisoun + Obsidian (default_obsidian.png) - Jojoa1997 + Rest - Sirrobzeroone + +In the Dungeon -- CC BY-SA 3.0 + Wood Pine Floor (default_pinewood.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Rest - Sirrobzeroone + +Industrial Age -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Wood Pine Floor (default_pinewood.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Sun () - Celeron55 + Rest - Sirrobzeroone + +Jungle Discoverer -- CC BY-SA 3.0 + Jungle Bark (default_jungletree.png) - Cisoun + Jungle Leaves (default_jungleleaves.png) - PilzAdam + Jungle Litter (default_rainforest_litter.png) - npx + Grass texture (default_grass.png) - Paramat + Rest - Sirrobzeroone + +Junglebaby -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Jungle Bark (default_jungletree.png) - Cisoun + Rest - Sirrobzeroone + +Jungleman -- CC BY-SA 3.0 + Jungle Bark (default_jungletree.png) - Cisoun + Jungle Leaves (default_jungleleaves.png) - PilzAdam + Rest - Sirrobzeroone + +Lava and Water -- CC BY-SA 3.0 + Water (default_water.png) - Cisoun + Lava (default_lava.png) - Cisoun + Obsidian (default_obsidian.png) - Jojoa1997 + Rest - Sirrobzeroone + +Lava Miner -- CC BY-SA 3.0 + Lava (default_lava.png) - Cisoun + Stone (default_stone.png) - Cisoun + Rest - Sirrobzeroone + +Light It Up -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Torch (default_torch_on_floor.png) - VanessaE + Rest - Sirrobzeroone + +Little Library -- CC BY-SA 3.0 + BookShelf (default_bookshelf.png) - Celeron55 + Tree Wood (default_wood.png) - BlockMen + Rest - Sirrobzeroone + +Long Ladder -- CC BY-SA 3.0 + Ladder (default_ladder_wood.png) - Celeron55 + Rest - Sirrobzeroone + +Lumberjack -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Tree Bark (default_tree.png) - Cisoun + Rest - Sirrobzeroone + +Marchand De Sable -- CC BY-SA 3.0 + Sand ( default_desert_sand.png) - VanessaE + Sand Block (default_desert_stone.png) - VanessaE + Rest - Sirrobzeroone + +Master Miner -- CC BY-SA 3.0 + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Rest - Sirrobzeroone + +Mese Mastery -- CC BY-SA 3.0 + Stone (default_stone.png) - Cisoun + Mese block (default_mese_block.png) - Paramat + Rest - Sirrobzeroone + +Mini Miner -- CC BY-SA 3.0 + Stone (default_stone.png) - Cisoun + Iron Ore (default_mineral_iron.png) - Celeron55 + Rest - Sirrobzeroone + +Mushroom Lover -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Rest - Sirrobzeroone + +Obsessed with Obsidian -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Tree Bark (default_tree.png) - Cisoun + Tree Leaves (default_leaves.png) - Cisoun + Dirt Texture (default_dirt.png) - Random-Geek/Neuromancer + Obsidian (default_obsidian.png) - Jojoa1997 + Rest - Sirrobzeroone + +On The Way -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Tree Bark (default_tree.png) - Cisoun + Tree Leaves (default_leaves.png) - Cisoun + Rail (carts_rail_*) - Hexafraction/Sofar + Rest - Sirrobzeroone + +Outpost -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Tree Bark (default_tree.png) - Cisoun + Tree Leaves (default_leaves.png) - Cisoun + Rest - Sirrobzeroone + +Pharaoh -- CC BY-SA 3.0 + Sand (default_desert_sand.png) - VanessaE + Rest - Sirrobzeroone + +Professional Lumberjack -- CC BY-SA 3.0 + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Tree Wood (default_wood.png) - BlockMen + Axe (default_tool_*.png) - BlockMen + Rest - Sirrobzeroone + +Pyromaniac -- CC0 (Public Domain) + All - Sirrobzeroone + +Really Well Lit -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Wheat Texture - PilzAdam/BlockMen/MasterGollum/Gambit + Tree Wood (default_wood.png) - BlockMen + Rest - Sirrobzeroone + +Roses Are Red -- CC0 (Public Domain) + All - Sirrobzeroone + +Saint-Maclou -- CC0 (Public Domain) + All - Sirrobzeroone + +Sam the Trapper -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Grass texture (default_grass.png) - Paramat + Rest - Sirrobzeroone + +Savannah Discoverer -- CC BY-SA 3.0 + Dry grass (default_dry_grass.png) - Paramat + Dirt Texture (default_dirt.png) - Random-Geek/Neuromancer + Sun () - Celeron55 + Acacia Leaves (default_acacia_leaves.png) - Paramat + Acacia Bark (default_acacia_tree.png) - Paramat + Rest - Sirrobzeroone + +Semi-pro Lumberjack -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Tree Bark (default_tree.png) - Cisoun + Axe (default_tool_*.png) - BlockMen + Rest - Sirrobzeroone + +Smelter -- CC0 (Public Domain) + All - Openclipart library/Sirrobzeroone + +Tasty Mushrooms -- CC0 (Public Domain) + All - Openclipart library/Sirrobzeroone + +Treasurer -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Wood Pine Floor (default_pinewood.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Rest - Sirrobzeroone + +Underground Mushroom Farmer -- CC BY-SA 3.0 + Dirt Texture (default_dirt.png) - Random-Geek/Neuromancer + Stone (default_stone.png) - Cisoun + Mushroom (flowers_mushroom_brown.png) - RHRhino/Gambit/yyt16384/Paramat + Torch (default_torch_on_floor.png) - VanessaE + Rest - Sirrobzeroone + +Very Simple Snow Man -- CC BY-SA 3.0 + Snow (default_snow.png) - Gambit + Stick (default_stick.png) - BlockMen + Rest - Sirrobzeroone + +Watchtower -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Tree Bark (default_tree.png) - Cisoun + Tree Leaves (default_leaves.png) - Cisoun + Rest - Sirrobzeroone + +Well Lit -- CC BY-SA 3.0 + Grass texture (default_grass.png) - Paramat + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Wood Pine Floor (default_pinewood.png) - Paramat + Rest - Sirrobzeroone + +Wheat Magnate -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Sun () - Celeron55 + Wheat Texture - PilzAdam/BlockMen/MasterGollum/Gambit + Rest - Sirrobzeroone + +White Color Stock -- CC BY-SA 3.0 + Tree Wood (default_wood.png) - BlockMen + Cobble Wall (default_cobble.png) - Neuromancer/Brane Praefect + Rest - Sirrobzeroone + +Wool Over Your Eyes -- CC BY-SA 3.0 + Sun () - Celeron55 + Grass texture (default_grass.png) - Paramat + Dirt Texture (default_dirt.png) - Random-Geek/Neuromancer + Bluberry (default_blueberries.png) - Random-Geek + Viola (flowers_viola.png) - RHRhino/Gambit/yyt16384/Paramat + Grass Tall (default_grass_*.png) - Gambit + Rest - Sirrobzeroone + +Wow, I am Diamonds! -- CC BY-SA 3.0 + Diamond (default_diamond.png) - BlockMen + Stone (default_stone.png) - Cisoun + Rest - Sirrobzeroone + +You’re a copper -- CC0 (Public Domain) + All - Sirrobzeroone + +Yummy! -- CC0 (Public Domain) + All - Openclipart library/Sirrobzeroone + + + + + diff --git a/mods/awards/textures/_RinrinDaishi_message.png b/mods/awards/textures/_RinrinDaishi_message.png new file mode 100644 index 0000000..b22781e Binary files /dev/null and b/mods/awards/textures/_RinrinDaishi_message.png differ diff --git a/mods/awards/textures/awards_a_cat_in_a_pop_tart.png b/mods/awards/textures/awards_a_cat_in_a_pop_tart.png new file mode 100644 index 0000000..79ec4c1 Binary files /dev/null and b/mods/awards/textures/awards_a_cat_in_a_pop_tart.png differ diff --git a/mods/awards/textures/awards_architect.png b/mods/awards/textures/awards_architect.png new file mode 100644 index 0000000..526a290 Binary files /dev/null and b/mods/awards/textures/awards_architect.png differ diff --git a/mods/awards/textures/awards_aspiring_farmer.png b/mods/awards/textures/awards_aspiring_farmer.png new file mode 100644 index 0000000..6fcce95 Binary files /dev/null and b/mods/awards/textures/awards_aspiring_farmer.png differ diff --git a/mods/awards/textures/awards_backpacker.png b/mods/awards/textures/awards_backpacker.png new file mode 100644 index 0000000..d87ffa7 Binary files /dev/null and b/mods/awards/textures/awards_backpacker.png differ diff --git a/mods/awards/textures/awards_baker.png b/mods/awards/textures/awards_baker.png new file mode 100644 index 0000000..445da14 Binary files /dev/null and b/mods/awards/textures/awards_baker.png differ diff --git a/mods/awards/textures/awards_banker.png b/mods/awards/textures/awards_banker.png new file mode 100644 index 0000000..f0899c0 Binary files /dev/null and b/mods/awards/textures/awards_banker.png differ diff --git a/mods/awards/textures/awards_bg_default.png b/mods/awards/textures/awards_bg_default.png new file mode 100644 index 0000000..a6f57d3 Binary files /dev/null and b/mods/awards/textures/awards_bg_default.png differ diff --git a/mods/awards/textures/awards_bg_mining.png b/mods/awards/textures/awards_bg_mining.png new file mode 100644 index 0000000..a698779 Binary files /dev/null and b/mods/awards/textures/awards_bg_mining.png differ diff --git a/mods/awards/textures/awards_bricker.png b/mods/awards/textures/awards_bricker.png new file mode 100644 index 0000000..eb5e814 Binary files /dev/null and b/mods/awards/textures/awards_bricker.png differ diff --git a/mods/awards/textures/awards_build_a_cave.png b/mods/awards/textures/awards_build_a_cave.png new file mode 100644 index 0000000..de2e75b Binary files /dev/null and b/mods/awards/textures/awards_build_a_cave.png differ diff --git a/mods/awards/textures/awards_builder.png b/mods/awards/textures/awards_builder.png new file mode 100644 index 0000000..6c04003 Binary files /dev/null and b/mods/awards/textures/awards_builder.png differ diff --git a/mods/awards/textures/awards_castorama.png b/mods/awards/textures/awards_castorama.png new file mode 100644 index 0000000..b5dce24 Binary files /dev/null and b/mods/awards/textures/awards_castorama.png differ diff --git a/mods/awards/textures/awards_crafter_of_sticks.png b/mods/awards/textures/awards_crafter_of_sticks.png new file mode 100644 index 0000000..a2137bd Binary files /dev/null and b/mods/awards/textures/awards_crafter_of_sticks.png differ diff --git a/mods/awards/textures/awards_dandelions_are_yellow.png b/mods/awards/textures/awards_dandelions_are_yellow.png new file mode 100644 index 0000000..c875de1 Binary files /dev/null and b/mods/awards/textures/awards_dandelions_are_yellow.png differ diff --git a/mods/awards/textures/awards_desert_discoverer.png b/mods/awards/textures/awards_desert_discoverer.png new file mode 100644 index 0000000..6d4a2e5 Binary files /dev/null and b/mods/awards/textures/awards_desert_discoverer.png differ diff --git a/mods/awards/textures/awards_desert_dweller.png b/mods/awards/textures/awards_desert_dweller.png new file mode 100644 index 0000000..e03a2d1 Binary files /dev/null and b/mods/awards/textures/awards_desert_dweller.png differ diff --git a/mods/awards/textures/awards_engineer.png b/mods/awards/textures/awards_engineer.png new file mode 100644 index 0000000..bd6bd4f Binary files /dev/null and b/mods/awards/textures/awards_engineer.png differ diff --git a/mods/awards/textures/awards_far_lands.png b/mods/awards/textures/awards_far_lands.png new file mode 100644 index 0000000..2072bf6 Binary files /dev/null and b/mods/awards/textures/awards_far_lands.png differ diff --git a/mods/awards/textures/awards_farming_skills_acquired.png b/mods/awards/textures/awards_farming_skills_acquired.png new file mode 100644 index 0000000..28803dc Binary files /dev/null and b/mods/awards/textures/awards_farming_skills_acquired.png differ diff --git a/mods/awards/textures/awards_field_worker.png b/mods/awards/textures/awards_field_worker.png new file mode 100644 index 0000000..e898ee9 Binary files /dev/null and b/mods/awards/textures/awards_field_worker.png differ diff --git a/mods/awards/textures/awards_filthy_rich.png b/mods/awards/textures/awards_filthy_rich.png new file mode 100644 index 0000000..6578c38 Binary files /dev/null and b/mods/awards/textures/awards_filthy_rich.png differ diff --git a/mods/awards/textures/awards_firefighter.png b/mods/awards/textures/awards_firefighter.png new file mode 100644 index 0000000..46076a7 Binary files /dev/null and b/mods/awards/textures/awards_firefighter.png differ diff --git a/mods/awards/textures/awards_first_day_in_the_woods.png b/mods/awards/textures/awards_first_day_in_the_woods.png new file mode 100644 index 0000000..e677d88 Binary files /dev/null and b/mods/awards/textures/awards_first_day_in_the_woods.png differ diff --git a/mods/awards/textures/awards_first_gold_find.png b/mods/awards/textures/awards_first_gold_find.png new file mode 100644 index 0000000..edd6c14 Binary files /dev/null and b/mods/awards/textures/awards_first_gold_find.png differ diff --git a/mods/awards/textures/awards_first_mese_find.png b/mods/awards/textures/awards_first_mese_find.png new file mode 100644 index 0000000..43d848e Binary files /dev/null and b/mods/awards/textures/awards_first_mese_find.png differ diff --git a/mods/awards/textures/awards_fortress.png b/mods/awards/textures/awards_fortress.png new file mode 100644 index 0000000..d40ab74 Binary files /dev/null and b/mods/awards/textures/awards_fortress.png differ diff --git a/mods/awards/textures/awards_geraniums_are_blue.png b/mods/awards/textures/awards_geraniums_are_blue.png new file mode 100644 index 0000000..f4fed56 Binary files /dev/null and b/mods/awards/textures/awards_geraniums_are_blue.png differ diff --git a/mods/awards/textures/awards_girls_best_friend.png b/mods/awards/textures/awards_girls_best_friend.png new file mode 100644 index 0000000..6143ea4 Binary files /dev/null and b/mods/awards/textures/awards_girls_best_friend.png differ diff --git a/mods/awards/textures/awards_glacier_discoverer.png b/mods/awards/textures/awards_glacier_discoverer.png new file mode 100644 index 0000000..5d7b3ca Binary files /dev/null and b/mods/awards/textures/awards_glacier_discoverer.png differ diff --git a/mods/awards/textures/awards_glasser.png b/mods/awards/textures/awards_glasser.png new file mode 100644 index 0000000..a5dfb03 Binary files /dev/null and b/mods/awards/textures/awards_glasser.png differ diff --git a/mods/awards/textures/awards_gold_rush.png b/mods/awards/textures/awards_gold_rush.png new file mode 100644 index 0000000..dbd6ac3 Binary files /dev/null and b/mods/awards/textures/awards_gold_rush.png differ diff --git a/mods/awards/textures/awards_grasslands_discoverer.png b/mods/awards/textures/awards_grasslands_discoverer.png new file mode 100644 index 0000000..7de444c Binary files /dev/null and b/mods/awards/textures/awards_grasslands_discoverer.png differ diff --git a/mods/awards/textures/awards_hardened_miner.png b/mods/awards/textures/awards_hardened_miner.png new file mode 100644 index 0000000..d4baf48 Binary files /dev/null and b/mods/awards/textures/awards_hardened_miner.png differ diff --git a/mods/awards/textures/awards_hardest_block_on_earth.png b/mods/awards/textures/awards_hardest_block_on_earth.png new file mode 100644 index 0000000..3ab903c Binary files /dev/null and b/mods/awards/textures/awards_hardest_block_on_earth.png differ diff --git a/mods/awards/textures/awards_hotelier.png b/mods/awards/textures/awards_hotelier.png new file mode 100644 index 0000000..5a0f6fd Binary files /dev/null and b/mods/awards/textures/awards_hotelier.png differ diff --git a/mods/awards/textures/awards_house_of_obsidian.png b/mods/awards/textures/awards_house_of_obsidian.png new file mode 100644 index 0000000..15b3409 Binary files /dev/null and b/mods/awards/textures/awards_house_of_obsidian.png differ diff --git a/mods/awards/textures/awards_in_the_dungeon.png b/mods/awards/textures/awards_in_the_dungeon.png new file mode 100644 index 0000000..d419d64 Binary files /dev/null and b/mods/awards/textures/awards_in_the_dungeon.png differ diff --git a/mods/awards/textures/awards_industrial_age.png b/mods/awards/textures/awards_industrial_age.png new file mode 100644 index 0000000..d02c3c8 Binary files /dev/null and b/mods/awards/textures/awards_industrial_age.png differ diff --git a/mods/awards/textures/awards_jungle_discoverer.png b/mods/awards/textures/awards_jungle_discoverer.png new file mode 100644 index 0000000..f955e66 Binary files /dev/null and b/mods/awards/textures/awards_jungle_discoverer.png differ diff --git a/mods/awards/textures/awards_junglebaby.png b/mods/awards/textures/awards_junglebaby.png new file mode 100644 index 0000000..e878977 Binary files /dev/null and b/mods/awards/textures/awards_junglebaby.png differ diff --git a/mods/awards/textures/awards_jungleman.png b/mods/awards/textures/awards_jungleman.png new file mode 100644 index 0000000..11ad3bd Binary files /dev/null and b/mods/awards/textures/awards_jungleman.png differ diff --git a/mods/awards/textures/awards_lava_and_water.png b/mods/awards/textures/awards_lava_and_water.png new file mode 100644 index 0000000..a61ec12 Binary files /dev/null and b/mods/awards/textures/awards_lava_and_water.png differ diff --git a/mods/awards/textures/awards_lava_miner.png b/mods/awards/textures/awards_lava_miner.png new file mode 100644 index 0000000..14c4ff8 Binary files /dev/null and b/mods/awards/textures/awards_lava_miner.png differ diff --git a/mods/awards/textures/awards_level1.png b/mods/awards/textures/awards_level1.png new file mode 100644 index 0000000..92051e6 Binary files /dev/null and b/mods/awards/textures/awards_level1.png differ diff --git a/mods/awards/textures/awards_level2.png b/mods/awards/textures/awards_level2.png new file mode 100644 index 0000000..7132dcc Binary files /dev/null and b/mods/awards/textures/awards_level2.png differ diff --git a/mods/awards/textures/awards_level3.png b/mods/awards/textures/awards_level3.png new file mode 100644 index 0000000..4a61d25 Binary files /dev/null and b/mods/awards/textures/awards_level3.png differ diff --git a/mods/awards/textures/awards_level4.png b/mods/awards/textures/awards_level4.png new file mode 100644 index 0000000..5909a32 Binary files /dev/null and b/mods/awards/textures/awards_level4.png differ diff --git a/mods/awards/textures/awards_level5.png b/mods/awards/textures/awards_level5.png new file mode 100644 index 0000000..26b94ac Binary files /dev/null and b/mods/awards/textures/awards_level5.png differ diff --git a/mods/awards/textures/awards_level6.png b/mods/awards/textures/awards_level6.png new file mode 100644 index 0000000..1685125 Binary files /dev/null and b/mods/awards/textures/awards_level6.png differ diff --git a/mods/awards/textures/awards_level7.png b/mods/awards/textures/awards_level7.png new file mode 100644 index 0000000..6b84557 Binary files /dev/null and b/mods/awards/textures/awards_level7.png differ diff --git a/mods/awards/textures/awards_light_it_up.png b/mods/awards/textures/awards_light_it_up.png new file mode 100644 index 0000000..e8725d1 Binary files /dev/null and b/mods/awards/textures/awards_light_it_up.png differ diff --git a/mods/awards/textures/awards_little_library.png b/mods/awards/textures/awards_little_library.png new file mode 100644 index 0000000..bf609f3 Binary files /dev/null and b/mods/awards/textures/awards_little_library.png differ diff --git a/mods/awards/textures/awards_long_ladder.png b/mods/awards/textures/awards_long_ladder.png new file mode 100644 index 0000000..a3c38d9 Binary files /dev/null and b/mods/awards/textures/awards_long_ladder.png differ diff --git a/mods/awards/textures/awards_lumberjack.png b/mods/awards/textures/awards_lumberjack.png new file mode 100644 index 0000000..4f89c47 Binary files /dev/null and b/mods/awards/textures/awards_lumberjack.png differ diff --git a/mods/awards/textures/awards_marchand_de_sable.png b/mods/awards/textures/awards_marchand_de_sable.png new file mode 100644 index 0000000..01e80d6 Binary files /dev/null and b/mods/awards/textures/awards_marchand_de_sable.png differ diff --git a/mods/awards/textures/awards_master_architect.png b/mods/awards/textures/awards_master_architect.png new file mode 100644 index 0000000..34b8bc2 Binary files /dev/null and b/mods/awards/textures/awards_master_architect.png differ diff --git a/mods/awards/textures/awards_master_miner.png b/mods/awards/textures/awards_master_miner.png new file mode 100644 index 0000000..8bf37c4 Binary files /dev/null and b/mods/awards/textures/awards_master_miner.png differ diff --git a/mods/awards/textures/awards_mese_mastery.png b/mods/awards/textures/awards_mese_mastery.png new file mode 100644 index 0000000..89714ae Binary files /dev/null and b/mods/awards/textures/awards_mese_mastery.png differ diff --git a/mods/awards/textures/awards_mini_miner.png b/mods/awards/textures/awards_mini_miner.png new file mode 100644 index 0000000..4ccb127 Binary files /dev/null and b/mods/awards/textures/awards_mini_miner.png differ diff --git a/mods/awards/textures/awards_mushroom_lover.png b/mods/awards/textures/awards_mushroom_lover.png new file mode 100644 index 0000000..52805bd Binary files /dev/null and b/mods/awards/textures/awards_mushroom_lover.png differ diff --git a/mods/awards/textures/awards_obsessed_with_obsidian.png b/mods/awards/textures/awards_obsessed_with_obsidian.png new file mode 100644 index 0000000..4b179bd Binary files /dev/null and b/mods/awards/textures/awards_obsessed_with_obsidian.png differ diff --git a/mods/awards/textures/awards_on_the_way.png b/mods/awards/textures/awards_on_the_way.png new file mode 100644 index 0000000..c2fd224 Binary files /dev/null and b/mods/awards/textures/awards_on_the_way.png differ diff --git a/mods/awards/textures/awards_outpost.png b/mods/awards/textures/awards_outpost.png new file mode 100644 index 0000000..e278052 Binary files /dev/null and b/mods/awards/textures/awards_outpost.png differ diff --git a/mods/awards/textures/awards_pharaoh.png b/mods/awards/textures/awards_pharaoh.png new file mode 100644 index 0000000..f2f4b9a Binary files /dev/null and b/mods/awards/textures/awards_pharaoh.png differ diff --git a/mods/awards/textures/awards_professional_lumberjack.png b/mods/awards/textures/awards_professional_lumberjack.png new file mode 100644 index 0000000..6d67fb7 Binary files /dev/null and b/mods/awards/textures/awards_professional_lumberjack.png differ diff --git a/mods/awards/textures/awards_progress_gray.png b/mods/awards/textures/awards_progress_gray.png new file mode 100644 index 0000000..a5fc6cb Binary files /dev/null and b/mods/awards/textures/awards_progress_gray.png differ diff --git a/mods/awards/textures/awards_progress_green.png b/mods/awards/textures/awards_progress_green.png new file mode 100644 index 0000000..54b4e5d Binary files /dev/null and b/mods/awards/textures/awards_progress_green.png differ diff --git a/mods/awards/textures/awards_pyromaniac.png b/mods/awards/textures/awards_pyromaniac.png new file mode 100644 index 0000000..a12649c Binary files /dev/null and b/mods/awards/textures/awards_pyromaniac.png differ diff --git a/mods/awards/textures/awards_really_well_lit.png b/mods/awards/textures/awards_really_well_lit.png new file mode 100644 index 0000000..b69cdff Binary files /dev/null and b/mods/awards/textures/awards_really_well_lit.png differ diff --git a/mods/awards/textures/awards_roses_are_red.png b/mods/awards/textures/awards_roses_are_red.png new file mode 100644 index 0000000..994760f Binary files /dev/null and b/mods/awards/textures/awards_roses_are_red.png differ diff --git a/mods/awards/textures/awards_saint_maclou.png b/mods/awards/textures/awards_saint_maclou.png new file mode 100644 index 0000000..96b3b39 Binary files /dev/null and b/mods/awards/textures/awards_saint_maclou.png differ diff --git a/mods/awards/textures/awards_sam_the_trapper.png b/mods/awards/textures/awards_sam_the_trapper.png new file mode 100644 index 0000000..89ba567 Binary files /dev/null and b/mods/awards/textures/awards_sam_the_trapper.png differ diff --git a/mods/awards/textures/awards_savannah_discoverer.png b/mods/awards/textures/awards_savannah_discoverer.png new file mode 100644 index 0000000..26c5a39 Binary files /dev/null and b/mods/awards/textures/awards_savannah_discoverer.png differ diff --git a/mods/awards/textures/awards_semi_pro_lumberjack.png b/mods/awards/textures/awards_semi_pro_lumberjack.png new file mode 100644 index 0000000..c4d2d79 Binary files /dev/null and b/mods/awards/textures/awards_semi_pro_lumberjack.png differ diff --git a/mods/awards/textures/awards_smelter.png b/mods/awards/textures/awards_smelter.png new file mode 100644 index 0000000..0dea637 Binary files /dev/null and b/mods/awards/textures/awards_smelter.png differ diff --git a/mods/awards/textures/awards_tasty_mushrooms.png b/mods/awards/textures/awards_tasty_mushrooms.png new file mode 100644 index 0000000..bf34fd2 Binary files /dev/null and b/mods/awards/textures/awards_tasty_mushrooms.png differ diff --git a/mods/awards/textures/awards_template.png b/mods/awards/textures/awards_template.png new file mode 100644 index 0000000..4ea47d1 Binary files /dev/null and b/mods/awards/textures/awards_template.png differ diff --git a/mods/awards/textures/awards_treasurer.png b/mods/awards/textures/awards_treasurer.png new file mode 100644 index 0000000..b872604 Binary files /dev/null and b/mods/awards/textures/awards_treasurer.png differ diff --git a/mods/awards/textures/awards_ui_icon.png b/mods/awards/textures/awards_ui_icon.png new file mode 100644 index 0000000..239ad71 Binary files /dev/null and b/mods/awards/textures/awards_ui_icon.png differ diff --git a/mods/awards/textures/awards_underground_mushroom_farmer.png b/mods/awards/textures/awards_underground_mushroom_farmer.png new file mode 100644 index 0000000..5623171 Binary files /dev/null and b/mods/awards/textures/awards_underground_mushroom_farmer.png differ diff --git a/mods/awards/textures/awards_unknown.png b/mods/awards/textures/awards_unknown.png new file mode 100644 index 0000000..40d839c Binary files /dev/null and b/mods/awards/textures/awards_unknown.png differ diff --git a/mods/awards/textures/awards_very_simple_snow_man.png b/mods/awards/textures/awards_very_simple_snow_man.png new file mode 100644 index 0000000..b2da7b7 Binary files /dev/null and b/mods/awards/textures/awards_very_simple_snow_man.png differ diff --git a/mods/awards/textures/awards_watchtower.png b/mods/awards/textures/awards_watchtower.png new file mode 100644 index 0000000..22fabd5 Binary files /dev/null and b/mods/awards/textures/awards_watchtower.png differ diff --git a/mods/awards/textures/awards_well_lit.png b/mods/awards/textures/awards_well_lit.png new file mode 100644 index 0000000..db85e70 Binary files /dev/null and b/mods/awards/textures/awards_well_lit.png differ diff --git a/mods/awards/textures/awards_wheat_magnate.png b/mods/awards/textures/awards_wheat_magnate.png new file mode 100644 index 0000000..835d5fa Binary files /dev/null and b/mods/awards/textures/awards_wheat_magnate.png differ diff --git a/mods/awards/textures/awards_white_color_stock.png b/mods/awards/textures/awards_white_color_stock.png new file mode 100644 index 0000000..4f850f0 Binary files /dev/null and b/mods/awards/textures/awards_white_color_stock.png differ diff --git a/mods/awards/textures/awards_wool_over_your_eyes.png b/mods/awards/textures/awards_wool_over_your_eyes.png new file mode 100644 index 0000000..740c5f0 Binary files /dev/null and b/mods/awards/textures/awards_wool_over_your_eyes.png differ diff --git a/mods/awards/textures/awards_wow_i_am_diamonds.png b/mods/awards/textures/awards_wow_i_am_diamonds.png new file mode 100644 index 0000000..5bb71b9 Binary files /dev/null and b/mods/awards/textures/awards_wow_i_am_diamonds.png differ diff --git a/mods/awards/textures/awards_youre_a_copper.png b/mods/awards/textures/awards_youre_a_copper.png new file mode 100644 index 0000000..4d28811 Binary files /dev/null and b/mods/awards/textures/awards_youre_a_copper.png differ diff --git a/mods/awards/textures/awards_yummy.png b/mods/awards/textures/awards_yummy.png new file mode 100644 index 0000000..da230e8 Binary files /dev/null and b/mods/awards/textures/awards_yummy.png differ diff --git a/mods/awards/tools/updatepo.sh b/mods/awards/tools/updatepo.sh new file mode 100755 index 0000000..74332e0 --- /dev/null +++ b/mods/awards/tools/updatepo.sh @@ -0,0 +1,22 @@ +#! /bin/bash + +# To create a new translation: +# msginit --locale=ll_CC -o locale/ll_CC.po -i locale/template.pot + +cd "$(dirname "${BASH_SOURCE[0]}")/.."; + +# Extract translatable strings. +xgettext --from-code=UTF-8 \ + --keyword=S \ + --keyword=NS:1,2 \ + --keyword=N_ \ + --add-comments='Translators:' \ + --add-location=file \ + -o locale/template.pot \ + $(find . -name '*.lua') + +# Update translations. +find locale -name '*.po' | while read -r file; do + echo $file + msgmerge --update $file locale/template.pot; +done diff --git a/mods/bakedclay/README.md b/mods/bakedclay/README.md new file mode 100644 index 0000000..fd143df --- /dev/null +++ b/mods/bakedclay/README.md @@ -0,0 +1,20 @@ +Baked Clay + +This mod lets the player bake clay into hardened blocks and colour them with +dye (8x baked clay and 1x dye in centre), stairs and slabs are also available. + +https://forum.minetest.net/viewtopic.php?id=8890 + +Changelog: + +- 0.9 - Baked clay now works in the technic cnc machine +- 0.8 - Cooking clay block in furnace gives natural baked clay which you can dye +- 0.7 - Added support for stairsplus so that stairs are registered properly +- 0.6 - Added 3 new flowers and a new grass that are used for missing dyes +- 0.5 - Now using minecraft recipe to colour baked clay (8x baked clay, 1x dye in centre) +- 0.4 - Code tweak and tidy +- 0.3 - Added Stairs and Slabs for each colour +- 0.2 - Any colour of baked clay can be re-dyed into another colour +- 0.1 - Initial Release + +Lucky Blocks: 9 diff --git a/mods/bakedclay/init.lua b/mods/bakedclay/init.lua new file mode 100644 index 0000000..7b04233 --- /dev/null +++ b/mods/bakedclay/init.lua @@ -0,0 +1,300 @@ + +-- Baked Clay by TenPlus1 + +local clay = { + {"natural", "Natural"}, + {"white", "White"}, + {"grey", "Grey"}, + {"black", "Black"}, + {"red", "Red"}, + {"yellow", "Yellow"}, + {"green", "Green"}, + {"cyan", "Cyan"}, + {"blue", "Blue"}, + {"magenta", "Magenta"}, + {"orange", "Orange"}, + {"violet", "Violet"}, + {"brown", "Brown"}, + {"pink", "Pink"}, + {"dark_grey", "Dark Grey"}, + {"dark_green", "Dark Green"}, +} + +local techcnc_mod = minetest.get_modpath("technic_cnc") +local stairs_mod = minetest.get_modpath("stairs") +local stairsplus_mod = minetest.get_modpath("moreblocks") + and minetest.global_exists("stairsplus") + +for _, clay in pairs(clay) do + + -- node definition + + minetest.register_node("bakedclay:" .. clay[1], { + description = clay[2] .. " Baked Clay", + tiles = {"baked_clay_" .. clay[1] ..".png"}, + groups = {cracky = 3, bakedclay = 1}, + sounds = default.node_sound_stone_defaults(), + }) + + -- craft from dye and any baked clay + if clay[1] ~= "natural" then + minetest.register_craft({ + output = "bakedclay:" .. clay[1] .. " 8", + recipe = { + {"group:bakedclay", "group:bakedclay", "group:bakedclay"}, + {"group:bakedclay", "dye:" .. clay[1], "group:bakedclay"}, + {"group:bakedclay", "group:bakedclay", "group:bakedclay"} + }, + }) + end + + -- register stairsplus stairs if found + if stairsplus_mod then + + stairsplus:register_all("bakedclay", "baked_clay_" .. clay[1], "bakedclay:" .. clay[1], { + description = clay[2] .. " Baked Clay", + tiles = {"baked_clay_" .. clay[1] .. ".png"}, + groups = {cracky = 3}, + sounds = default.node_sound_stone_defaults(), + }) + + stairsplus:register_alias_all("bakedclay", clay[1], "bakedclay", "baked_clay_" .. clay[1]) + minetest.register_alias("stairs:slab_bakedclay_".. clay[1], "bakedclay:slab_baked_clay_" .. clay[1]) + minetest.register_alias("stairs:stair_bakedclay_".. clay[1], "bakedclay:stair_baked_clay_" .. clay[1]) + + -- register all stair types for stairs redo + elseif stairs_mod and stairs.mod then + + stairs.register_all("bakedclay_" .. clay[1], "bakedclay:" .. clay[1], + {cracky = 3}, + {"baked_clay_" .. clay[1] .. ".png"}, + clay[2] .. " Baked Clay", + default.node_sound_stone_defaults()) + + -- register stair and slab using default stairs + elseif stairs_mod then + + stairs.register_stair_and_slab("bakedclay_".. clay[1], "bakedclay:".. clay[1], + {cracky = 3}, + {"baked_clay_" .. clay[1] .. ".png"}, + clay[2] .. " Baked Clay Stair", + clay[2] .. " Baked Clay Slab", + default.node_sound_stone_defaults()) + end + + -- register bakedclay for use in technic_cnc mod + if techcnc_mod then + + technic_cnc.register_all("bakedclay:" .. clay[1], + {cracky = 3, not_in_creative_inventory = 1}, + {"baked_clay_" .. clay[1] .. ".png"}, + clay[2] .. " Baked Clay") + end +end + +-- cook clay block into white baked clay + +minetest.register_craft({ + type = "cooking", + output = "bakedclay:natural", + recipe = "default:clay", +}) + +-- register a few extra dye colour options + +minetest.register_craft( { + type = "shapeless", + output = "dye:dark_grey 3", + recipe = {"dye:black", "dye:black", "dye:white"} +}) + +minetest.register_craft( { + type = "shapeless", + output = "dye:grey 3", + recipe = {"dye:black", "dye:white", "dye:white"} +}) + +minetest.register_craft( { + type = "shapeless", + output = "dye:green 4", + recipe = {"default:cactus"} +}) + +minetest.register_craft( { + type = "shapeless", + output = "dye:black 4", + recipe = {"default:coal_lump"} +}) + +minetest.register_craft( { + type = "shapeless", + output = "dye:brown 4", + recipe = {"default:dry_shrub"} +}) + +-- 2x2 red bakedclay makes 16x clay brick +minetest.register_craft( { + output = "default:clay_brick 16", + recipe = { + {"bakedclay:red", "bakedclay:red"}, + {"bakedclay:red", "bakedclay:red"}, + } +}) + +-- register some new flowers to fill in missing dye colours +-- flower registration (borrowed from default game) + +local function add_simple_flower(name, desc, box, f_groups) + + f_groups.snappy = 3 + f_groups.flower = 1 + f_groups.flora = 1 + f_groups.attached_node = 1 + + minetest.register_node("bakedclay:" .. name, { + description = desc, + drawtype = "plantlike", + waving = 1, + tiles = {"baked_clay_" .. name .. ".png"}, + inventory_image = "baked_clay_" .. name .. ".png", + wield_image = "baked_clay_" .. name .. ".png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + stack_max = 99, + groups = f_groups, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = box + } + }) +end + +local flowers = { + {"delphinium", "Blue Delphinium", {-0.15, -0.5, -0.15, 0.15, 0.3, 0.15}, {color_cyan = 1}}, + {"thistle", "Thistle", {-0.15, -0.5, -0.15, 0.15, 0.2, 0.15}, {color_magenta = 1}}, + {"lazarus", "Lazarus Bell", {-0.15, -0.5, -0.15, 0.15, 0.2, 0.15}, {color_pink = 1}}, + {"mannagrass", "Reed Mannagrass", {-0.15, -0.5, -0.15, 0.15, 0.2, 0.15}, {color_dark_green = 1}}, +} + +for _,item in pairs(flowers) do + add_simple_flower(unpack(item)) +end + +-- mapgen for new flowers + +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.004, + spread = {x = 100, y = 100, z = 100}, + seed = 7133, + octaves = 3, + persist = 0.6 + }, + y_min = 10, + y_max = 90, + decoration = "bakedclay:delphinium", +}) + +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dirt_with_grass", "default:dirt_with_dry_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.004, + spread = {x = 100, y = 100, z = 100}, + seed = 7134, + octaves = 3, + persist = 0.6 + }, + y_min = 15, + y_max = 90, + decoration = "bakedclay:thistle", +}) + +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dirt_with_grass", "default:dirt_with_rainforest_litter"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 7135, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = 90, + decoration = "bakedclay:lazarus", + spawn_by = "default:jungletree", + num_spawn_by = 1, +}) + +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dirt_with_grass", "default:sand"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.009, + spread = {x = 100, y = 100, z = 100}, + seed = 7136, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = 15, + decoration = "bakedclay:mannagrass", + spawn_by = "group:water", + num_spawn_by = 1, +}) + +-- add lucky blocks + +if minetest.get_modpath("lucky_block") then +local p = "bakedclay:" +lucky_block:add_blocks({ + {"dro", {"bakedclay:"}, 10, true}, + {"fal", {p.."black", p.."blue", p.."brown", p.."cyan", p.."dark_green", + p.."dark_grey", p.."green", p.."grey", p.."magenta", p.."orange", + p.."pink", p.."red", p.."violet", p.."white", p.."yellow", p.."natural"}, 0}, + {"fal", {p.."black", p.."blue", p.."brown", p.."cyan", p.."dark_green", + p.."dark_grey", p.."green", p.."grey", p.."magenta", p.."orange", + p.."pink", p.."red", p.."violet", p.."white", p.."yellow", p.."natural"}, 0, true}, + {"dro", {p.."delphinium"}, 5}, + {"dro", {p.."lazarus"}, 5}, + {"dro", {p.."mannagrass"}, 5}, + {"dro", {p.."thistle"}, 6}, + {"flo", 5, {p.."natural", p.."black", p.."blue", p.."brown", p.."cyan", + p.."dark_green", p.."dark_grey", p.."green", p.."grey", p.."magenta", + p.."orange", p.."pink", p.."red", p.."violet", p.."white", p.."yellow"}, 2}, + {"nod", "default:chest", 0, { + {name = p.."natural", max = 30}, + {name = p.."black", max = 30}, + {name = p.."blue", max = 30}, + {name = p.."brown", max = 30}, + {name = p.."cyan", max = 30}, + {name = p.."dark_green", max = 30}, + {name = p.."dark_grey", max = 30}, + {name = p.."green", max = 30}, + {name = p.."grey", max = 30}, + {name = p.."magenta", max = 30}, + {name = p.."orange", max = 30}, + {name = p.."pink", max = 30}, + {name = p.."red", max = 30}, + {name = p.."violet", max = 30}, + {name = p.."white", max = 30}, + {name = p.."yellow", max = 30}, + }}, +}) +end + +print ("[MOD] Baked Clay loaded") diff --git a/mods/bakedclay/license.txt b/mods/bakedclay/license.txt new file mode 100644 index 0000000..fec6f6a --- /dev/null +++ b/mods/bakedclay/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 TenPlus1 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/mods/bakedclay/mod.conf b/mods/bakedclay/mod.conf new file mode 100644 index 0000000..8eb320b --- /dev/null +++ b/mods/bakedclay/mod.conf @@ -0,0 +1,4 @@ +name = bakedclay +description = Adds the ability to bake clay into blocks and colour them with dye. +depends = default, stairs +optional_depends = moreblocks, lucky_block, technic_cnc diff --git a/mods/bakedclay/screenshot.png b/mods/bakedclay/screenshot.png new file mode 100644 index 0000000..68a950a Binary files /dev/null and b/mods/bakedclay/screenshot.png differ diff --git a/mods/bakedclay/textures/baked_clay_black.png b/mods/bakedclay/textures/baked_clay_black.png new file mode 100644 index 0000000..956f315 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_black.png differ diff --git a/mods/bakedclay/textures/baked_clay_blue.png b/mods/bakedclay/textures/baked_clay_blue.png new file mode 100644 index 0000000..2b11d36 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_blue.png differ diff --git a/mods/bakedclay/textures/baked_clay_brown.png b/mods/bakedclay/textures/baked_clay_brown.png new file mode 100644 index 0000000..f46e328 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_brown.png differ diff --git a/mods/bakedclay/textures/baked_clay_cyan.png b/mods/bakedclay/textures/baked_clay_cyan.png new file mode 100644 index 0000000..364793e Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_cyan.png differ diff --git a/mods/bakedclay/textures/baked_clay_dark_green.png b/mods/bakedclay/textures/baked_clay_dark_green.png new file mode 100644 index 0000000..2bd2586 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_dark_green.png differ diff --git a/mods/bakedclay/textures/baked_clay_dark_grey.png b/mods/bakedclay/textures/baked_clay_dark_grey.png new file mode 100644 index 0000000..44642e7 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_dark_grey.png differ diff --git a/mods/bakedclay/textures/baked_clay_delphinium.png b/mods/bakedclay/textures/baked_clay_delphinium.png new file mode 100644 index 0000000..51b8ef9 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_delphinium.png differ diff --git a/mods/bakedclay/textures/baked_clay_green.png b/mods/bakedclay/textures/baked_clay_green.png new file mode 100644 index 0000000..58f348c Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_green.png differ diff --git a/mods/bakedclay/textures/baked_clay_grey.png b/mods/bakedclay/textures/baked_clay_grey.png new file mode 100644 index 0000000..deecb6a Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_grey.png differ diff --git a/mods/bakedclay/textures/baked_clay_lazarus.png b/mods/bakedclay/textures/baked_clay_lazarus.png new file mode 100644 index 0000000..548a4b1 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_lazarus.png differ diff --git a/mods/bakedclay/textures/baked_clay_magenta.png b/mods/bakedclay/textures/baked_clay_magenta.png new file mode 100644 index 0000000..e740738 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_magenta.png differ diff --git a/mods/bakedclay/textures/baked_clay_mannagrass.png b/mods/bakedclay/textures/baked_clay_mannagrass.png new file mode 100644 index 0000000..295d41d Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_mannagrass.png differ diff --git a/mods/bakedclay/textures/baked_clay_natural.png b/mods/bakedclay/textures/baked_clay_natural.png new file mode 100644 index 0000000..56893aa Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_natural.png differ diff --git a/mods/bakedclay/textures/baked_clay_orange.png b/mods/bakedclay/textures/baked_clay_orange.png new file mode 100644 index 0000000..847b793 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_orange.png differ diff --git a/mods/bakedclay/textures/baked_clay_pink.png b/mods/bakedclay/textures/baked_clay_pink.png new file mode 100644 index 0000000..417fcfc Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_pink.png differ diff --git a/mods/bakedclay/textures/baked_clay_red.png b/mods/bakedclay/textures/baked_clay_red.png new file mode 100644 index 0000000..e716218 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_red.png differ diff --git a/mods/bakedclay/textures/baked_clay_thistle.png b/mods/bakedclay/textures/baked_clay_thistle.png new file mode 100644 index 0000000..22a3d51 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_thistle.png differ diff --git a/mods/bakedclay/textures/baked_clay_violet.png b/mods/bakedclay/textures/baked_clay_violet.png new file mode 100644 index 0000000..b5db133 Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_violet.png differ diff --git a/mods/bakedclay/textures/baked_clay_white.png b/mods/bakedclay/textures/baked_clay_white.png new file mode 100644 index 0000000..ff953ab Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_white.png differ diff --git a/mods/bakedclay/textures/baked_clay_yellow.png b/mods/bakedclay/textures/baked_clay_yellow.png new file mode 100644 index 0000000..e26e40c Binary files /dev/null and b/mods/bakedclay/textures/baked_clay_yellow.png differ diff --git a/mods/bedrock2/README.md b/mods/bedrock2/README.md new file mode 100644 index 0000000..5309a58 --- /dev/null +++ b/mods/bedrock2/README.md @@ -0,0 +1,11 @@ +# Bedrock [`bedrock2`] + +Version 1.2.2 + +## Description +This mod adds an indestructible bedrock layer at the bottom of the world. + +## Configuration +This mod recognizes the following minetest.conf setting: + +* `bedrock2_y`: Sets the Y coordinate on which the bedrock layer will be created (default: -30912). diff --git a/mods/bedrock2/init.lua b/mods/bedrock2/init.lua new file mode 100644 index 0000000..5c5aa3c --- /dev/null +++ b/mods/bedrock2/init.lua @@ -0,0 +1,46 @@ +local S = minetest.get_translator("bedrock2") + +local bedrock = {} + +bedrock.layer = -30912 -- determined as appropriate by experiment +bedrock.node = {name = "bedrock2:bedrock"} + +local depth = tonumber(minetest.settings:get("bedrock2_y")) +if depth ~= nil then + bedrock.layer = depth +end + +minetest.register_on_generated(function(minp, maxp) + if maxp.y >= bedrock.layer and minp.y <= bedrock.layer then + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local data = vm:get_data() + local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) + local c_bedrock = minetest.get_content_id("bedrock2:bedrock") + + for x = minp.x, maxp.x do + for z = minp.z, maxp.z do + local p_pos = area:index(x, bedrock.layer, z) + data[p_pos] = c_bedrock + end + end + + vm:set_data(data) + vm:calc_lighting() + vm:update_liquids() + vm:write_to_map() + end +end) + +minetest.register_node("bedrock2:bedrock", { + description = S("Bedrock"), + _doc_items_longdesc = S("Bedrock is a very hard block. It cannot be mined, altered, destroyed or moved by any means. It appears at the bottom of the world in a flat layer."), + tiles = {"bedrock2_bedrock.png"}, + groups = {immortal=1, not_in_creative_inventory=1, }, + sounds = { footstep = { name = "bedrock2_step", gain = 1 } }, + is_ground_content = false, + on_blast = function() end, + on_destruct = function () end, + can_dig = function() return false end, + diggable = false, + drop = "", +}) diff --git a/mods/bedrock2/license.txt b/mods/bedrock2/license.txt new file mode 100644 index 0000000..185e9cc --- /dev/null +++ b/mods/bedrock2/license.txt @@ -0,0 +1,3 @@ +Code is licensed MIT, Media CC by SA 4.0 + +Relicensed from wtfpl diff --git a/mods/bedrock2/locale/bedrock2.de.tr b/mods/bedrock2/locale/bedrock2.de.tr new file mode 100644 index 0000000..e625f37 --- /dev/null +++ b/mods/bedrock2/locale/bedrock2.de.tr @@ -0,0 +1,3 @@ +# textdomain:bedrock2 +Bedrock=Grundgestein +Bedrock is a very hard block. It cannot be mined, altered, destroyed or moved by any means. It appears at the bottom of the world in a flat layer.=Grundgestein ist sehr hart. Es kann nicht gegraben, verändert, zerstört oder bewegt werden. Es taucht am Boden der Welt in einer flachen Ebene auf. diff --git a/mods/bedrock2/locale/template.txt b/mods/bedrock2/locale/template.txt new file mode 100644 index 0000000..555f804 --- /dev/null +++ b/mods/bedrock2/locale/template.txt @@ -0,0 +1,2 @@ +Bedrock +Bedrock is a very hard block. It cannot be mined, altered, destroyed or moved by any means. It appears at the bottom of the world in a flat layer. diff --git a/mods/bedrock2/mod.conf b/mods/bedrock2/mod.conf new file mode 100644 index 0000000..2223c7e --- /dev/null +++ b/mods/bedrock2/mod.conf @@ -0,0 +1 @@ +name = bedrock2 diff --git a/mods/bedrock2/settingtypes.txt b/mods/bedrock2/settingtypes.txt new file mode 100644 index 0000000..e9f9818 --- /dev/null +++ b/mods/bedrock2/settingtypes.txt @@ -0,0 +1,2 @@ +# Sets the height (Y) at which the bedrock layer will be created. +bedrock2_y (Bedrock height) int -30912 diff --git a/mods/bedrock2/sounds/bedrock2_step.1.ogg b/mods/bedrock2/sounds/bedrock2_step.1.ogg new file mode 100644 index 0000000..63f364d Binary files /dev/null and b/mods/bedrock2/sounds/bedrock2_step.1.ogg differ diff --git a/mods/bedrock2/sounds/bedrock2_step.2.ogg b/mods/bedrock2/sounds/bedrock2_step.2.ogg new file mode 100644 index 0000000..cb3b91c Binary files /dev/null and b/mods/bedrock2/sounds/bedrock2_step.2.ogg differ diff --git a/mods/bedrock2/sounds/bedrock2_step.3.ogg b/mods/bedrock2/sounds/bedrock2_step.3.ogg new file mode 100644 index 0000000..2f97002 Binary files /dev/null and b/mods/bedrock2/sounds/bedrock2_step.3.ogg differ diff --git a/mods/bedrock2/textures/bedrock2_bedrock.png b/mods/bedrock2/textures/bedrock2_bedrock.png new file mode 100644 index 0000000..2d29423 Binary files /dev/null and b/mods/bedrock2/textures/bedrock2_bedrock.png differ diff --git a/mods/beds/README.txt b/mods/beds/README.txt new file mode 100644 index 0000000..7b35e14 --- /dev/null +++ b/mods/beds/README.txt @@ -0,0 +1,30 @@ +Minetest Game mod: beds +======================= +See license.txt for license information. + +Authors of source code +---------------------- +Originally by BlockMen (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +BlockMen (CC BY-SA 3.0) + All textures unless otherwise noted + +TumeniNodes (CC BY-SA 3.0) + beds_bed_under.png + +This mod adds a bed to Minetest which allows players to skip the night. +To sleep, right click on the bed. If playing in singleplayer mode the night gets skipped +immediately. If playing multiplayer you get shown how many other players are in bed too, +if all players are sleeping the night gets skipped. The night skip can be forced if more +than half of the players are lying in bed and use this option. + +Another feature is a controlled respawning. If you have slept in bed (not just lying in +it) your respawn point is set to the beds location and you will respawn there after +death. +You can disable the respawn at beds by setting "enable_bed_respawn = false" in +minetest.conf. +You can disable the night skip feature by setting "enable_bed_night_skip = false" in +minetest.conf or by using the /set command in-game. diff --git a/mods/beds/api.lua b/mods/beds/api.lua new file mode 100644 index 0000000..09687a2 --- /dev/null +++ b/mods/beds/api.lua @@ -0,0 +1,182 @@ + +local reverse = true + +local function destruct_bed(pos, n) + local node = minetest.get_node(pos) + local other + + if n == 2 then + local dir = minetest.facedir_to_dir(node.param2) + other = vector.subtract(pos, dir) + elseif n == 1 then + local dir = minetest.facedir_to_dir(node.param2) + other = vector.add(pos, dir) + end + + if reverse then + reverse = not reverse + minetest.remove_node(other) + minetest.check_for_falling(other) + beds.remove_spawns_at(pos) + beds.remove_spawns_at(other) + else + reverse = not reverse + end +end + +function beds.register_bed(name, def) + minetest.register_node(name .. "_bottom", { + description = def.description, + inventory_image = def.inventory_image, + wield_image = def.wield_image, + drawtype = "nodebox", + tiles = def.tiles.bottom, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + stack_max = 1, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1}, + sounds = def.sounds or default.node_sound_wood_defaults(), + node_box = { + type = "fixed", + fixed = def.nodebox.bottom, + }, + selection_box = { + type = "fixed", + fixed = def.selectionbox, + }, + + 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:is_player() and + placer:get_player_control().sneak) then + return udef.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + + local pos + if udef and udef.buildable_to then + pos = under + else + pos = pointed_thing.above + end + + local player_name = placer and placer:get_player_name() or "" + + if minetest.is_protected(pos, player_name) and + not minetest.check_player_privs(player_name, "protection_bypass") then + minetest.record_protection_violation(pos, player_name) + return itemstack + end + + local node_def = minetest.registered_nodes[minetest.get_node(pos).name] + if not node_def or not node_def.buildable_to then + return itemstack + end + + local dir = placer and placer:get_look_dir() and + minetest.dir_to_facedir(placer:get_look_dir()) or 0 + local botpos = vector.add(pos, minetest.facedir_to_dir(dir)) + + if minetest.is_protected(botpos, player_name) and + not minetest.check_player_privs(player_name, "protection_bypass") then + minetest.record_protection_violation(botpos, player_name) + return itemstack + end + + local botdef = minetest.registered_nodes[minetest.get_node(botpos).name] + if not botdef or not botdef.buildable_to then + return itemstack + end + + minetest.set_node(pos, {name = name .. "_bottom", param2 = dir}) + minetest.set_node(botpos, {name = name .. "_top", param2 = dir}) + + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(player_name)) then + itemstack:take_item() + end + return itemstack + end, + + on_destruct = function(pos) + destruct_bed(pos, 1) + end, + + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + beds.on_rightclick(pos, clicker) + return itemstack + end, + + on_rotate = function(pos, node, user, _, new_param2) + local dir = minetest.facedir_to_dir(node.param2) + local p = vector.add(pos, dir) + local node2 = minetest.get_node_or_nil(p) + if not node2 or not minetest.get_item_group(node2.name, "bed") == 2 or + not node.param2 == node2.param2 then + return false + end + if minetest.is_protected(p, user:get_player_name()) then + minetest.record_protection_violation(p, user:get_player_name()) + return false + end + if new_param2 % 32 > 3 then + return false + end + local newp = vector.add(pos, minetest.facedir_to_dir(new_param2)) + local node3 = minetest.get_node_or_nil(newp) + local node_def = node3 and minetest.registered_nodes[node3.name] + if not node_def or not node_def.buildable_to then + return false + end + if minetest.is_protected(newp, user:get_player_name()) then + minetest.record_protection_violation(newp, user:get_player_name()) + return false + end + node.param2 = new_param2 + -- do not remove_node here - it will trigger destroy_bed() + minetest.set_node(p, {name = "air"}) + minetest.set_node(pos, node) + minetest.set_node(newp, {name = name .. "_top", param2 = new_param2}) + return true + end, + can_dig = function(pos, player) + return beds.can_dig(pos) + end, + }) + + minetest.register_node(name .. "_top", { + drawtype = "nodebox", + tiles = def.tiles.top, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + pointable = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 2}, + sounds = def.sounds or default.node_sound_wood_defaults(), + drop = name .. "_bottom", + node_box = { + type = "fixed", + fixed = def.nodebox.top, + }, + on_destruct = function(pos) + destruct_bed(pos, 2) + end, + can_dig = function(pos, player) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + local p = vector.add(pos, dir) + return beds.can_dig(p) + end, + }) + + minetest.register_alias(name, name .. "_bottom") + +-- minetest.register_craft({ +-- output = name, +-- recipe = def.recipe +-- }) +end diff --git a/mods/beds/beds.lua b/mods/beds/beds.lua new file mode 100644 index 0000000..dc044a3 --- /dev/null +++ b/mods/beds/beds.lua @@ -0,0 +1,109 @@ +-- beds/beds.lua + +-- support for MT game translation. +local S = beds.get_translator + +-- Fancy shaped bed + +beds.register_bed("beds:fancy_bed", { + description = S("Fancy Bed"), + inventory_image = "beds_bed_fancy.png", + wield_image = "beds_bed_fancy.png", + tiles = { + bottom = { + "beds_bed_top1.png", + "beds_bed_under.png", + "beds_bed_side1.png", + "beds_bed_side1.png^[transformFX", + "beds_bed_foot.png", + "beds_bed_foot.png", + }, + top = { + "beds_bed_top2.png", + "beds_bed_under.png", + "beds_bed_side2.png", + "beds_bed_side2.png^[transformFX", + "beds_bed_head.png", + "beds_bed_head.png", + } + }, + nodebox = { + bottom = { + {-0.5, -0.5, -0.5, -0.375, -0.065, -0.4375}, + {0.375, -0.5, -0.5, 0.5, -0.065, -0.4375}, + {-0.5, -0.375, -0.5, 0.5, -0.125, -0.4375}, + {-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5}, + {0.4375, -0.375, -0.5, 0.5, -0.125, 0.5}, + {-0.4375, -0.3125, -0.4375, 0.4375, -0.0625, 0.5}, + }, + top = { + {-0.5, -0.5, 0.4375, -0.375, 0.1875, 0.5}, + {0.375, -0.5, 0.4375, 0.5, 0.1875, 0.5}, + {-0.5, 0, 0.4375, 0.5, 0.125, 0.5}, + {-0.5, -0.375, 0.4375, 0.5, -0.125, 0.5}, + {-0.5, -0.375, -0.5, -0.4375, -0.125, 0.5}, + {0.4375, -0.375, -0.5, 0.5, -0.125, 0.5}, + {-0.4375, -0.3125, -0.5, 0.4375, -0.0625, 0.4375}, + } + }, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.06, 1.5}, + recipe = { + {"", "", "group:stick"}, + {"wool:white", "wool:white", "wool:white"}, + {"group:wood", "group:wood", "group:wood"}, + }, +}) + +-- Simple shaped bed + +beds.register_bed("beds:bed", { + description = S("Simple Bed"), + inventory_image = "beds_bed.png", + wield_image = "beds_bed.png", + tiles = { + bottom = { + "beds_bed_top_bottom.png^[transformR90", + "beds_bed_under.png", + "beds_bed_side_bottom_r.png", + "beds_bed_side_bottom_r.png^[transformfx", + "beds_transparent.png", + "beds_bed_side_bottom.png" + }, + top = { + "beds_bed_top_top.png^[transformR90", + "beds_bed_under.png", + "beds_bed_side_top_r.png", + "beds_bed_side_top_r.png^[transformfx", + "beds_bed_side_top.png", + "beds_transparent.png", + } + }, + nodebox = { + bottom = {-0.5, -0.5, -0.5, 0.5, 0.0625, 0.5}, + top = {-0.5, -0.5, -0.5, 0.5, 0.0625, 0.5}, + }, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.0625, 1.5}, + recipe = { + {"wool:white", "wool:white", "wool:white"}, + {"group:wood", "group:wood", "group:wood"} + }, +}) + +-- Aliases for PilzAdam's beds mod + +minetest.register_alias("beds:bed_bottom_red", "beds:bed_bottom") +minetest.register_alias("beds:bed_top_red", "beds:bed_top") + +-- Fuel + +minetest.register_craft({ + type = "fuel", + recipe = "beds:fancy_bed_bottom", + burntime = 13, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "beds:bed_bottom", + burntime = 12, +}) diff --git a/mods/beds/functions.lua b/mods/beds/functions.lua new file mode 100644 index 0000000..f6e65df --- /dev/null +++ b/mods/beds/functions.lua @@ -0,0 +1,261 @@ +local pi = math.pi +local is_sp = minetest.is_singleplayer() +local enable_respawn = minetest.settings:get_bool("enable_bed_respawn") +if enable_respawn == nil then + enable_respawn = true +end + +-- support for MT game translation. +local S = beds.get_translator + +-- Helper functions + +local function get_look_yaw(pos) + local rotation = minetest.get_node(pos).param2 + if rotation > 3 then + rotation = rotation % 4 -- Mask colorfacedir values + end + if rotation == 1 then + return pi / 2, rotation + elseif rotation == 3 then + return -pi / 2, rotation + elseif rotation == 0 then + return pi, rotation + else + return 0, rotation + end +end + +local function is_night_skip_enabled() + local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip") + if enable_night_skip == nil then + enable_night_skip = true + end + return enable_night_skip +end + +local function check_in_beds(players) + local in_bed = beds.player + if not players then + players = minetest.get_connected_players() + end + + for n, player in ipairs(players) do + local name = player:get_player_name() + if not in_bed[name] then + return false + end + end + + return #players > 0 +end + +local function lay_down(player, pos, bed_pos, state, skip) + local name = player:get_player_name() + local hud_flags = player:hud_get_flags() + + if not player or not name then + return + end + + -- stand up + if state ~= nil and not state then + if not beds.player[name] then + return + end + local p = beds.pos[name] or nil + beds.bed_position[name] = nil + -- skip here to prevent sending player specific changes (used for leaving players) + if skip then + return + end + if p then + player:set_pos(p) + end + + -- physics, eye_offset, etc + player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0}) + player:set_look_horizontal(math.random(1, 180) / 100) + default.player_attached[name] = false + player:set_physics_override(beds.player[name]) + hud_flags.wielditem = true + default.player_set_animation(player, "stand" , 30) + beds.player[name] = nil + + -- lay down + else + beds.pos[name] = pos + beds.bed_position[name] = bed_pos + beds.player[name] = player:get_physics_override() + + -- physics, eye_offset, etc + player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0}) + local yaw, param2 = get_look_yaw(bed_pos) + player:set_look_horizontal(yaw) + local dir = minetest.facedir_to_dir(param2) + -- p.y is just above the nodebox height of the 'Simple Bed' (the highest bed), + -- to avoid sinking down through the bed. + local p = { + x = bed_pos.x + dir.x / 2, + y = bed_pos.y + 0.07, + z = bed_pos.z + dir.z / 2 + } + player:set_physics_override(0, 0, 0) + player:set_pos(p) + default.player_attached[name] = true + hud_flags.wielditem = false + default.player_set_animation(player, "lay" , 0) + end + + player:hud_set_flags(hud_flags) +end + +local function get_player_in_bed_count() + local c = 0 + for _, _ in pairs(beds.player) do + c = c + 1 + end + return c +end + +local function update_formspecs(finished) + local ges = #minetest.get_connected_players() + local player_in_bed = get_player_in_bed_count() + local is_majority = (ges / 2) < player_in_bed + + local form_n + local esc = minetest.formspec_escape + if finished then + form_n = beds.formspec .. "label[2.7,9;" .. esc(S("Good morning.")) .. "]" + else + form_n = beds.formspec .. "label[2.2,9;" .. + esc(S("@1 of @2 players are in bed", player_in_bed, ges)) .. "]" + if is_majority and is_night_skip_enabled() then + form_n = form_n .. "button_exit[2,6;4,0.75;force;" .. + esc(S("Force night skip")) .. "]" + end + end + + for name,_ in pairs(beds.player) do + minetest.show_formspec(name, "beds_form", form_n) + end +end + + +-- Public functions + +function beds.kick_players() + for name, _ in pairs(beds.player) do + local player = minetest.get_player_by_name(name) + lay_down(player, nil, nil, false) + end +end + +function beds.skip_night() + minetest.set_timeofday(0.23) +end + +function beds.on_rightclick(pos, player) + local name = player:get_player_name() + local ppos = player:get_pos() + local tod = minetest.get_timeofday() + + if tod > 0.2 and tod < 0.805 then + if beds.player[name] then + lay_down(player, nil, nil, false) + end + minetest.chat_send_player(name, S("You can only sleep at night.")) + return + end + + -- move to bed + if not beds.player[name] then + lay_down(player, ppos, pos) + beds.set_spawns() -- save respawn positions when entering bed + else + lay_down(player, nil, nil, false) + end + + if not is_sp then + update_formspecs(false) + end + + -- skip the night and let all players stand up + if check_in_beds() then + minetest.after(2, function() + if not is_sp then + update_formspecs(is_night_skip_enabled()) + end + if is_night_skip_enabled() then + beds.skip_night() + beds.kick_players() + end + end) + end +end + +function beds.can_dig(bed_pos) + -- Check all players in bed which one is at the expected position + for _, player_bed_pos in pairs(beds.bed_position) do + if vector.equals(bed_pos, player_bed_pos) then + return false + end + end + return true +end + +-- Callbacks +-- Only register respawn callback if respawn enabled +if enable_respawn then + -- respawn player at bed if enabled and valid position is found + minetest.register_on_respawnplayer(function(player) + local name = player:get_player_name() + local pos = beds.spawn[name] + if pos then + player:set_pos(pos) + return true + end + end) +end + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + lay_down(player, nil, nil, false, true) + beds.player[name] = nil + if check_in_beds() then + minetest.after(2, function() + update_formspecs(is_night_skip_enabled()) + if is_night_skip_enabled() then + beds.skip_night() + beds.kick_players() + end + end) + end +end) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "beds_form" then + return + end + + -- Because "Force night skip" button is a button_exit, it will set fields.quit + -- and lay_down call will change value of player_in_bed, so it must be taken + -- earlier. + local last_player_in_bed = get_player_in_bed_count() + + if fields.quit or fields.leave then + lay_down(player, nil, nil, false) + update_formspecs(false) + end + + if fields.force then + local is_majority = (#minetest.get_connected_players() / 2) < last_player_in_bed + if is_majority and is_night_skip_enabled() then + update_formspecs(true) + beds.skip_night() + beds.kick_players() + else + update_formspecs(false) + end + end +end) diff --git a/mods/beds/init.lua b/mods/beds/init.lua new file mode 100644 index 0000000..a1a46ce --- /dev/null +++ b/mods/beds/init.lua @@ -0,0 +1,26 @@ +-- beds/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("beds") +local esc = minetest.formspec_escape + +beds = {} +beds.player = {} +beds.bed_position = {} +beds.pos = {} +beds.spawn = {} +beds.get_translator = S + +beds.formspec = "size[8,11;true]" .. + "no_prepend[]" .. + "bgcolor[#080808BB;true]" .. + "button_exit[2,10;4,0.75;leave;" .. esc(S("Leave Bed")) .. "]" + +local modpath = minetest.get_modpath("beds") + +-- Load files + +dofile(modpath .. "/functions.lua") +dofile(modpath .. "/api.lua") +dofile(modpath .. "/beds.lua") +dofile(modpath .. "/spawns.lua") diff --git a/mods/beds/license.txt b/mods/beds/license.txt new file mode 100644 index 0000000..f3c517f --- /dev/null +++ b/mods/beds/license.txt @@ -0,0 +1,61 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2014-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2018 TumeniNodes + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/beds/locale/beds.de.tr b/mods/beds/locale/beds.de.tr new file mode 100644 index 0000000..e77f654 --- /dev/null +++ b/mods/beds/locale/beds.de.tr @@ -0,0 +1,8 @@ +# textdomain: beds +Fancy Bed=Schickes Bett +Simple Bed=Schlichtes Bett +Leave Bed=Bett verlassen +Good morning.=Guten Morgen. +@1 of @2 players are in bed=@1 von @2 Spielern sind im Bett +Force night skip=Ãœberspringen der Nacht erzwingen +You can only sleep at night.=Sie können nur nachts schlafen. diff --git a/mods/beds/locale/beds.es.tr b/mods/beds/locale/beds.es.tr new file mode 100644 index 0000000..0543e7f --- /dev/null +++ b/mods/beds/locale/beds.es.tr @@ -0,0 +1,8 @@ +# textdomain: beds +Fancy Bed=Cama de lujo +Simple Bed=Cama sencilla +Leave Bed=Abandonar cama +Good morning.=Buenos días. +@1 of @2 players are in bed=@1 de @2 jugadores están en cama +Force night skip=Forzar evitar noche +You can only sleep at night.=Sólo puedes dormir por la noche. diff --git a/mods/beds/locale/beds.fr.tr b/mods/beds/locale/beds.fr.tr new file mode 100644 index 0000000..bddf9b5 --- /dev/null +++ b/mods/beds/locale/beds.fr.tr @@ -0,0 +1,8 @@ +# textdomain: beds +Fancy Bed=Lit chic +Simple Bed=Lit simple +Leave Bed=Se lever du lit +Good morning.=Bonjour. +@1 of @2 players are in bed=@1 joueur(s) sur @2 sont au lit +Force night skip=Forcer le passage de la nuit +You can only sleep at night.=Vous ne pouvez dormir que la nuit. diff --git a/mods/beds/locale/beds.it.tr b/mods/beds/locale/beds.it.tr new file mode 100644 index 0000000..3dbc70c --- /dev/null +++ b/mods/beds/locale/beds.it.tr @@ -0,0 +1,4 @@ +# textdomain: beds +Fancy Bed=Letto decorato +Simple Bed=Letto semplice +Leave Bed=Alzati dal letto \ No newline at end of file diff --git a/mods/beds/locale/beds.ms.tr b/mods/beds/locale/beds.ms.tr new file mode 100644 index 0000000..797e3a6 --- /dev/null +++ b/mods/beds/locale/beds.ms.tr @@ -0,0 +1,8 @@ +# textdomain: beds +Fancy Bed=Katil Beragam +Simple Bed=Katil Biasa +Leave Bed=Bangun +Good morning.=Selamat pagi. +@1 of @2 players are in bed=@1 daripada @2 pemain sedang tidur +Force night skip=Paksa langkau malam +You can only sleep at night.=Anda hanya boleh tidur pada waktu malam. diff --git a/mods/beds/locale/beds.ru.tr b/mods/beds/locale/beds.ru.tr new file mode 100644 index 0000000..1974b3d --- /dev/null +++ b/mods/beds/locale/beds.ru.tr @@ -0,0 +1,8 @@ +# textdomain: beds +Fancy Bed=Ð”ÐµÑ‚Ð°Ð»Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ ÐšÑ€Ð¾Ð²Ð°Ñ‚ÑŒ +Simple Bed=ÐžÐ±Ñ‹Ñ‡Ð½Ð°Ñ ÐšÑ€Ð¾Ð²Ð°Ñ‚ÑŒ +Leave Bed=Ð’Ñтать Ñ ÐºÑ€Ð¾Ð²Ð°Ñ‚Ð¸ +Good morning.=Доброе утро. +@1 of @2 players are in bed=@1 из @2 игроков в кровати +Force night skip=ПропуÑтить ночь +You can only sleep at night.=Ð’Ñ‹ можете Ñпать только ночью. diff --git a/mods/beds/locale/beds.se.tr b/mods/beds/locale/beds.se.tr new file mode 100644 index 0000000..53f4f2d --- /dev/null +++ b/mods/beds/locale/beds.se.tr @@ -0,0 +1,8 @@ +# textdomain: beds +Fancy Bed=Fin säng +Simple Bed=Enkel Säng +Leave Bed=Lämna Säng +Good morning.= God morgon. +@1 of @2 players are in bed=@1 av @2 spelar försöker sover. +Force night skip=Tvinga över natten +You can only sleep at night.=Du kan bara sova pÃ¥ natten. diff --git a/mods/beds/locale/beds.zh_CN.tr b/mods/beds/locale/beds.zh_CN.tr new file mode 100644 index 0000000..609524d --- /dev/null +++ b/mods/beds/locale/beds.zh_CN.tr @@ -0,0 +1,8 @@ +# textdomain: beds +Fancy Bed=花å¼åºŠ +Simple Bed=简易床 +Leave Bed=离开床 +Good morning.=æ—©å®‰ï¼ +@1 of @2 players are in bed=@2ä½çŽ©å®¶ä¸­çš„@1ä½åœ¨åºŠä¸Š +Force night skip=强制跳过夜晚 +You can only sleep at night.=ä½ åªèƒ½åœ¨æ™šä¸Šç¡è§‰ã€‚ diff --git a/mods/beds/locale/beds.zh_TW.tr b/mods/beds/locale/beds.zh_TW.tr new file mode 100644 index 0000000..4e7d687 --- /dev/null +++ b/mods/beds/locale/beds.zh_TW.tr @@ -0,0 +1,9 @@ +# textdomain: beds +Fancy Bed=花å¼åºŠ +Simple Bed=簡易床 +Leave Bed=離開床 +Good morning.=æ—©å®‰ï¼ +@1 of @2 players are in bed=@2ä½çŽ©å®¶ä¸­çš„@1ä½åœ¨åºŠä¸Š +Force night skip=強制跳éŽå¤œæ™š +You can only sleep at night.=ä½ åªèƒ½åœ¨æ™šä¸Šç¡è¦ºã€‚ + diff --git a/mods/beds/locale/template.txt b/mods/beds/locale/template.txt new file mode 100644 index 0000000..518fdbf --- /dev/null +++ b/mods/beds/locale/template.txt @@ -0,0 +1,8 @@ +# textdomain: beds +Fancy Bed= +Simple Bed= +Leave Bed= +Good morning.= +@1 of @2 players are in bed= +Force night skip= +You can only sleep at night.= diff --git a/mods/beds/mod.conf b/mods/beds/mod.conf new file mode 100644 index 0000000..450ec13 --- /dev/null +++ b/mods/beds/mod.conf @@ -0,0 +1,3 @@ +name = beds +description = Minetest Game mod: beds +depends = default, wool diff --git a/mods/beds/spawns.lua b/mods/beds/spawns.lua new file mode 100644 index 0000000..1a2ce81 --- /dev/null +++ b/mods/beds/spawns.lua @@ -0,0 +1,72 @@ +local world_path = minetest.get_worldpath() +local org_file = world_path .. "/beds_spawns" +local file = world_path .. "/beds_spawns" +local bkwd = false + +-- check for PA's beds mod spawns +local cf = io.open(world_path .. "/beds_player_spawns", "r") +if cf ~= nil then + io.close(cf) + file = world_path .. "/beds_player_spawns" + bkwd = true +end + +function beds.read_spawns() + local spawns = beds.spawn + local input = io.open(file, "r") + if input and not bkwd then + repeat + local x = input:read("*n") + if x == nil then + break + end + local y = input:read("*n") + local z = input:read("*n") + local name = input:read("*l") + spawns[name:sub(2)] = {x = x, y = y, z = z} + until input:read(0) == nil + io.close(input) + elseif input and bkwd then + beds.spawn = minetest.deserialize(input:read("*all")) + input:close() + beds.save_spawns() + os.rename(file, file .. ".backup") + file = org_file + end +end + +beds.read_spawns() + +function beds.save_spawns() + if not beds.spawn then + return + end + local data = {} + local output = io.open(org_file, "w") + for k, v in pairs(beds.spawn) do + table.insert(data, string.format("%.1f %.1f %.1f %s\n", v.x, v.y, v.z, k)) + end + output:write(table.concat(data)) + io.close(output) +end + +function beds.set_spawns() + for name,_ in pairs(beds.player) do + local player = minetest.get_player_by_name(name) + local p = player:get_pos() + -- but don't change spawn location if borrowing a bed + if not minetest.is_protected(p, name) then + beds.spawn[name] = p + end + end + beds.save_spawns() +end + +function beds.remove_spawns_at(pos) + for name, p in pairs(beds.spawn) do + if vector.equals(vector.round(p), pos) then + beds.spawn[name] = nil + end + end + beds.save_spawns() +end diff --git a/mods/beds/textures/beds_bed.png b/mods/beds/textures/beds_bed.png new file mode 100644 index 0000000..5c0054c Binary files /dev/null and b/mods/beds/textures/beds_bed.png differ diff --git a/mods/beds/textures/beds_bed_fancy.png b/mods/beds/textures/beds_bed_fancy.png new file mode 100644 index 0000000..4f9e8a7 Binary files /dev/null and b/mods/beds/textures/beds_bed_fancy.png differ diff --git a/mods/beds/textures/beds_bed_foot.png b/mods/beds/textures/beds_bed_foot.png new file mode 100644 index 0000000..74d84c8 Binary files /dev/null and b/mods/beds/textures/beds_bed_foot.png differ diff --git a/mods/beds/textures/beds_bed_head.png b/mods/beds/textures/beds_bed_head.png new file mode 100644 index 0000000..763f5e1 Binary files /dev/null and b/mods/beds/textures/beds_bed_head.png differ diff --git a/mods/beds/textures/beds_bed_side1.png b/mods/beds/textures/beds_bed_side1.png new file mode 100644 index 0000000..1ed8158 Binary files /dev/null and b/mods/beds/textures/beds_bed_side1.png differ diff --git a/mods/beds/textures/beds_bed_side2.png b/mods/beds/textures/beds_bed_side2.png new file mode 100644 index 0000000..9d1384d Binary files /dev/null and b/mods/beds/textures/beds_bed_side2.png differ diff --git a/mods/beds/textures/beds_bed_side_bottom.png b/mods/beds/textures/beds_bed_side_bottom.png new file mode 100644 index 0000000..99ff309 Binary files /dev/null and b/mods/beds/textures/beds_bed_side_bottom.png differ diff --git a/mods/beds/textures/beds_bed_side_bottom_r.png b/mods/beds/textures/beds_bed_side_bottom_r.png new file mode 100644 index 0000000..6f870e8 Binary files /dev/null and b/mods/beds/textures/beds_bed_side_bottom_r.png differ diff --git a/mods/beds/textures/beds_bed_side_top.png b/mods/beds/textures/beds_bed_side_top.png new file mode 100644 index 0000000..b2807c5 Binary files /dev/null and b/mods/beds/textures/beds_bed_side_top.png differ diff --git a/mods/beds/textures/beds_bed_side_top_r.png b/mods/beds/textures/beds_bed_side_top_r.png new file mode 100644 index 0000000..429ad7d Binary files /dev/null and b/mods/beds/textures/beds_bed_side_top_r.png differ diff --git a/mods/beds/textures/beds_bed_top1.png b/mods/beds/textures/beds_bed_top1.png new file mode 100644 index 0000000..b6fcc2c Binary files /dev/null and b/mods/beds/textures/beds_bed_top1.png differ diff --git a/mods/beds/textures/beds_bed_top2.png b/mods/beds/textures/beds_bed_top2.png new file mode 100644 index 0000000..2fe5bf2 Binary files /dev/null and b/mods/beds/textures/beds_bed_top2.png differ diff --git a/mods/beds/textures/beds_bed_top_bottom.png b/mods/beds/textures/beds_bed_top_bottom.png new file mode 100644 index 0000000..9b78be6 Binary files /dev/null and b/mods/beds/textures/beds_bed_top_bottom.png differ diff --git a/mods/beds/textures/beds_bed_top_top.png b/mods/beds/textures/beds_bed_top_top.png new file mode 100644 index 0000000..e877c80 Binary files /dev/null and b/mods/beds/textures/beds_bed_top_top.png differ diff --git a/mods/beds/textures/beds_bed_under.png b/mods/beds/textures/beds_bed_under.png new file mode 100644 index 0000000..a930115 Binary files /dev/null and b/mods/beds/textures/beds_bed_under.png differ diff --git a/mods/beds/textures/beds_transparent.png b/mods/beds/textures/beds_transparent.png new file mode 100644 index 0000000..2dc0e3d Binary files /dev/null and b/mods/beds/textures/beds_transparent.png differ diff --git a/mods/binoculars/README.txt b/mods/binoculars/README.txt new file mode 100644 index 0000000..0c65f6e --- /dev/null +++ b/mods/binoculars/README.txt @@ -0,0 +1,37 @@ +Minetest Game mod: binoculars +============================= +See license.txt for license information. + +Authors of source code +---------------------- +paramat (MIT) + +Authors of media (textures) +--------------------------- +paramat (CC BY-SA 3.0): + binoculars_binoculars.png + +Crafting +-------- +binoculars:binoculars + +default:obsidian_glass O +default:bronze_ingot B + +O_O +BBB +O_O + +Usage +----- +In survival mode, use of zoom requires the binoculars item in your inventory, +they will allow a 10 degree field of view. +It can take up to 5 seconds for adding to or removal from inventory to have an +effect, however to instantly allow the use of this zoom 'use' (leftclick) the +item. + +Zoom with a field of view of 15 degrees is automatically allowed in creative +mode and for any player with the 'creative' privilege. + +The 'binoculars.update_player_property()' function is global so can be +redefined by a mod for alternative behaviour. diff --git a/mods/binoculars/init.lua b/mods/binoculars/init.lua new file mode 100644 index 0000000..7685897 --- /dev/null +++ b/mods/binoculars/init.lua @@ -0,0 +1,81 @@ +-- binoculars/init.lua + +-- Mod global namespace + +binoculars = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("binoculars") + + +-- Detect creative mod +local creative_mod = minetest.get_modpath("creative") +-- Cache creative mode setting as fallback if creative mod not present +local creative_mode_cache = minetest.settings:get_bool("creative_mode") + + +-- Update player property +-- Global to allow overriding + +function binoculars.update_player_property(player) + local creative_enabled = + (creative_mod and creative.is_enabled_for(player:get_player_name())) or + creative_mode_cache + local new_zoom_fov = 0 + + if player:get_inventory():contains_item( + "main", "binoculars:binoculars") then + new_zoom_fov = 10 + elseif creative_enabled then + new_zoom_fov = 15 + end + + -- Only set property if necessary to avoid player mesh reload + if player:get_properties().zoom_fov ~= new_zoom_fov then + player:set_properties({zoom_fov = new_zoom_fov}) + end +end + + +-- Set player property 'on joinplayer' + +minetest.register_on_joinplayer(function(player) + binoculars.update_player_property(player) +end) + + +-- Cyclic update of player property + +local function cyclic_update() + for _, player in ipairs(minetest.get_connected_players()) do + binoculars.update_player_property(player) + end + minetest.after(4.7, cyclic_update) +end + +minetest.after(4.7, cyclic_update) + + +-- Binoculars item + +minetest.register_craftitem("binoculars:binoculars", { + description = S("Binoculars") .. "\n" .. S("Use with 'Zoom' key"), + inventory_image = "binoculars_binoculars.png", + stack_max = 1, + + on_use = function(itemstack, user, pointed_thing) + binoculars.update_player_property(user) + end, +}) + + +-- Crafting + +minetest.register_craft({ + output = "binoculars:binoculars", + recipe = { + {"default:obsidian_glass", "", "default:obsidian_glass"}, + {"default:bronze_ingot", "default:bronze_ingot", "default:bronze_ingot"}, + {"default:obsidian_glass", "", "default:obsidian_glass"}, + } +}) diff --git a/mods/binoculars/license.txt b/mods/binoculars/license.txt new file mode 100644 index 0000000..f3aefda --- /dev/null +++ b/mods/binoculars/license.txt @@ -0,0 +1,59 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2017 paramat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2017 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/binoculars/locale/binoculars.de.tr b/mods/binoculars/locale/binoculars.de.tr new file mode 100644 index 0000000..7bd9b9d --- /dev/null +++ b/mods/binoculars/locale/binoculars.de.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=Fernglas +Use with 'Zoom' key=Mit „Zoom“-Taste benutzen diff --git a/mods/binoculars/locale/binoculars.es.tr b/mods/binoculars/locale/binoculars.es.tr new file mode 100644 index 0000000..7b7e77d --- /dev/null +++ b/mods/binoculars/locale/binoculars.es.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=Prismáticos +Use with 'Zoom' key=Usar con la tecla 'Zoom' diff --git a/mods/binoculars/locale/binoculars.fr.tr b/mods/binoculars/locale/binoculars.fr.tr new file mode 100644 index 0000000..3f8b0bc --- /dev/null +++ b/mods/binoculars/locale/binoculars.fr.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=Jumelles +Use with 'Zoom' key=Utiliser avec le bouton « Zoom » diff --git a/mods/binoculars/locale/binoculars.it.tr b/mods/binoculars/locale/binoculars.it.tr new file mode 100644 index 0000000..f8e98d6 --- /dev/null +++ b/mods/binoculars/locale/binoculars.it.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=Binocolo +Use with 'Zoom' key=Usalo col tasto 'Ingrandimento' \ No newline at end of file diff --git a/mods/binoculars/locale/binoculars.ms.tr b/mods/binoculars/locale/binoculars.ms.tr new file mode 100644 index 0000000..d38e64f --- /dev/null +++ b/mods/binoculars/locale/binoculars.ms.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=Binokular +Use with 'Zoom' key=Guna dengan kekunci 'Zum' diff --git a/mods/binoculars/locale/binoculars.ru.tr b/mods/binoculars/locale/binoculars.ru.tr new file mode 100644 index 0000000..6b3aa9e --- /dev/null +++ b/mods/binoculars/locale/binoculars.ru.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=Бинокль +Use with 'Zoom' key=ИÑпользуетÑÑ Ñ Ð¿Ñ€Ð¸Ð²Ð¸Ð»ÐµÐ³Ð¸ÐµÐ¹ 'Zoom' diff --git a/mods/binoculars/locale/binoculars.se.tr b/mods/binoculars/locale/binoculars.se.tr new file mode 100644 index 0000000..291afd5 --- /dev/null +++ b/mods/binoculars/locale/binoculars.se.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=Kikare +Use with 'Zoom' key=Används med 'Zoom' knappen \ No newline at end of file diff --git a/mods/binoculars/locale/binoculars.zh_CN.tr b/mods/binoculars/locale/binoculars.zh_CN.tr new file mode 100644 index 0000000..ec46cf8 --- /dev/null +++ b/mods/binoculars/locale/binoculars.zh_CN.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=望远镜 +Use with 'Zoom' key=与“缩放â€é”®ä¸€èµ·ä½¿ç”¨ diff --git a/mods/binoculars/locale/binoculars.zh_TW.tr b/mods/binoculars/locale/binoculars.zh_TW.tr new file mode 100644 index 0000000..bbe3b39 --- /dev/null +++ b/mods/binoculars/locale/binoculars.zh_TW.tr @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars=望é é¡ +Use with 'Zoom' key=與“縮放â€éµä¸€èµ·ä½¿ç”¨ diff --git a/mods/binoculars/locale/template.txt b/mods/binoculars/locale/template.txt new file mode 100644 index 0000000..a526462 --- /dev/null +++ b/mods/binoculars/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: binoculars +Binoculars= +Use with 'Zoom' key= diff --git a/mods/binoculars/mod.conf b/mods/binoculars/mod.conf new file mode 100644 index 0000000..7d73741 --- /dev/null +++ b/mods/binoculars/mod.conf @@ -0,0 +1,4 @@ +name = binoculars +description = Minetest Game mod: binoculars +depends = default +optional_depends = creative diff --git a/mods/binoculars/textures/binoculars_binoculars.png b/mods/binoculars/textures/binoculars_binoculars.png new file mode 100644 index 0000000..5803d48 Binary files /dev/null and b/mods/binoculars/textures/binoculars_binoculars.png differ diff --git a/mods/boats/README.txt b/mods/boats/README.txt new file mode 100644 index 0000000..a2ccb48 --- /dev/null +++ b/mods/boats/README.txt @@ -0,0 +1,31 @@ +Minetest Game mod: boats +======================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by PilzAdam (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures and model) +------------------------------------- +Textures: Zeg9 (CC BY-SA 3.0) +Model: thetoon and Zeg9 (CC BY-SA 3.0), + modified by PavelS(SokolovPavel) (CC BY-SA 3.0), + modified by sofar (CC BY-SA 3.0) + +Controls +-------- +Right mouse button = Enter or exit boat when pointing at boat. +Forward = Speed up. + Slow down when moving backwards. +Forward + backward = Enable cruise mode: Boat will accelerate to maximum forward + speed and remain at that speed without needing to hold the + forward key. +Backward = Slow down. + Speed up when moving backwards. + Disable cruise mode. +Left = Turn to the left. + Turn to the right when moving backwards. +Right = Turn to the right. + Turn to the left when moving backwards. diff --git a/mods/boats/init.lua b/mods/boats/init.lua new file mode 100644 index 0000000..f9ae8e0 --- /dev/null +++ b/mods/boats/init.lua @@ -0,0 +1,294 @@ +-- boats/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("boats") + +-- +-- Helper functions +-- + +local function is_water(pos) + local nn = minetest.get_node(pos).name + return minetest.get_item_group(nn, "water") ~= 0 +end + + +local function get_velocity(v, yaw, y) + local x = -math.sin(yaw) * v + local z = math.cos(yaw) * v + return {x = x, y = y, z = z} +end + + +local function get_v(v) + return math.sqrt(v.x ^ 2 + v.z ^ 2) +end + +-- +-- Boat entity +-- + +local boat = { + initial_properties = { + physical = true, + -- Warning: Do not change the position of the collisionbox top surface, + -- lowering it causes the boat to fall through the world if underwater + collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, + visual = "mesh", + mesh = "boats_boat.obj", + textures = {"default_wood.png"}, + }, + + driver = nil, + v = 0, + last_v = 0, + removed = false, + auto = false +} + + +function boat.on_rightclick(self, clicker) + if not clicker or not clicker:is_player() then + return + end + local name = clicker:get_player_name() + if self.driver and name == self.driver then + self.driver = nil + self.auto = false + clicker:set_detach() + player_api.player_attached[name] = false + player_api.set_animation(clicker, "stand" , 30) + local pos = clicker:get_pos() + pos = {x = pos.x, y = pos.y + 0.2, z = pos.z} + minetest.after(0.1, function() + clicker:set_pos(pos) + end) + elseif not self.driver then + local attach = clicker:get_attach() + if attach and attach:get_luaentity() then + local luaentity = attach:get_luaentity() + if luaentity.driver then + luaentity.driver = nil + end + clicker:set_detach() + end + self.driver = name + clicker:set_attach(self.object, "", + {x = 0.5, y = 1, z = -3}, {x = 0, y = 0, z = 0}) + player_api.player_attached[name] = true + minetest.after(0.2, function() + player_api.set_animation(clicker, "sit" , 30) + end) + clicker:set_look_horizontal(self.object:get_yaw()) + end +end + + +-- If driver leaves server while driving boat +function boat.on_detach_child(self, child) + self.driver = nil + self.auto = false +end + + +function boat.on_activate(self, staticdata, dtime_s) + self.object:set_armor_groups({immortal = 1}) + if staticdata then + self.v = tonumber(staticdata) + end + self.last_v = self.v +end + + +function boat.get_staticdata(self) + return tostring(self.v) +end + + +function boat.on_punch(self, puncher) + if not puncher or not puncher:is_player() or self.removed then + return + end + + local name = puncher:get_player_name() + if self.driver and name == self.driver then + self.driver = nil + puncher:set_detach() + player_api.player_attached[name] = false + end + if not self.driver then + self.removed = true + local inv = puncher:get_inventory() + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(name)) + or not inv:contains_item("main", "boats:boat") then + local leftover = inv:add_item("main", "boats:boat") + -- if no room in inventory add a replacement boat to the world + if not leftover:is_empty() then + minetest.add_item(self.object:get_pos(), leftover) + end + end + -- delay remove to ensure player is detached + minetest.after(0.1, function() + self.object:remove() + end) + end +end + + +function boat.on_step(self, dtime) + self.v = get_v(self.object:get_velocity()) * math.sign(self.v) + if self.driver then + local driver_objref = minetest.get_player_by_name(self.driver) + if driver_objref then + local ctrl = driver_objref:get_player_control() + if ctrl.up and ctrl.down then + if not self.auto then + self.auto = true + minetest.chat_send_player(self.driver, S("Boat cruise mode on")) + end + elseif ctrl.down then + self.v = self.v - dtime * 2.0 + if self.auto then + self.auto = false + minetest.chat_send_player(self.driver, S("Boat cruise mode off")) + end + elseif ctrl.up or self.auto then + self.v = self.v + dtime * 2.0 + end + if ctrl.left then + if self.v < -0.001 then + self.object:set_yaw(self.object:get_yaw() - dtime * 0.9) + else + self.object:set_yaw(self.object:get_yaw() + dtime * 0.9) + end + elseif ctrl.right then + if self.v < -0.001 then + self.object:set_yaw(self.object:get_yaw() + dtime * 0.9) + else + self.object:set_yaw(self.object:get_yaw() - dtime * 0.9) + end + end + end + end + local velo = self.object:get_velocity() + if self.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then + self.object:set_pos(self.object:get_pos()) + return + end + -- We need to preserve velocity sign to properly apply drag force + -- while moving backward + local drag = dtime * math.sign(self.v) * (0.01 + 0.0796 * self.v * self.v) + -- If drag is larger than velocity, then stop horizontal movement + if math.abs(self.v) <= math.abs(drag) then + self.v = 0 + else + self.v = self.v - drag + end + + local p = self.object:get_pos() + p.y = p.y - 0.5 + local new_velo + local new_acce = {x = 0, y = 0, z = 0} + if not is_water(p) then + local nodedef = minetest.registered_nodes[minetest.get_node(p).name] + if (not nodedef) or nodedef.walkable then + self.v = 0 + new_acce = {x = 0, y = 1, z = 0} + else + new_acce = {x = 0, y = -9.8, z = 0} + end + new_velo = get_velocity(self.v, self.object:get_yaw(), + self.object:get_velocity().y) + self.object:set_pos(self.object:get_pos()) + else + p.y = p.y + 1 + if is_water(p) then + local y = self.object:get_velocity().y + if y >= 5 then + y = 5 + elseif y < 0 then + new_acce = {x = 0, y = 20, z = 0} + else + new_acce = {x = 0, y = 5, z = 0} + end + new_velo = get_velocity(self.v, self.object:get_yaw(), y) + self.object:set_pos(self.object:get_pos()) + else + new_acce = {x = 0, y = 0, z = 0} + if math.abs(self.object:get_velocity().y) < 1 then + local pos = self.object:get_pos() + pos.y = math.floor(pos.y) + 0.5 + self.object:set_pos(pos) + new_velo = get_velocity(self.v, self.object:get_yaw(), 0) + else + new_velo = get_velocity(self.v, self.object:get_yaw(), + self.object:get_velocity().y) + self.object:set_pos(self.object:get_pos()) + end + end + end + self.object:set_velocity(new_velo) + self.object:set_acceleration(new_acce) +end + + +minetest.register_entity("boats:boat", boat) + + +minetest.register_craftitem("boats:boat", { + description = S("Boat"), + inventory_image = "boats_inventory.png", + wield_image = "boats_wield.png", + wield_scale = {x = 2, y = 2, z = 1}, + liquids_pointable = true, + groups = {flammable = 2}, + + 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:is_player() and + placer:get_player_control().sneak) then + return udef.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + + if pointed_thing.type ~= "node" then + return itemstack + end + if not is_water(pointed_thing.under) then + return itemstack + end + pointed_thing.under.y = pointed_thing.under.y + 0.5 + boat = minetest.add_entity(pointed_thing.under, "boats:boat") + if boat then + if placer then + boat:set_yaw(placer:get_look_horizontal()) + end + local player_name = placer and placer:get_player_name() or "" + if not (creative and creative.is_enabled_for and + creative.is_enabled_for(player_name)) then + itemstack:take_item() + end + end + return itemstack + end, +}) + + +minetest.register_craft({ + output = "boats:boat", + recipe = { + {"", "", "" }, + {"group:wood", "", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + }, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "boats:boat", + burntime = 20, +}) diff --git a/mods/boats/license.txt b/mods/boats/license.txt new file mode 100644 index 0000000..d4afe75 --- /dev/null +++ b/mods/boats/license.txt @@ -0,0 +1,63 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures and model) +-------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Zeg9 +Copyright (C) 2012-2016 thetoon +Copyright (C) 2012-2016 PavelS(SokolovPavel) +Copyright (C) 2016 sofar (sofar@foo-projects.org) + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/boats/locale/boats.de.tr b/mods/boats/locale/boats.de.tr new file mode 100644 index 0000000..d8eb8d7 --- /dev/null +++ b/mods/boats/locale/boats.de.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=Schneller Bootsmodus an +Boat cruise mode off=Schneller Bootsmodus aus +Boat=Boot diff --git a/mods/boats/locale/boats.es.tr b/mods/boats/locale/boats.es.tr new file mode 100644 index 0000000..b9adb72 --- /dev/null +++ b/mods/boats/locale/boats.es.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=Modo crucero en bote activado +Boat cruise mode off=Modo crucero en bote desactivado +Boat=Bote diff --git a/mods/boats/locale/boats.fr.tr b/mods/boats/locale/boats.fr.tr new file mode 100644 index 0000000..f469a0b --- /dev/null +++ b/mods/boats/locale/boats.fr.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=Bateau mode rapide activé +Boat cruise mode off=Bateau mode rapide désactivé +Boat=Bateau diff --git a/mods/boats/locale/boats.it.tr b/mods/boats/locale/boats.it.tr new file mode 100644 index 0000000..5bd7125 --- /dev/null +++ b/mods/boats/locale/boats.it.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=Modalità movimento automatico barca attivata +Boat cruise mode off=Modalità movimento automatico barca disattivata +Boat=Barca \ No newline at end of file diff --git a/mods/boats/locale/boats.ms.tr b/mods/boats/locale/boats.ms.tr new file mode 100644 index 0000000..d11a68b --- /dev/null +++ b/mods/boats/locale/boats.ms.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=Mod bot layar makan angin dibolehkan +Boat cruise mode off=Mod bot layar makan angin dilumpuhkan +Boat=Bot diff --git a/mods/boats/locale/boats.ru.tr b/mods/boats/locale/boats.ru.tr new file mode 100644 index 0000000..4327098 --- /dev/null +++ b/mods/boats/locale/boats.ru.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=Режим путешеÑÑ‚Ð²Ð¸Ñ Ð½Ð° лодке включен +Boat cruise mode off=Режим путешеÑÑ‚Ð²Ð¸Ñ Ð½Ð° лодке выключен +Boat=Лодка diff --git a/mods/boats/locale/boats.se.tr b/mods/boats/locale/boats.se.tr new file mode 100644 index 0000000..4ca7c80 --- /dev/null +++ b/mods/boats/locale/boats.se.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=BÃ¥tkryssningsläge pÃ¥ +Boat cruise mode off=BÃ¥tkryssningsläge av +Boat=BÃ¥t \ No newline at end of file diff --git a/mods/boats/locale/boats.zh_CN.tr b/mods/boats/locale/boats.zh_CN.tr new file mode 100644 index 0000000..254f2df --- /dev/null +++ b/mods/boats/locale/boats.zh_CN.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=巡航模å¼å¼€å¯ +Boat cruise mode off=巡航模å¼å…³é—­ +Boat=船 diff --git a/mods/boats/locale/boats.zh_TW.tr b/mods/boats/locale/boats.zh_TW.tr new file mode 100644 index 0000000..97b3471 --- /dev/null +++ b/mods/boats/locale/boats.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on=巡航模å¼é–‹å•Ÿ +Boat cruise mode off=巡航模å¼é—œé–‰ +Boat=船 diff --git a/mods/boats/locale/template.txt b/mods/boats/locale/template.txt new file mode 100644 index 0000000..17aedc8 --- /dev/null +++ b/mods/boats/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: boats +Boat cruise mode on= +Boat cruise mode off= +Boat= diff --git a/mods/boats/mod.conf b/mods/boats/mod.conf new file mode 100644 index 0000000..a727f8f --- /dev/null +++ b/mods/boats/mod.conf @@ -0,0 +1,3 @@ +name = boats +description = Minetest Game mod: boats +depends = default, player_api diff --git a/mods/boats/models/boats_boat.obj b/mods/boats/models/boats_boat.obj new file mode 100644 index 0000000..0f21e47 --- /dev/null +++ b/mods/boats/models/boats_boat.obj @@ -0,0 +1,358 @@ +# Blender v2.76 (sub 11) OBJ File: 'boat.blend' +# www.blender.org +mtllib boat.mtl +o boats_boat +v -6.786140 -3.033999 -9.415440 +v -6.786140 -1.967150 -9.415440 +v -6.786140 -1.967150 8.793510 +v -6.786140 -3.033999 8.793510 +v 5.732520 -1.967150 -9.415440 +v 5.732520 -3.033999 -9.415440 +v 5.732520 -3.033999 8.793510 +v 5.732520 -1.967150 8.793510 +v -2.233900 -3.033999 -9.415440 +v -2.233900 -1.967150 -9.415440 +v -2.233900 -1.967150 8.793510 +v -2.233900 -3.033999 8.793510 +v 2.318340 -3.033999 -9.415440 +v 2.318340 -1.967150 -9.415440 +v 2.318340 -1.967150 8.793510 +v 2.318340 -3.033999 8.793510 +v -3.371960 -3.033999 8.793510 +v -3.371960 -1.967150 8.793510 +v -3.371960 -1.967150 -9.415440 +v -3.371960 -3.033999 -9.415440 +v 2.318340 0.276645 8.793510 +v 1.180280 -1.967150 8.793510 +v 5.732520 0.276645 8.793510 +v 5.732520 1.039180 8.793510 +v 6.870580 0.276645 8.793510 +v 6.870580 -1.967150 8.793510 +v 2.318340 1.039180 8.793510 +v 1.180280 0.276645 8.793510 +v 1.180280 1.039180 8.793510 +v 1.180280 -3.033999 8.793510 +v -2.233900 0.276645 8.793510 +v -3.371960 0.276645 8.793510 +v -2.233900 1.039180 8.793510 +v -3.371960 1.039180 8.793510 +v -6.786140 0.276645 8.793510 +v -7.786200 0.276645 8.793510 +v -7.786200 -1.967150 8.793510 +v -6.786140 1.039180 8.793510 +v 1.180280 -1.967150 -9.415440 +v 1.180280 -3.033999 -9.415440 +v 2.318340 0.276645 -9.415440 +v 1.180280 0.276645 -9.415440 +v 2.318340 1.039180 -9.415440 +v 5.732520 0.276645 -9.415440 +v 6.870580 -1.967150 -9.415440 +v 5.732520 1.039180 -9.415440 +v 6.870580 0.276645 -9.415440 +v 0.042220 1.039180 -9.415440 +v 1.180280 1.039180 -9.415440 +v 0.042220 -1.967150 -9.415440 +v -1.095840 -1.967150 -9.415440 +v -2.233900 0.276645 -9.415440 +v -3.371960 0.276645 -9.415440 +v -2.233900 1.039180 -9.415440 +v -1.095840 1.039180 -9.415440 +v -3.371960 1.039180 -9.415440 +v -6.786140 0.276645 -9.415440 +v -6.786140 1.039180 -9.415440 +v -7.786200 -1.967150 -9.415440 +v -7.786200 0.276645 -9.415440 +v -1.095840 0.156645 -12.044100 +v -1.095840 -4.601110 -9.415440 +v -1.095840 1.039181 -10.802900 +v -1.095840 2.868579 -10.802900 +v -1.095840 2.868580 -7.883420 +v -1.095840 3.746069 -12.034100 +v -1.095840 3.746070 -7.883420 +v -1.095840 0.156645 -14.294900 +v -1.095840 -4.601110 -14.284900 +v 0.042220 -4.601110 -14.284900 +v 0.042220 -4.601110 -9.415440 +v 0.042220 1.039181 -10.802900 +v 0.042220 0.156645 -12.044100 +v 0.042220 2.868579 -10.802900 +v 0.042220 0.156645 -14.294900 +v 0.042220 3.746069 -12.034100 +v 0.042220 3.746070 -7.883420 +v 0.042220 2.868580 -7.883420 +v -1.096322 -3.033999 -9.415440 +v 0.044046 -3.035397 -9.415440 +vt 1.000000 0.187500 +vt -1.000000 0.312500 +vt 1.000000 0.312500 +vt 0.687500 1.000000 +vt 0.500000 0.875000 +vt 0.500000 0.625000 +vt -1.000000 0.062500 +vt 1.000000 0.062500 +vt 1.000000 -0.000000 +vt -1.000000 0.125000 +vt 1.000000 0.125000 +vt 0.437500 0.125000 +vt 0.312500 0.500000 +vt 0.312500 0.125000 +vt 1.000000 0.625000 +vt -1.000000 0.500000 +vt 1.000000 0.500000 +vt 0.187500 0.687500 +vt -0.187500 0.687500 +vt -0.187500 0.312500 +vt 1.000000 0.812500 +vt -1.000000 0.937500 +vt -1.000000 0.812500 +vt 0.812500 0.687500 +vt 1.187500 0.687500 +vt 0.812500 0.312500 +vt 1.000000 0.562500 +vt 0.312500 0.437500 +vt 1.000000 0.437500 +vt 1.000000 0.750000 +vt -1.000000 0.875000 +vt -1.000000 0.750000 +vt -1.000000 1.000000 +vt 1.000000 1.000000 +vt 0.437500 0.625000 +vt 0.562500 0.437500 +vt 0.562500 0.625000 +vt -1.000000 0.437500 +vt -1.000000 0.000000 +vt 0.500000 0.062500 +vt 0.375000 0.750000 +vt 0.500000 0.750000 +vt -1.000000 0.250000 +vt -1.000000 0.687500 +vt 1.000000 0.687500 +vt 0.625000 0.375000 +vt 1.000000 0.375000 +vt 1.000000 0.250000 +vt 1.000000 0.937500 +vt 0.437500 0.812500 +vt 0.312500 0.312500 +vt 0.312500 0.812500 +vt 0.437500 0.312500 +vt 0.437500 0.437500 +vt 0.687500 0.812500 +vt 0.000000 0.687500 +vt 0.000000 0.812500 +vt -1.000000 0.562500 +vt 0.875000 0.812500 +vt 0.875000 0.687500 +vt 0.250000 0.312500 +vt 0.562500 0.187500 +vt 0.250000 0.187500 +vt -1.000000 0.187500 +vt 0.312500 0.625000 +vt 0.312500 0.187500 +vt 0.312500 -0.187500 +vt 1.000000 -0.187500 +vt 0.687500 0.500000 +vt -0.000000 1.000000 +vt 0.000000 0.875000 +vt 0.437500 0.500000 +vt -1.000000 0.625000 +vt 0.812500 0.187500 +vt 1.187500 0.187500 +vt 1.187500 0.312500 +vt 1.312500 0.312500 +vt 1.312500 0.687500 +vt 0.687500 0.187500 +vt 0.687500 0.312500 +vt 1.187500 0.812500 +vt 0.812500 0.812500 +vt 0.187500 0.312500 +vt 0.312500 0.687500 +vt 0.687500 0.687500 +vt -0.187500 0.187500 +vt 0.187500 0.187500 +vt -0.312500 0.687500 +vt -0.312500 0.312500 +vt 0.187500 0.812500 +vt -0.187500 0.812500 +vt 0.437500 0.687500 +vt 0.437500 0.187500 +vt 0.562500 0.812500 +vt 0.562500 0.687500 +vt 0.312500 0.562500 +vt 1.000000 0.875000 +vt 0.375000 0.062500 +vt -1.000000 0.375000 +vt 0.625000 0.500000 +vt 0.875000 0.562500 +vt 0.937500 0.812500 +vt 0.937500 0.687500 +vt 0.875000 0.937500 +vt 0.562500 0.312500 +vn -1.000000 0.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -0.002100 -1.000000 +vn 0.001200 -1.000000 0.000000 +vn 0.000000 0.002800 -1.000000 +vn -0.001200 -1.000000 0.000200 +g boats_boat_boats_boat_None +usemtl None +s off +f 41/1/1 27/2/1 43/3/1 +f 76/4/2 74/5/2 72/6/2 +f 8/7/2 6/1/2 5/8/2 +f 15/9/1 13/10/1 16/11/1 +f 51/12/3 71/13/3 50/14/3 +f 56/15/2 32/16/2 53/17/2 +f 15/18/3 8/19/3 23/20/3 +f 22/21/2 40/22/2 39/23/2 +f 19/24/4 2/25/4 53/26/4 +f 70/27/5 62/28/5 69/29/5 +f 11/30/5 19/31/5 10/32/5 +f 4/15/5 20/33/5 17/34/5 +f 72/35/3 64/36/3 63/37/3 +f 13/8/5 7/38/5 16/7/5 +f 23/39/6 47/11/6 44/9/6 +f 68/40/7 70/41/7 69/42/7 +f 80/43/8 40/10/8 30/11/8 +f 3/15/1 1/32/1 4/30/1 +f 20/44/2 18/27/2 17/45/2 +f 74/17/5 65/46/5 64/47/5 +f 31/43/1 54/47/1 52/48/1 +f 22/47/5 14/43/5 15/48/5 +f 46/1/2 23/7/2 44/8/2 +f 57/21/1 38/22/1 58/49/1 +f 61/50/9 76/51/9 73/52/9 +f 37/45/5 2/23/5 3/21/5 +f 78/28/3 67/53/3 65/54/3 +f 64/5/1 66/4/1 63/6/1 +f 76/55/6 67/56/6 77/57/6 +f 47/17/2 26/10/2 45/11/2 +f 5/16/5 26/47/5 8/17/5 +f 33/58/6 48/59/6 55/60/6 +f 29/38/2 42/3/2 49/29/2 +f 32/44/6 52/21/6 53/45/6 +f 58/15/6 34/33/6 56/34/6 +f 27/7/6 46/29/6 43/8/6 +f 73/61/6 68/62/6 61/63/6 +f 21/58/6 42/29/6 28/38/6 +f 11/29/1 9/58/1 12/27/1 +f 59/45/1 36/2/1 60/3/1 +f 60/9/6 35/10/6 57/11/6 +f 41/1/1 21/64/1 27/2/1 +f 72/6/2 48/65/2 50/66/2 +f 50/66/2 71/67/2 70/68/2 +f 70/68/2 75/17/2 73/69/2 +f 76/4/2 77/70/2 74/5/2 +f 77/70/2 78/71/2 74/5/2 +f 50/66/2 70/68/2 73/69/2 +f 73/69/2 76/4/2 72/6/2 +f 72/6/2 50/66/2 73/69/2 +f 8/7/2 7/64/2 6/1/2 +f 15/9/1 14/39/1 13/10/1 +f 51/12/3 62/72/3 71/13/3 +f 56/15/2 34/73/2 32/16/2 +f 32/26/3 34/74/3 38/75/3 +f 35/76/3 36/77/3 37/78/3 +f 32/26/3 38/75/3 35/76/3 +f 29/66/3 33/79/3 31/80/3 +f 32/26/3 35/76/3 3/25/3 +f 28/51/3 29/66/3 31/80/3 +f 31/80/3 32/26/3 18/24/3 +f 3/25/3 4/81/3 17/82/3 +f 35/76/3 37/78/3 3/25/3 +f 21/83/3 28/51/3 22/84/3 +f 3/25/3 17/82/3 18/24/3 +f 11/85/3 12/55/3 30/52/3 +f 32/26/3 3/25/3 18/24/3 +f 11/85/3 30/52/3 22/84/3 +f 31/80/3 18/24/3 11/85/3 +f 24/86/3 27/87/3 21/83/3 +f 28/51/3 31/80/3 11/85/3 +f 11/85/3 22/84/3 28/51/3 +f 24/86/3 21/83/3 23/20/3 +f 26/88/3 25/89/3 23/20/3 +f 23/20/3 21/83/3 15/18/3 +f 15/18/3 16/90/3 7/91/3 +f 21/83/3 22/84/3 15/18/3 +f 8/19/3 26/88/3 23/20/3 +f 15/18/3 7/91/3 8/19/3 +f 22/21/2 30/49/2 40/22/2 +f 47/89/4 45/88/4 5/19/4 +f 5/19/4 6/91/4 13/90/4 +f 5/19/4 13/90/4 14/18/4 +f 44/20/4 47/89/4 5/19/4 +f 43/87/4 46/86/4 44/20/4 +f 41/83/4 43/87/4 44/20/4 +f 44/20/4 5/19/4 14/18/4 +f 39/84/4 40/52/4 80/50/4 +f 44/20/4 14/18/4 41/83/4 +f 42/51/4 41/83/4 39/84/4 +f 39/84/4 80/50/4 50/92/4 +f 41/83/4 14/18/4 39/84/4 +f 48/93/4 49/66/4 42/51/4 +f 50/92/4 48/93/4 42/51/4 +f 80/50/4 79/94/4 50/92/4 +f 50/92/4 42/51/4 39/84/4 +f 54/79/4 55/62/4 52/80/4 +f 50/92/4 79/94/4 51/95/4 +f 52/80/4 55/62/4 51/95/4 +f 51/95/4 79/94/4 10/85/4 +f 79/94/4 9/55/4 10/85/4 +f 53/26/4 52/80/4 10/85/4 +f 58/75/4 56/74/4 53/26/4 +f 59/78/4 60/77/4 57/76/4 +f 57/76/4 58/75/4 53/26/4 +f 52/80/4 51/95/4 10/85/4 +f 19/24/4 20/82/4 1/81/4 +f 53/26/4 10/85/4 19/24/4 +f 59/78/4 57/76/4 2/25/4 +f 19/24/4 1/81/4 2/25/4 +f 2/25/4 57/76/4 53/26/4 +f 70/27/5 71/96/5 62/28/5 +f 11/30/5 18/97/5 19/31/5 +f 4/15/5 1/73/5 20/33/5 +f 72/35/3 74/54/3 64/36/3 +f 13/8/5 6/29/5 7/38/5 +f 23/39/6 25/10/6 47/11/6 +f 68/40/7 75/98/7 70/41/7 +f 30/11/5 12/17/5 79/99/5 +f 79/99/10 80/43/10 30/11/10 +f 12/17/5 9/16/5 79/99/5 +f 3/15/1 2/73/1 1/32/1 +f 20/44/2 19/58/2 18/27/2 +f 74/17/5 78/100/5 65/46/5 +f 31/43/1 33/99/1 54/47/1 +f 22/47/5 39/99/5 14/43/5 +f 46/1/2 24/64/2 23/7/2 +f 57/21/1 35/23/1 38/22/1 +f 61/50/9 66/53/9 76/51/9 +f 37/45/5 59/44/5 2/23/5 +f 78/28/3 77/51/3 67/53/3 +f 62/67/1 51/66/1 69/68/1 +f 51/66/1 55/65/1 63/6/1 +f 68/17/1 69/68/1 61/69/1 +f 61/69/1 69/68/1 51/66/1 +f 61/69/1 51/66/1 63/6/1 +f 65/71/1 67/70/1 64/5/1 +f 61/69/1 63/6/1 66/4/1 +f 64/5/1 67/70/1 66/4/1 +f 76/55/6 66/85/6 67/56/6 +f 47/17/2 25/16/2 26/10/2 +f 5/16/5 45/99/5 26/47/5 +f 55/60/6 54/101/6 33/58/6 +f 33/58/6 29/22/6 48/59/6 +f 48/59/6 72/102/6 63/103/6 +f 29/22/6 49/104/6 48/59/6 +f 48/59/6 63/103/6 55/60/6 +f 29/38/2 28/2/2 42/3/2 +f 32/44/6 31/23/6 52/21/6 +f 58/15/6 38/73/6 34/33/6 +f 27/7/6 24/38/6 46/29/6 +f 73/61/6 75/105/6 68/62/6 +f 21/58/6 41/27/6 42/29/6 +f 11/29/1 10/38/1 9/58/1 +f 59/45/1 37/44/1 36/2/1 +f 60/9/6 36/39/6 35/10/6 diff --git a/mods/boats/textures/boats_inventory.png b/mods/boats/textures/boats_inventory.png new file mode 100644 index 0000000..f9d082e Binary files /dev/null and b/mods/boats/textures/boats_inventory.png differ diff --git a/mods/boats/textures/boats_wield.png b/mods/boats/textures/boats_wield.png new file mode 100644 index 0000000..f998b5b Binary files /dev/null and b/mods/boats/textures/boats_wield.png differ diff --git a/mods/bonemeal/README.md b/mods/bonemeal/README.md new file mode 100644 index 0000000..e3ed954 --- /dev/null +++ b/mods/bonemeal/README.md @@ -0,0 +1,36 @@ +Bonemeal mod [bonemeal] + +This mod adds four new items into the game, bones which can be dug from normal +dirt which can be made into bonemeal, mulch which is is crafted using a tree and +8x leaves, and fertiliser which is a mixture of them both. + +Each item can be used on saplings and crops for a chance to grow them quicker as +well as dirt which will generate random grass, flowers or whichever decoration +is registered. + +Mulch has a strength of 1, Bonemeal 2 and Fertiliser 3 which means the stronger +the item, the more chance of growing saplings in low light, making crops sprout +quicker or simply decorate a larger area with grass and flowers. + +The api.txt document shows how to add your own saplings, crops and grasses to +the list by using one of the 3 commands included and the mod.lua file gives you +many examples by using some of the popular mods available. + +https://forum.minetest.net/viewtopic.php?f=9&t=16446 + +Changelog: + +- 0.1 - Initial release +- 0.2 - Added global on_use function for bonemeal growth +- 0.3 - Added strength to on_use global for new items (mulch and fertiliser) +- 0.4 - Added Intllib support and fr.txt file +- 0.5 - Added support for default bush and acacia bush saplings +- 0.6 - Using newer functions, Minetest 0.4.16 and above needed to run +- 0.7 - Can be used on papyrus and cactus now, added coral recipe, api addition +- 0.8 - Added support for farming redo's new garlic, pepper and onion crops +- 0.9 - Added support for farming redo's pea and beetroot crops, checks for place_param +- 1.0 - add_deco() now adds to existing item list while set_deco() replaces item list (thanks h-v-smacker) +- 1.1 - Added {can_bonemeal=1} group for special nodes +- 1.2 - Added support for minetest 5.0 cactus seedling, blueberry bush sapling and emergent jungle tree saplings, additional flowers and pine bush sapling. + +Lucky Blocks: 6 diff --git a/mods/bonemeal/api.txt b/mods/bonemeal/api.txt new file mode 100644 index 0000000..47b631d --- /dev/null +++ b/mods/bonemeal/api.txt @@ -0,0 +1,96 @@ + +Bonemeal API +============ + +This guide will show you how to add saplings, crops and dirt types for the +bonemeal mod to use from withhin your own mods. Please make sure that bonemeal +appears in the depends.txt file of your mod so everything work properly. + + +Function Usage +============== + + +Adding Crops +------------ + +bonemeal:add_crop({ + { nodename_start, growing_steps, seed_name } +}) + +This command is used to add new crops for bonemeal to work on. + +e.g. + +bonemeal:add_crop({ + {"farming:cotton_", 8, "farming:seed_cotton"}, + {"farming:wheat_", 8, "farming:seed_wheat"}, +}) + + +Adding Saplings +--------------- + +bonemeal:add_sapling({ + { sapling_node, function, soil_type[sand, dirt, nodename] } +}) + +This command will add new saplings for bonemeal to grow on sand, soil or a +specified node type. + +bonemeal:add_sapling({ + {"ethereal:palm_sapling", ethereal.grow_palm_tree, "soil"}, + {"ethereal:palm_sapling", ethereal.grow_palm_tree, "sand"}, +}) + + +Adding Dirt Decoration +---------------------- + +bonemeal:add_deco({ + { dirt_node, {grass_node_list}, {decor_node_list} } +}) + +This command will add grass and decoration to specific dirt types, use "" to +add an empty node. If some decorations have been already defined for this dirt type, new +will be added to the respective list. All empty ("") entries will be added regardless, +which allows to decrease the frequency of decoration emergence, if needed. + +e.g. + +bonemeal:add_deco({ + {"default:dirt_with_dry_grass", {"default:dry_grass_1", ""}, + {"flowers:rose", "flowers:viola"} } +}) + +Thus, add_deco() always adds (to) a definition, and never overrides. To discard an existing +definiton in favor of the new one, use + +bonemeal:set_deco({ + { dirt_node, {grass_node_list}, {decor_node_list} } +}) + +This command will set decoration for a given dirt type, fully replacing any existing definition. + + +Global ON_USE Function +---------------------- + +bonemeal:on_use(pos, strength, node) + +This function can be called from other mods to grow plants using alternative +bonemeal items and have the same effect. + + {pos} is the location to apply growing + {strength} is how strong to grow [low of 1 to high of 4] + {node} is the node at pos, but can be left nil to get_node itself + +Note: Higher strength items require lower light levels, and a strength of 4 +needs no light at all. + + +Final Words +=========== + +I hope this guide helps you add your own plants so you can grow them quickly +with the items included. Please check the mods.lua for more examples. diff --git a/mods/bonemeal/init.lua b/mods/bonemeal/init.lua new file mode 100644 index 0000000..27f64c9 --- /dev/null +++ b/mods/bonemeal/init.lua @@ -0,0 +1,646 @@ + +bonemeal = {} + +-- Load support for intllib. +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP .. "/intllib.lua") + + +-- creative check +local creative_mode_cache = minetest.settings:get_bool("creative_mode") +function is_creative(name) + return creative_mode_cache or minetest.check_player_privs(name, {creative = true}) +end + + +-- default crops +local crops = { + {"farming:cotton_", 8, "farming:seed_cotton"}, + {"farming:wheat_", 8, "farming:seed_wheat"}, +} + + +-- special pine check for nearby snow +local function pine_grow(pos) + + if minetest.find_node_near(pos, 1, + {"default:snow", "default:snowblock", "default:dirt_with_snow"}) then + + default.grow_new_snowy_pine_tree(pos) + else + default.grow_new_pine_tree(pos) + end +end + + +-- default saplings +local saplings = { + {"default:sapling", default.grow_new_apple_tree, "soil"}, + {"default:junglesapling", default.grow_new_jungle_tree, "soil"}, + {"default:emergent_jungle_sapling", default.grow_new_emergent_jungle_tree, "soil"}, + {"default:acacia_sapling", default.grow_new_acacia_tree, "soil"}, + {"default:aspen_sapling", default.grow_new_aspen_tree, "soil"}, + {"default:pine_sapling", pine_grow, "soil"}, + {"default:bush_sapling", default.grow_bush, "soil"}, + {"default:acacia_bush_sapling", default.grow_acacia_bush, "soil"}, + {"default:large_cactus_seedling", default.grow_large_cactus, "sand"}, + {"default:blueberry_bush_sapling", default.grow_blueberry_bush, "soil"}, + {"default:pine_bush_sapling", default.grow_pine_bush, "soil"}, +} + +-- helper tables ( "" denotes a blank item ) +local green_grass = { + "default:grass_2", "default:grass_3", "default:grass_4", + "default:grass_5", "", "" +} + +local dry_grass = { + "default:dry_grass_2", "default:dry_grass_3", "default:dry_grass_4", + "default:dry_grass_5", "", "" +} + +local flowers = { + "flowers:dandelion_white", "flowers:dandelion_yellow", "flowers:geranium", + "flowers:rose", "flowers:tulip", "flowers:viola", "" +} + +-- 5.0 flower check +if minetest.registered_nodes["flowers:tulip_black"] then + flowers[#flowers + 1] = "flowers:tulip_black" + flowers[#flowers + 1] = "flowers:chrysanthemum_green" +end + +-- add additional bakedclay flowers if enabled +if minetest.get_modpath("bakedclay") then + flowers[#flowers + 1] = "bakedclay:delphinium" + flowers[#flowers + 1] = "bakedclay:thistle" + flowers[#flowers + 1] = "bakedclay:lazarus" + flowers[#flowers + 1] = "bakedclay:mannagrass" + flowers[#flowers + 1] = "" +end + +-- default biomes deco +local deco = { + {"default:dirt_with_dry_grass", dry_grass, flowers}, + {"default:sand", {}, {"default:dry_shrub", "", "", ""} }, + {"default:desert_sand", {}, {"default:dry_shrub", "", "", ""} }, + {"default:silver_sand", {}, {"default:dry_shrub", "", "", ""} }, +} + + +----- local functions + + +-- particles +local function particle_effect(pos) + + minetest.add_particlespawner({ + amount = 4, + time = 0.15, + minpos = pos, + maxpos = pos, + minvel = {x = -1, y = 2, z = -1}, + maxvel = {x = 1, y = 4, z = 1}, + minacc = {x = -1, y = -1, z = -1}, + maxacc = {x = 1, y = 1, z = 1}, + minexptime = 1, + maxexptime = 1, + minsize = 1, + maxsize = 3, + texture = "bonemeal_particle.png", + }) +end + + +-- tree type check +local function grow_tree(pos, object) + + if type(object) == "table" and object.axiom then + -- grow L-system tree + minetest.remove_node(pos) + minetest.spawn_tree(pos, object) + + elseif type(object) == "string" and minetest.registered_nodes[object] then + -- place node + minetest.set_node(pos, {name = object}) + + elseif type(object) == "function" then + -- function + object(pos) + end +end + + +-- sapling check +local function check_sapling(pos, nodename) + + -- what is sapling placed on? + local under = minetest.get_node({ + x = pos.x, + y = pos.y - 1, + z = pos.z + }) + + local can_grow, grow_on + + -- check list for sapling and function + for n = 1, #saplings do + + if saplings[n][1] == nodename then + + grow_on = saplings[n][3] + + -- sapling grows on top of specific node + if grow_on + and grow_on ~= "soil" + and grow_on ~= "sand" + and grow_on == under.name then + can_grow = true + end + + -- sapling grows on top of soil (default) + if can_grow == nil + and (grow_on == nil or grow_on == "soil") + and minetest.get_item_group(under.name, "soil") > 0 then + can_grow = true + end + + -- sapling grows on top of sand + if can_grow == nil + and grow_on == "sand" + and minetest.get_item_group(under.name, "sand") > 0 then + can_grow = true + end + + -- check if we can grow sapling + if can_grow then + particle_effect(pos) + grow_tree(pos, saplings[n][2]) + return + end + end + end +end + + +-- crops check +local function check_crops(pos, nodename, strength) + + local mod, crop, stage, nod, def + + -- grow registered crops + for n = 1, #crops do + + if string.find(nodename, crops[n][1]) + or nodename == crops[n][3] then + + -- separate mod and node name + mod = nodename:split(":")[1] .. ":" + crop = nodename:split(":")[2] + + -- get stage number or set to 0 for seed + stage = tonumber( crop:split("_")[2] ) or 0 + stage = math.min(stage + strength, crops[n][2]) + + -- check for place_param setting + nod = crops[n][1] .. stage + def = minetest.registered_nodes[nod] + def = def and def.place_param2 or 0 + + minetest.set_node(pos, {name = nod, param2 = def}) + + particle_effect(pos) + + return + end + end +end + + +-- check soil for specific decoration placement +local function check_soil(pos, nodename, strength) + + -- set radius according to strength + local side = strength - 1 + local tall = math.max(strength - 2, 0) + local floor + local groups = minetest.registered_items[nodename] + and minetest.registered_items[nodename].groups or {} + + -- only place decoration on one type of surface + if groups.soil then + floor = {"group:soil"} + elseif groups.sand then + floor = {"group:sand"} + else + floor = {nodename} + end + + -- get area of land with free space above + local dirt = minetest.find_nodes_in_area_under_air( + {x = pos.x - side, y = pos.y - tall, z = pos.z - side}, + {x = pos.x + side, y = pos.y + tall, z = pos.z + side}, floor) + + -- set default grass and decoration + local grass = green_grass + local decor = flowers + + -- choose grass and decoration to use on dirt patch + for n = 1, #deco do + + -- do we have a grass match? + if nodename == deco[n][1] then + grass = deco[n][2] or {} + decor = deco[n][3] or {} + end + end + + local pos2, nod, def + + -- loop through soil + for _,n in pairs(dirt) do + + pos2 = n + + pos2.y = pos2.y + 1 + + if math.random(1, 5) == 5 then + if decor and #decor > 0 then + -- place random decoration (rare) + local dnum = #decor or 1 + nod = decor[math.random(1, dnum)] or "" + end + else + if grass and #grass > 0 then + -- place random grass (common) + local dgra = #grass or 1 + nod = #grass > 0 and grass[math.random(1, dgra)] or "" + end + end + + if nod and nod ~= "" then + def = minetest.registered_nodes[nod] + def = def and def.place_param2 or 0 + minetest.set_node(pos2, {name = nod, param2 = def}) + end + + particle_effect(pos2) + end +end + + +-- global functions + + +-- add to sapling list +-- {sapling node, schematic or function name, "soil"|"sand"|specific_node} +--e.g. {"default:sapling", default.grow_new_apple_tree, "soil"} + +function bonemeal:add_sapling(list) + + for n = 1, #list do + table.insert(saplings, list[n]) + end +end + + +-- add to crop list to force grow +-- {crop name start_, growth steps, seed node (if required)} +-- e.g. {"farming:wheat_", 8, "farming:seed_wheat"} +function bonemeal:add_crop(list) + + for n = 1, #list do + table.insert(crops, list[n]) + end +end + + +-- add grass and flower/plant decoration for specific dirt types +-- {dirt_node, {grass_nodes}, {flower_nodes} +-- e.g. {"default:dirt_with_dry_grass", dry_grass, flowers} +-- if an entry already exists for a given dirt type, it will add new entries and all empty +-- entries, allowing to both add decorations and decrease their frequency. +function bonemeal:add_deco(list) + + for l = 1, #list do + + for n = 1, #deco do + + -- update existing entry + if list[l][1] == deco[n][1] then + + -- adding grass types + for _,extra in ipairs(list[l][2]) do + + if extra ~= "" then + + for __,entry in ipairs(deco[n][2]) do + + if extra == entry then + extra = false + break + end + end + end + + if extra then + table.insert(deco[n][2], extra) + end + end + + -- adding decoration types + for _,extra in ipairs(list[l][3]) do + + if extra ~= "" then + + for __,entry in ipairs(deco[n][3]) do + + if extra == entry then + extra = false + break + end + end + end + + if extra then + table.insert(deco[n][3], extra) + end + end + + list[l] = false + break + end + end + + if list[l] then + table.insert(deco, list[l]) + end + end +end + + +-- definitively set a decration scheme +-- this function will either add a new entry as is, or replace the existing one +function bonemeal:set_deco(list) + + for l = 1, #list do + + for n = 1, #deco do + + -- replace existing entry + if list[l][1] == deco[n][1] then + deco[n][2] = list[l][2] + deco[n][3] = list[l][3] + list[l] = false + break + end + end + + if list[l] then + table.insert(deco, list[l]) + end + end +end + + +-- global on_use function for bonemeal +function bonemeal:on_use(pos, strength, node) + + -- get node pointed at + local node = node or minetest.get_node(pos) + + -- return if nothing there + if node.name == "ignore" then + return + end + + -- make sure strength is between 1 and 4 + strength = strength or 1 + strength = math.max(strength, 1) + strength = math.min(strength, 4) + + -- papyrus and cactus + if node.name == "default:papyrus" then + + default.grow_papyrus(pos, node) + particle_effect(pos) + return + + elseif node.name == "default:cactus" then + + default.grow_cactus(pos, node) + particle_effect(pos) + return + end + + -- grow grass and flowers + if minetest.get_item_group(node.name, "soil") > 0 + or minetest.get_item_group(node.name, "sand") > 0 + or minetest.get_item_group(node.name, "can_bonemeal") > 0 then + check_soil(pos, node.name, strength) + return + end + + -- light check depending on strength (strength of 4 = no light needed) + if (minetest.get_node_light(pos) or 0) < (12 - (strength * 3)) then + return + end + + -- check for tree growth if pointing at sapling +-- if minetest.get_item_group(node.name, "sapling") > 0 + if math.random(1, (5 - strength)) == 1 then + check_sapling(pos, node.name) + return + end + + -- check for crop growth + check_crops(pos, node.name, strength) +end + + +----- items + + +-- mulch (strength 1) +minetest.register_craftitem("bonemeal:mulch", { + description = S("Mulch"), + inventory_image = "bonemeal_mulch.png", + + on_use = function(itemstack, user, pointed_thing) + + -- did we point at a node? + if pointed_thing.type ~= "node" then + return + end + + -- is area protected? + if minetest.is_protected(pointed_thing.under, user:get_player_name()) then + return + end + + -- take item if not in creative + if not is_creative(user:get_player_name()) then + itemstack:take_item() + end + + -- call global on_use function with strength of 1 + bonemeal:on_use(pointed_thing.under, 1) + + return itemstack + end, +}) + + +-- bonemeal (strength 2) +minetest.register_craftitem("bonemeal:bonemeal", { + description = S("Bone Meal"), + inventory_image = "bonemeal_item.png", + + on_use = function(itemstack, user, pointed_thing) + + -- did we point at a node? + if pointed_thing.type ~= "node" then + return + end + + -- is area protected? + if minetest.is_protected(pointed_thing.under, user:get_player_name()) then + return + end + + -- take item if not in creative + if not is_creative(user:get_player_name()) then + itemstack:take_item() + end + + -- call global on_use function with strength of 2 + bonemeal:on_use(pointed_thing.under, 2) + + return itemstack + end, +}) + + +-- fertiliser (strength 3) +minetest.register_craftitem("bonemeal:fertiliser", { + description = S("Fertiliser"), + inventory_image = "bonemeal_fertiliser.png", + + on_use = function(itemstack, user, pointed_thing) + + -- did we point at a node? + if pointed_thing.type ~= "node" then + return + end + + -- is area protected? + if minetest.is_protected(pointed_thing.under, user:get_player_name()) then + return + end + + -- take item if not in creative + if not is_creative(user:get_player_name()) then + itemstack:take_item() + end + + -- call global on_use function with strength of 3 + bonemeal:on_use(pointed_thing.under, 3) + + return itemstack + end, +}) + + +-- bone +minetest.register_craftitem("bonemeal:bone", { + description = S("Bone"), + inventory_image = "bonemeal_bone.png", +}) + +-- gelatin powder +minetest.register_craftitem("bonemeal:gelatin_powder", { + description = S("Gelatin Powder"), + inventory_image = "bonemeal_gelatin_powder.png", + groups = {food_gelatin = 1, flammable = 2}, +}) + + +--- crafting recipes + +-- gelatin powder +minetest.register_craft({ + output = "bonemeal:gelatin_powder 4", + recipe = { + {"bonemeal:bone", "bonemeal:bone", "bonemeal:bone"}, + {"bucket:bucket_water", "bucket:bucket_water", "bucket:bucket_water"}, + {"bucket:bucket_water", "default:torch", "bucket:bucket_water"}, + }, + replacements = { + {"bucket:bucket_water", "bucket:bucket_empty 5"}, + }, +}) + +-- bonemeal (from bone) +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:bonemeal 2", + recipe = {"bonemeal:bone"}, +}) + +-- bonemeal (from player bones) +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:bonemeal 4", + recipe = {"bones:bones"}, +}) + +-- bonemeal (from coral skeleton) +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:bonemeal 2", + recipe = {"default:coral_skeleton"}, +}) + +-- mulch +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:mulch 4", + recipe = { + "group:tree", "group:leaves", "group:leaves", + "group:leaves", "group:leaves", "group:leaves", + "group:leaves", "group:leaves", "group:leaves" + }, +}) + +-- fertiliser +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:fertiliser 2", + recipe = {"bonemeal:bonemeal", "bonemeal:mulch"}, +}) + + +-- add bones to dirt +minetest.override_item("default:dirt", { + drop = { + max_items = 1, + items = { + { + items = {"bonemeal:bone"}, + rarity = 30, + }, + { + items = {"default:dirt"}, + } + } + }, +}) + + +-- add support for other mods +local path = minetest.get_modpath("bonemeal") + +dofile(path .. "/mods.lua") +dofile(path .. "/lucky_block.lua") + +print (S("[MOD] bonemeal loaded")) diff --git a/mods/bonemeal/intllib.lua b/mods/bonemeal/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/bonemeal/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/bonemeal/license.txt b/mods/bonemeal/license.txt new file mode 100644 index 0000000..fec6f6a --- /dev/null +++ b/mods/bonemeal/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 TenPlus1 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/mods/bonemeal/locale/fr.txt b/mods/bonemeal/locale/fr.txt new file mode 100644 index 0000000..24475c8 --- /dev/null +++ b/mods/bonemeal/locale/fr.txt @@ -0,0 +1,7 @@ +# init.lua + +Mulch = Paillis +Bone Meal = Poudre d'os +Fertiliser = Engrais +Bone = Os +[MOD] bonemeal loaded = [MOD] bonemeal chargé diff --git a/mods/bonemeal/locale/template.txt b/mods/bonemeal/locale/template.txt new file mode 100644 index 0000000..f4023ac --- /dev/null +++ b/mods/bonemeal/locale/template.txt @@ -0,0 +1,7 @@ +# init.lua + +Mulch = +Bone Meal = +Fertiliser = +Bone = +[bonemeal] loaded = diff --git a/mods/bonemeal/lucky_block.lua b/mods/bonemeal/lucky_block.lua new file mode 100644 index 0000000..d335d35 --- /dev/null +++ b/mods/bonemeal/lucky_block.lua @@ -0,0 +1,29 @@ + +-- add lucky blocks + +local function growy(pos, player) + + local dpos = minetest.find_node_near(pos, 1, "group:soil") + + if dpos then + bonemeal:on_use(dpos, 5) + end +end + + +if minetest.get_modpath("lucky_block") then + + lucky_block:add_blocks({ + {"lig"}, + {"dro", {"bonemeal:mulch"}, 10}, + {"dro", {"bonemeal:bonemeal"}, 10}, + {"dro", {"bonemeal:fertiliser"}, 10}, + {"cus", growy}, + {"nod", "default:chest", 0, { + {name = "bonemeal:mulch", max = 20}, + {name = "bonemeal:bonemeal", max = 15}, + {name = "bonemeal:fertiliser", max = 10}, + }}, + }) + +end diff --git a/mods/bonemeal/mod.conf b/mods/bonemeal/mod.conf new file mode 100644 index 0000000..5828b2c --- /dev/null +++ b/mods/bonemeal/mod.conf @@ -0,0 +1,4 @@ +name = bonemeal +depends = default +description = Adds bone and bonemeal giving the ability to quickly grow plants and saplings. +optional_depends = intllib, farming, ethereal, moretrees, technic_worldgen, lucky_block, flowers diff --git a/mods/bonemeal/mods.lua b/mods/bonemeal/mods.lua new file mode 100644 index 0000000..0a51131 --- /dev/null +++ b/mods/bonemeal/mods.lua @@ -0,0 +1,143 @@ + +-- craft bones from animalmaterials into bonemeal +if minetest.get_modpath("animalmaterials") then + + minetest.register_craft({ + type = "shapeless", + output = "bonemeal:bonemeal 2", + recipe = {"animalmaterials:bone"}, + }) +end + + +if farming and farming.mod and farming.mod == "redo" then + + bonemeal:add_crop({ + {"farming:tomato_", 8}, + {"farming:corn_", 8}, + {"farming:melon_", 8}, + {"farming:pumpkin_", 8}, + {"farming:beanpole_", 5}, + {"farming:blueberry_", 4}, + {"farming:raspberry_", 4}, + {"farming:carrot_", 8}, + {"farming:cocoa_", 4}, + {"farming:coffee_", 5}, + {"farming:cucumber_", 4}, + {"farming:potato_", 4}, + {"farming:grapes_", 8}, + {"farming:rhubarb_", 3}, + {"farming:barley_", 7}, + {"farming:hemp_", 8}, + {"farming:chili_", 8}, + {"farming:garlic_", 5}, + {"farming:onion_", 5}, + {"farming:pepper_", 5}, + {"farming:pineapple_", 8}, + {"farming:pea_", 5}, + {"farming:beetroot_", 5}, + {"farming:rye_", 8}, + {"farming:oat_", 8}, + {"farming:rice_", 8}, + }) +end + + +if minetest.get_modpath("ethereal") then + + bonemeal:add_crop({ + {"ethereal:strawberry_", 8}, + {"ethereal:onion_", 5}, + }) + + bonemeal:add_sapling({ + {"ethereal:palm_sapling", ethereal.grow_palm_tree, "soil"}, + {"ethereal:palm_sapling", ethereal.grow_palm_tree, "sand"}, + {"ethereal:yellow_tree_sapling", ethereal.grow_yellow_tree, "soil"}, + {"ethereal:big_tree_sapling", ethereal.grow_big_tree, "soil"}, + {"ethereal:banana_tree_sapling", ethereal.grow_banana_tree, "soil"}, + {"ethereal:frost_tree_sapling", ethereal.grow_frost_tree, "soil"}, + {"ethereal:mushroom_sapling", ethereal.grow_mushroom_tree, "soil"}, + {"ethereal:willow_sapling", ethereal.grow_willow_tree, "soil"}, + {"ethereal:redwood_sapling", ethereal.grow_redwood_tree, "soil"}, + {"ethereal:orange_tree_sapling", ethereal.grow_orange_tree, "soil"}, + {"ethereal:bamboo_sprout", ethereal.grow_bamboo_tree, "soil"}, + {"ethereal:birch_sapling", ethereal.grow_birch_tree, "soil"}, + {"ethereal:sakura_sapling", ethereal.grow_sakura_tree, "soil"}, + }) + + local grass = {"default:grass_3", "default:grass_4", "default:grass_5", ""} + + bonemeal:add_deco({ + {"ethereal:crystal_dirt", {"ethereal:crystalgrass", "", "", "", ""}, {}}, + {"ethereal:fiery_dirt", {"ethereal:dry_shrub", "", "", "", ""}, {}}, + {"ethereal:prairie_dirt", grass, {"flowers:dandelion_white", + "flowers:dandelion_yellow", "flowers:geranium", "flowers:rose", + "flowers:tulip", "flowers:viola", "ethereal:strawberry_7"}}, + {"ethereal:gray_dirt", {}, {"ethereal:snowygrass", "", ""}}, + {"ethereal:cold_dirt", {}, {"ethereal:snowygrass", "", ""}}, + {"ethereal:mushroom_dirt", {}, {"flowers:mushroom_red", "flowers:mushroom_brown", "", "", ""}}, + {"ethereal:jungle_dirt", grass, {"default:junglegrass", "", "", ""}}, + {"ethereal:grove_dirt", grass, {"ethereal:fern", "", "", ""}}, + {"ethereal:bamboo_dirt", grass, {}}, + }) +end + + +if minetest.get_modpath("moretrees") then + + -- special fir check for snow + local function fir_grow(pos) + + if minetest.find_node_near(pos, 1, + {"default:snow", "default:snowblock", "default:dirt_with_snow"}) then + + moretrees.grow_fir_snow(pos) + else + moretrees.grow_fir(pos) + end + end + + bonemeal:add_sapling({ + {"moretrees:beech_sapling", moretrees.spawn_beech_object, "soil"}, + {"moretrees:apple_tree_sapling", moretrees.spawn_apple_tree_object, "soil"}, + {"moretrees:oak_sapling", moretrees.spawn_oak_object, "soil"}, + {"moretrees:sequoia_sapling", moretrees.spawn_sequoia_object, "soil"}, + --{"moretrees:birch_sapling", moretrees.spawn_birch_object, "soil"}, + {"moretrees:birch_sapling", moretrees.grow_birch, "soil"}, + {"moretrees:palm_sapling", moretrees.spawn_palm_object, "soil"}, + {"moretrees:palm_sapling", moretrees.spawn_palm_object, "sand"}, + {"moretrees:date_palm_sapling", moretrees.spawn_date_palm_object, "soil"}, + {"moretrees:date_palm_sapling", moretrees.spawn_date_palm_object, "sand"}, + --{"moretrees:spruce_sapling", moretrees.spawn_spruce_object, "soil"}, + {"moretrees:spruce_sapling", moretrees.grow_spruce, "soil"}, + {"moretrees:cedar_sapling", moretrees.spawn_cedar_object, "soil"}, + {"moretrees:poplar_sapling", moretrees.spawn_poplar_object, "soil"}, + {"moretrees:willow_sapling", moretrees.spawn_willow_object, "soil"}, + {"moretrees:rubber_tree_sapling", moretrees.spawn_rubber_tree_object, "soil"}, + {"moretrees:fir_sapling", fir_grow, "soil"}, + }) + +elseif minetest.get_modpath("technic_worldgen") then + + bonemeal:add_sapling({ + {"moretrees:rubber_tree_sapling", technic.rubber_tree_model, "soil"}, + }) +end + + +if minetest.get_modpath("caverealms") then + + local fil = minetest.get_modpath("caverealms") .. "/schematics/shroom.mts" + local add_shroom = function(pos) + + minetest.swap_node(pos, {name = "air"}) + + minetest.place_schematic( + {x = pos.x - 5, y = pos.y, z = pos.z - 5}, fil, 0, nil, false) + end + + bonemeal:add_sapling({ + {"caverealms:mushroom_sapling", add_shroom, "soil"}, + }) +end diff --git a/mods/bonemeal/screenshot.png b/mods/bonemeal/screenshot.png new file mode 100644 index 0000000..c4b9fa7 Binary files /dev/null and b/mods/bonemeal/screenshot.png differ diff --git a/mods/bonemeal/textures/bonemeal_bone.png b/mods/bonemeal/textures/bonemeal_bone.png new file mode 100644 index 0000000..d86e7be Binary files /dev/null and b/mods/bonemeal/textures/bonemeal_bone.png differ diff --git a/mods/bonemeal/textures/bonemeal_fertiliser.png b/mods/bonemeal/textures/bonemeal_fertiliser.png new file mode 100644 index 0000000..b187c9a Binary files /dev/null and b/mods/bonemeal/textures/bonemeal_fertiliser.png differ diff --git a/mods/bonemeal/textures/bonemeal_gelatin_powder.png b/mods/bonemeal/textures/bonemeal_gelatin_powder.png new file mode 100644 index 0000000..0625cc2 Binary files /dev/null and b/mods/bonemeal/textures/bonemeal_gelatin_powder.png differ diff --git a/mods/bonemeal/textures/bonemeal_item.png b/mods/bonemeal/textures/bonemeal_item.png new file mode 100644 index 0000000..f141263 Binary files /dev/null and b/mods/bonemeal/textures/bonemeal_item.png differ diff --git a/mods/bonemeal/textures/bonemeal_mulch.png b/mods/bonemeal/textures/bonemeal_mulch.png new file mode 100644 index 0000000..df00ac2 Binary files /dev/null and b/mods/bonemeal/textures/bonemeal_mulch.png differ diff --git a/mods/bonemeal/textures/bonemeal_particle.png b/mods/bonemeal/textures/bonemeal_particle.png new file mode 100644 index 0000000..71ef90f Binary files /dev/null and b/mods/bonemeal/textures/bonemeal_particle.png differ diff --git a/mods/bones/README.txt b/mods/bones/README.txt new file mode 100644 index 0000000..91bcd10 --- /dev/null +++ b/mods/bones/README.txt @@ -0,0 +1,12 @@ +Minetest Game mod: bones +======================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by PilzAdam (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +All textures: paramat (CC BY-SA 3.0) diff --git a/mods/bones/init.lua b/mods/bones/init.lua new file mode 100644 index 0000000..5e54259 --- /dev/null +++ b/mods/bones/init.lua @@ -0,0 +1,284 @@ +-- bones/init.lua + +-- Minetest 0.4 mod: bones +-- See README.txt for licensing and other information. + +-- Load support for MT game translation. +local S = minetest.get_translator("bones") + +bones = {} + +local function is_owner(pos, name) + local owner = minetest.get_meta(pos):get_string("owner") + if owner == "" or owner == name or minetest.check_player_privs(name, "protection_bypass") then + return true + end + return false +end + +local bones_formspec = + "size[8,9]" .. + "list[current_name;main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) + +local share_bones_time = tonumber(minetest.settings:get("share_bones_time")) or 1200 +local share_bones_time_early = tonumber(minetest.settings:get("share_bones_time_early")) or share_bones_time / 4 + +minetest.register_node("bones:bones", { + description = S("Bones"), + tiles = { + "bones_top.png^[transform2", + "bones_bottom.png", + "bones_side.png", + "bones_side.png", + "bones_rear.png", + "bones_front.png" + }, + paramtype2 = "facedir", + groups = {dig_immediate = 2}, + sounds = default.node_sound_gravel_defaults(), + + can_dig = function(pos, player) + local inv = minetest.get_meta(pos):get_inventory() + local name = "" + if player then + name = player:get_player_name() + end + return is_owner(pos, name) and inv:is_empty("main") + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if is_owner(pos, player:get_player_name()) then + return count + end + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + return 0 + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) then + return stack:get_count() + end + return 0 + end, + + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if meta:get_inventory():is_empty("main") then + local inv = player:get_inventory() + if inv:room_for_item("main", {name = "bones:bones"}) then + inv:add_item("main", {name = "bones:bones"}) + else + minetest.add_item(pos, "bones:bones") + end + minetest.remove_node(pos) + end + end, + + on_punch = function(pos, node, player) + if not is_owner(pos, player:get_player_name()) then + return + end + + if minetest.get_meta(pos):get_string("infotext") == "" then + return + end + + local inv = minetest.get_meta(pos):get_inventory() + local player_inv = player:get_inventory() + local has_space = true + + for i = 1, inv:get_size("main") do + local stk = inv:get_stack("main", i) + if player_inv:room_for_item("main", stk) then + inv:set_stack("main", i, nil) + player_inv:add_item("main", stk) + else + has_space = false + break + end + end + + -- remove bones if player emptied them + if has_space then + if player_inv:room_for_item("main", {name = "bones:bones"}) then + player_inv:add_item("main", {name = "bones:bones"}) + else + minetest.add_item(pos,"bones:bones") + end + minetest.remove_node(pos) + end + end, + + on_timer = function(pos, elapsed) + local meta = minetest.get_meta(pos) + local time = meta:get_int("time") + elapsed + if time >= share_bones_time then + meta:set_string("infotext", S("@1's old bones", meta:get_string("owner"))) + meta:set_string("owner", "") + else + meta:set_int("time", time) + return true + end + end, + on_blast = function(pos) + end, +}) + +local function may_replace(pos, player) + local node_name = minetest.get_node(pos).name + local node_definition = minetest.registered_nodes[node_name] + + -- if the node is unknown, we return false + if not node_definition then + return false + end + + -- allow replacing air and liquids + if node_name == "air" or node_definition.liquidtype ~= "none" then + return true + end + + -- don't replace filled chests and other nodes that don't allow it + local can_dig_func = node_definition.can_dig + if can_dig_func and not can_dig_func(pos, player) then + return false + end + + -- default to each nodes buildable_to; if a placed block would replace it, why shouldn't bones? + -- flowers being squished by bones are more realistical than a squished stone, too + -- exception are of course any protected buildable_to + return node_definition.buildable_to and not minetest.is_protected(pos, player:get_player_name()) +end + +local drop = function(pos, itemstack) + local obj = minetest.add_item(pos, itemstack:take_item(itemstack:get_count())) + if obj then + obj:set_velocity({ + x = math.random(-10, 10) / 9, + y = 5, + z = math.random(-10, 10) / 9, + }) + end +end + +local player_inventory_lists = { "main", "craft" } +bones.player_inventory_lists = player_inventory_lists + +local function is_all_empty(player_inv) + for _, list_name in ipairs(player_inventory_lists) do + if not player_inv:is_empty(list_name) then + return false + end + end + return true +end + +minetest.register_on_dieplayer(function(player) + + local bones_mode = minetest.settings:get("bones_mode") or "bones" + if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then + bones_mode = "bones" + end + + local bones_position_message = minetest.settings:get_bool("bones_position_message") == true + local player_name = player:get_player_name() + local pos = vector.round(player:get_pos()) + local pos_string = minetest.pos_to_string(pos) + + -- return if keep inventory set or in creative mode + if bones_mode == "keep" or (creative and creative.is_enabled_for + and creative.is_enabled_for(player:get_player_name())) then + minetest.log("action", player_name .. " dies at " .. pos_string .. + ". No bones placed") + if bones_position_message then + minetest.chat_send_player(player_name, S("@1 died at @2.", player_name, pos_string)) + end + return + end + + local player_inv = player:get_inventory() + if is_all_empty(player_inv) then + minetest.log("action", player_name .. " dies at " .. pos_string .. + ". No bones placed") + if bones_position_message then + minetest.chat_send_player(player_name, S("@1 died at @2.", player_name, pos_string)) + end + return + end + + -- check if it's possible to place bones, if not find space near player + if bones_mode == "bones" and not may_replace(pos, player) then + local air = minetest.find_node_near(pos, 1, {"air"}) + if air and not minetest.is_protected(air, player_name) then + pos = air + else + bones_mode = "drop" + end + end + + if bones_mode == "drop" then + for _, list_name in ipairs(player_inventory_lists) do + for i = 1, player_inv:get_size(list_name) do + drop(pos, player_inv:get_stack(list_name, i)) + end + player_inv:set_list(list_name, {}) + end + drop(pos, ItemStack("bones:bones")) + minetest.log("action", player_name .. " dies at " .. pos_string .. + ". Inventory dropped") + if bones_position_message then + minetest.chat_send_player(player_name, S("@1 died at @2, and dropped their inventory.", player_name, pos_string)) + end + return + end + + local param2 = minetest.dir_to_facedir(player:get_look_dir()) + minetest.set_node(pos, {name = "bones:bones", param2 = param2}) + + minetest.log("action", player_name .. " dies at " .. pos_string .. + ". Bones placed") + if bones_position_message then + minetest.chat_send_player(player_name, S("@1 died at @2, and bones were placed.", player_name, pos_string)) + end + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 8 * 4) + + for _, list_name in ipairs(player_inventory_lists) do + for i = 1, player_inv:get_size(list_name) do + local stack = player_inv:get_stack(list_name, i) + if inv:room_for_item("main", stack) then + inv:add_item("main", stack) + else -- no space left + drop(pos, stack) + end + end + player_inv:set_list(list_name, {}) + end + + meta:set_string("formspec", bones_formspec) + meta:set_string("owner", player_name) + + if share_bones_time ~= 0 then + meta:set_string("infotext", S("@1's fresh bones", player_name)) + + if share_bones_time_early == 0 or not minetest.is_protected(pos, player_name) then + meta:set_int("time", 0) + else + meta:set_int("time", (share_bones_time - share_bones_time_early)) + end + + minetest.get_node_timer(pos):start(10) + else + meta:set_string("infotext", S("@1's bones", player_name)) + end +end) diff --git a/mods/bones/license.txt b/mods/bones/license.txt new file mode 100644 index 0000000..fe52584 --- /dev/null +++ b/mods/bones/license.txt @@ -0,0 +1,58 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2016 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + diff --git a/mods/bones/locale/bones.de.tr b/mods/bones/locale/bones.de.tr new file mode 100644 index 0000000..83f5c28 --- /dev/null +++ b/mods/bones/locale/bones.de.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=Knochen +@1's old bones=Alte Knochen von @1 +@1 died at @2.=@1 starb bei @2. +@1 died at @2, and dropped their inventory.=@1 starb bei @2 und ließ das Inventar fallen. +@1 died at @2, and bones were placed.=@1 starb bei @2 und Knochen wurden platziert. +@1's fresh bones=Frische Knochen von @1 +@1's bones=Knochen von @1 diff --git a/mods/bones/locale/bones.es.tr b/mods/bones/locale/bones.es.tr new file mode 100644 index 0000000..9c45513 --- /dev/null +++ b/mods/bones/locale/bones.es.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=Huesos +@1's old bones=Huesos antiguos de @1 +@1 died at @2.=@1 murió en @2. +@1 died at @2, and dropped their inventory.=@1 murió en @2, y su inventario se desprendió. +@1 died at @2, and bones were placed.=@1 murió en @2, y sus huesos fueron depositados. +@1's fresh bones=Huesos recientes de @1 +@1's bones=Huesos de @1 diff --git a/mods/bones/locale/bones.fr.tr b/mods/bones/locale/bones.fr.tr new file mode 100644 index 0000000..cfe01ee --- /dev/null +++ b/mods/bones/locale/bones.fr.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=Os +@1's old bones=Vieux os de @1 +@1 died at @2.=@1 est mort à @2. +@1 died at @2, and dropped their inventory.=@1 est mort à @2 et a laissé tomber son inventaire. +@1 died at @2, and bones were placed.=@1 est mort à @2 et ses os ont été placés. +@1's fresh bones=Os frais de @1 +@1's bones=Os de @1 diff --git a/mods/bones/locale/bones.it.tr b/mods/bones/locale/bones.it.tr new file mode 100644 index 0000000..486b6d3 --- /dev/null +++ b/mods/bones/locale/bones.it.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=Ossa +@1's old bones=Ossa vecchie di @1 +@1 died at @2.=@1 è morto alla posizione @2. +@1 died at @2, and dropped their inventory.=@1 è morto alla posizione @2, e ha lasciato a terra il contenuto del suo inventario. +@1 died at @2, and bones were placed.=@1 è morto alla posizione @2, e vi sono state posizionate delle ossa. +@1's fresh bones=Ossa fresche di @1 +@1's bones=Ossa di @1 \ No newline at end of file diff --git a/mods/bones/locale/bones.ms.tr b/mods/bones/locale/bones.ms.tr new file mode 100644 index 0000000..e4b8712 --- /dev/null +++ b/mods/bones/locale/bones.ms.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=Tulang +@1's old bones=Tulang lama @1 +@1 died at @2.=@1 mati di @2. +@1 died at @2, and dropped their inventory.=@1 mati di @2, dan menjatuhkan inventorinya. +@1 died at @2, and bones were placed.=@1 mati di @2, dan tulang diletakkan. +@1's fresh bones=Tulang segar @1 +@1's bones=Tulang @1 diff --git a/mods/bones/locale/bones.ru.tr b/mods/bones/locale/bones.ru.tr new file mode 100644 index 0000000..98691c5 --- /dev/null +++ b/mods/bones/locale/bones.ru.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=КоÑти +@1's old bones=Старые коÑти @1 +@1 died at @2.=@1 умер в @2. +@1 died at @2, and dropped their inventory.=@1 умер в @2 и потерÑл Ñодержимое Ñвоего инвентарÑ. +@1 died at @2, and bones were placed.=@1 умер в @2, помещены коÑти. +@1's fresh bones=новые коÑти @1 +@1's bones=коÑти @1 diff --git a/mods/bones/locale/bones.se.tr b/mods/bones/locale/bones.se.tr new file mode 100644 index 0000000..1323c59 --- /dev/null +++ b/mods/bones/locale/bones.se.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=Ben +@1's old bones=@1s Gamla ben +@1 died at @2.=@1 dog pÃ¥ @a. +@1 died at @2, and dropped their inventory.=@1 dog pÃ¥ @a, och tappade deras saker. +@1 died at @2, and bones were placed.=@1 dog pÃ¥ @2, och deras ben var placerade. +@1's fresh bones=@1s färska ben +@1's bones=@1s ben diff --git a/mods/bones/locale/bones.zh_CN.tr b/mods/bones/locale/bones.zh_CN.tr new file mode 100644 index 0000000..dadf55e --- /dev/null +++ b/mods/bones/locale/bones.zh_CN.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=骨骸 +@1's old bones=@1的旧骨骸 +@1 died at @2.=@1在@2死亡。 +@1 died at @2, and dropped their inventory.=@1在@2死亡,丢掉了物å“æ ã€‚ +@1 died at @2, and bones were placed.=@1在@2死亡,骨骸被放置。 +@1's fresh bones=@1的新鲜骨骸 +@1's bones=@1的骨骸 diff --git a/mods/bones/locale/bones.zh_TW.tr b/mods/bones/locale/bones.zh_TW.tr new file mode 100644 index 0000000..1a94d2f --- /dev/null +++ b/mods/bones/locale/bones.zh_TW.tr @@ -0,0 +1,8 @@ +# textdomain: bones +Bones=骨骸 +@1's old bones=@1的舊骨骸 +@1 died at @2.=@1在@2死亡。 +@1 died at @2, and dropped their inventory.=@1在@2死亡,丟掉了物å“欄。 +@1 died at @2, and bones were placed.=@1在@2死亡,骨骸被放置。 +@1's fresh bones=@1的新鮮骨骸 +@1's bones=@1的骨骸 diff --git a/mods/bones/locale/template.txt b/mods/bones/locale/template.txt new file mode 100644 index 0000000..4ac8d45 --- /dev/null +++ b/mods/bones/locale/template.txt @@ -0,0 +1,8 @@ +# textdomain: bones +Bones= +@1's old bones= +@1 died at @2.= +@1 died at @2, and dropped their inventory.= +@1 died at @2, and bones were placed.= +@1's fresh bones= +@1's bones= diff --git a/mods/bones/mod.conf b/mods/bones/mod.conf new file mode 100644 index 0000000..371997b --- /dev/null +++ b/mods/bones/mod.conf @@ -0,0 +1,3 @@ +name = bones +description = Minetest Game mod: bones +depends = default diff --git a/mods/bones/textures/bones_bottom.png b/mods/bones/textures/bones_bottom.png new file mode 100644 index 0000000..859c6bb Binary files /dev/null and b/mods/bones/textures/bones_bottom.png differ diff --git a/mods/bones/textures/bones_front.png b/mods/bones/textures/bones_front.png new file mode 100644 index 0000000..1e52437 Binary files /dev/null and b/mods/bones/textures/bones_front.png differ diff --git a/mods/bones/textures/bones_rear.png b/mods/bones/textures/bones_rear.png new file mode 100644 index 0000000..4cfe236 Binary files /dev/null and b/mods/bones/textures/bones_rear.png differ diff --git a/mods/bones/textures/bones_side.png b/mods/bones/textures/bones_side.png new file mode 100644 index 0000000..a07595f Binary files /dev/null and b/mods/bones/textures/bones_side.png differ diff --git a/mods/bones/textures/bones_top.png b/mods/bones/textures/bones_top.png new file mode 100644 index 0000000..198a8a2 Binary files /dev/null and b/mods/bones/textures/bones_top.png differ diff --git a/mods/bridges/README.md b/mods/bridges/README.md new file mode 100644 index 0000000..65018b6 --- /dev/null +++ b/mods/bridges/README.md @@ -0,0 +1,68 @@ +Crafting recipes: +
S stands for stick +
W stands for wooden slab +
V stands for either vines or leaves (both can be used) +
G stands for groundplate of bridge +
H stands for handrail +
- stands for "leave empty" + +Groundplate: yields 2 "G" parts which are the basis for further bridges: +
V V V +
V W V +
V V V + +Handrail: yields 4 "H" parts which are needed in further receipes: +
- - - +
- G - +
- - - + +small bridge: +
S - S +
H G H +
S - S + +middle part (fits between small bridges): +
- - - +
H G H +
- - - + +corner of a bridge: +
S H S +
- G H +
S - S + +T junction of a bridge: +
S H S +
- G - +
S - S + +end of a bridge. +
S H S +
H G H +
S - S + +handrail, one side closed: +
- - - +
- - - +
S H S + +handrail, two sides closed: +
S - - +
H - - +
S H S + +handrail, three sides closed (if you want to walk around it): +
S H S +
H - - +
S H S + +a large, 3 nodes long bridge: +
- small_bridge - +
- middle_part_of_bridge - +
- small_bridge - + + +the self-building automatic bridge: +
large_bridge large_bridge large_bridge +
large_bridge large_bridge large_bridge +
large_bridge large_bridge large_bridge diff --git a/mods/bridges/init.lua b/mods/bridges/init.lua new file mode 100644 index 0000000..a0239ae --- /dev/null +++ b/mods/bridges/init.lua @@ -0,0 +1,391 @@ + +--[[ +Mod for Minetest that adds bridges (only one node wide!), slim handrails and a self-building-one-node-wide bridge. + + Copyright (C) 2013 Sokomine + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +--]] + +-- to make life a bit easier +bild_pfad = "default_wood.png"; --"forniture_wood.png"; +bild_pfad_s1 = bild_pfad; --"forniture_wood_s1.png"; +bild_pfad_s2 = bild_pfad; --"forniture_wood_s2.png"; +--bild_pfad_s1 = "default_wood.png"; --"forniture_wood_s1.png"; +--bild_pfad_s2 = "default_wood.png"; --"forniture_wood_s2.png"; + +leg_front_left = {-0.5,-0.5,-0.5, -0.4,0.5,-0.4}; +leg_front_right = { 0.4,-0.5,-0.5, 0.5,0.5,-0.4}; +leg_back_left = {-0.5,-0.5, 0.4, -0.4,0.5, 0.5}; +leg_back_right = { 0.4,-0.5, 0.4, 0.5,0.5, 0.5}; + +bar_left = {-0.5, 0.35,-0.4,-0.4, 0.4, 0.4}; +bar_right = { 0.4, 0.35,-0.4, 0.5, 0.4, 0.4}; +bar_back = { 0.4, 0.35, 0.4,-0.5, 0.4, 0.5}; +bar_front = { 0.5, 0.35,-0.5,-0.5, 0.4,-0.4}; + +bar_left_long = {-0.4, 0.35,-0.5,-0.5, 0.4, 0.5}; +bar_right_long = { 0.4, 0.35,-0.5, 0.5, 0.4, 0.5}; + +groundplate_small = {-0.4,-0.45,-0.5, 0.4,-0.4,0.5}; +groundplate_corner = {-0.5,-0.45,-0.5, 0.5,-0.4,0.5}; -- slightly larger + + +local STICK = "group:stick"; +local WOOD = "stairs:slab_wood"; +local BASIS = "bridges:bridge_basis"; +local RAIL = "bridges:handrail_middle"; +-- people who do not have vines have to replace "vines:vines" with something they do have and which they think might fit +local VINES = "vines:vines"; -- useful for ropes +local ALT = "group:leaves"; -- alternative for vines + +if( minetest.get_modpath( 'moon' ) or minetest.get_modpath( 'moonrealm') or minetest.get_modpath( 'moontest') ) then + STICK = "group:stick"; + WOOD = "default:steel_ingot"; + VINES = "group:stone"; + ALT = "group:leaves"; -- alternative for vines + + bild_pfad = "default_steel_block.png"; --"forniture_wood.png"; + bild_pfad_s1 = bild_pfad; --"forniture_wood_s1.png"; + bild_pfad_s2 = bild_pfad; --"forniture_wood_s2.png"; + +-- only if no moontest is installed +elseif( minetest.get_modpath( 'moreblocks' )) then + WOOD = 'moreblocks:slab_wood'; +end + + +local MAX_BRIDGE_LENGTH = 27; -- this is how far the automatic bridge can extend + + +local BRIDGE_PARTS = { + -- name, description, node definition, crafting receipe, additional information for yield of receipe + + -- the groundplate - essential for bridge building + { "bridge_basis", "groundplate of a bridge", { + groundplate_small, }, + { { VINES, VINES, VINES }, + { VINES, WOOD, VINES }, + { VINES, VINES, VINES } + }, " 2"}, -- yields 2 groundplates + -- the handrail is a basic part out of which bridges and handrails for staircases can be constructed + { "handrail_middle", "handrail for bridges and staircases", { + bar_front }, + { { "", "", "" }, + { "", BASIS, "" }, + { "", "", "" } + }, " 4"}, -- one groundplate yiels 4 handrails + + -- bridges + { "bridge_small", "small bridge", { -- TODO: slim legs? + leg_front_left, + leg_front_right, + leg_back_left, + leg_back_right, + bar_right, + bar_left, + groundplate_small, }, + { { STICK, "", STICK }, + { RAIL, BASIS, RAIL }, + { STICK, "", STICK } + }, "" }, + { "bridge_middle", "middle of a bridge", { + bar_right_long, + bar_left_long, + groundplate_small, }, + { { "", "", "" }, + { RAIL, BASIS, RAIL }, + { "", "", "" } + }, "" }, + { "bridge_corner", "corner of a bridge", { + leg_front_left, + leg_front_right, + leg_back_left, + leg_back_right, + bar_right, + bar_back, + groundplate_corner, }, + { { STICK, RAIL, STICK }, + { "", BASIS, RAIL }, + { STICK, "", STICK } + }, "" }, + { "bridge_t", "T junction of a bridge", { + leg_front_left, + leg_front_right, + leg_back_left, + leg_back_right, + bar_back, + groundplate_corner, }, + { { STICK, RAIL, STICK }, + { "", BASIS, "" }, + { STICK, "", STICK } + }, "" }, + { "bridge_end", "end of a bridge", { + leg_front_left, + leg_front_right, + leg_back_left, + leg_back_right, + bar_left, + bar_right, + bar_back, + groundplate_corner, }, + { { STICK, RAIL, STICK }, + { RAIL, BASIS, RAIL }, + { STICK, "", STICK } + }, "" }, + + -- handrails for the top of starcaises so that people won't fall down + { "handrail_top", "handrail for staircases, one side closed", { + leg_front_left, + leg_front_right, + bar_front, }, + { { "", "", "" }, + { "", "", "" }, + { STICK, RAIL, STICK } + }, "" }, + + + { "handrail_corner", "handrail for staircases, two sides closed", { + leg_front_left, + leg_front_right, + bar_front, + bar_left }, + { { STICK, "", "" }, + { RAIL, "", "" }, + { STICK, RAIL, STICK } + }, "" }, + + { "handrail_closed", "handrail for staircases, three sides closed", { + leg_front_left, + leg_front_right, + bar_front, + bar_right, + bar_left }, + { { STICK, RAIL, STICK }, + { RAIL, "", "" }, + { STICK, RAIL, STICK } + }, "" }, + } + + +for i in ipairs( BRIDGE_PARTS ) do + minetest.register_node("bridges:"..BRIDGE_PARTS[i][1], + { + description = BRIDGE_PARTS[i][2], + + tiles = { + bild_pfad, + bild_pfad, + bild_pfad_s1, + bild_pfad_s1, + bild_pfad_s2, + bild_pfad_s2, + }, + drawtype = "nodebox", + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = BRIDGE_PARTS[i][3], + }, + selection_box = { + type = "fixed", + fixed = {-0.5,-0.5,-0.5, 0.5, 0.5, 0.5}, + + }, + -- flammable so that it can be burned if no longer needed + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,flammable=3}, + }); + + minetest.register_craft({ + output = "bridges:"..BRIDGE_PARTS[i][1]..BRIDGE_PARTS[i][5], + recipe = BRIDGE_PARTS[i][4], + }); +end + +-- alternate receipe for the bridge basis + minetest.register_craft({ + output = "bridges:bridge_basis 2", + recipe = { { ALT, ALT, ALT }, + { ALT, WOOD, ALT }, + { ALT, ALT, ALT }, + }, + }); + +-- a bridge with covers 3 nodes in size + + minetest.register_node("bridges:bridge_large", + { description = 'large bridge', + tiles = { + bild_pfad, + bild_pfad, + bild_pfad_s1, + bild_pfad_s1, + bild_pfad_s2, + bild_pfad_s2, + }, + drawtype = "nodebox", + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + -- the large bridge covers 3 nodes + {-0.5,-0.5,-0.7, -0.4,0.5,-0.6}, + { 0.4,-0.5,-0.7, 0.5,0.5,-0.6}, + + {-0.5, 0.35,-1.5, -0.4,0.4, 1.5}, + + {-0.5,-0.5, 0.6, -0.4,0.5, 0.7}, + { 0.4,-0.5, 0.6, 0.5,0.5, 0.7}, + + { 0.4, 0.35,-1.5, 0.5,0.4, 1.5}, + + {-0.4,-0.45,-1.5, 0.4,-0.4,1.5}, + + } + }, + selection_box = { + type = "fixed", + fixed = {-0.5,-0.5,-1.5, 0.5,0.5, 1.5}, + + }, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,flammable=2} + }) + + minetest.register_craft({ + output = "bridges:bridge_large", + recipe = { { "", "bridges:bridge_middle", "" }, + { "", "bridges:bridge_small", "" }, + { "", "bridges:bridge_middle", "" }, + } }); + + + + +-- special: self-building automatic bridge + +minetest.register_node("bridges:bridge_auto", { + + description = "self building bridge", + tiles = { "default_chest_top.png" }, -- looks from all sides like the top of a chest + drawtype = "cube", + is_ground_content = true, + groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2,flammable=3}, + + drop = "", -- all leftover parts are in the "chest" + + on_construct = function(pos) + local meta = minetest.env:get_meta(pos); + meta:set_string("formspec", + "invsize[8,9;]".. + "list[current_name;main;0,0;8,4;]".. + "list[current_player;main;0,5;8,4;]") + meta:set_string("infotext", "Automatic bridge building set - leftover parts") + local inv = meta:get_inventory(); + inv:set_size("main", 8*4); + end, + + can_dig = function(pos,player) + local meta = minetest.env:get_meta(pos); + local inv = meta:get_inventory(); + return inv:is_empty("main"); + end, + + + after_place_node = function(pos, placer) + + local n; + local x_dir; + local z_dir; + local p; + local n; + + -- the bridge ought to unfold in the direction the player is looking + local dir = placer:get_look_dir(); + local fdir = minetest.dir_to_facedir(dir); + + -- the player is looking more in x- than in z-direction + if( math.abs( dir.x ) > math.abs( dir.z )) then + z_dir = 0; + if( dir.x > 0 ) then + x_dir = 1; + else + x_dir = -1; + end + else + x_dir = 0; + if( dir.z > 0 ) then + z_dir = 1; + else + z_dir = -1; + end + end + +-- print ("x_dir: "..tostring( x_dir ).." z_dir: "..tostring( z_dir )); + + -- we have determined the direction in which the bridge may extend - now lets look how far it can go + local i=1; + -- how many parts of the bridge remain? + local rem_small = math.floor(MAX_BRIDGE_LENGTH/3); + local rem_middle = MAX_BRIDGE_LENGTH-rem_small; + -- extend max. MAX_BRIDGE_LENGTH nodes wide and only if the node needs a bridge (i.e. consists of air) + while( i < MAX_BRIDGE_LENGTH ) do + + -- is there space for a bridge? + p = {x=pos.x+(x_dir*i), y=pos.y, z=pos.z+(z_dir*i)}; + n = minetest.env:get_node(p); + if( n == nil or (n.name ~= "air" and n.name ~= 'moonrealm:vacuum' and n.name ~= 'moonrealm:air' and n.name ~= 'moontest:vacuum' and n.name ~= 'moontest:air')) then + i = MAX_BRIDGE_LENGTH+1; -- end +-- print("At length "..tostring(i)..": node at target position not air; no place for bridge: "..tostring(n.name)); + else + -- one small bridge is followed by two middle parts + if( i%3 == 1 ) then + minetest.env:add_node(p, {name="bridges:bridge_small", param1=0, param2=fdir}); + rem_small = rem_small - 1; -- one small bridge used +-- print("Placing small bridge at dist "..tostring(i)); + else + minetest.env:add_node(p, {name="bridges:bridge_middle", param1=0, param2=fdir}); + rem_middle = rem_middle -1; -- one middle part used +-- print("Placing middle bridge at dist "..tostring(i)); + end + + i = i+1; + end + end + + + -- do we have to give any leftover parts back? + local meta = minetest.env:get_meta(pos); + local inv = meta:get_inventory(); + + if( rem_small > 0 ) then + inv:add_item( "main", "bridges:bridge_small "..tostring( rem_small )); + end + + if( rem_middle > 0 ) then + inv:add_item( "main", "bridges:bridge_middle "..tostring( rem_middle )); + end + end, +}) + + + minetest.register_craft({ + output = "bridges:bridge_auto", + recipe = { { "bridges:bridge_large", "bridges:bridge_large", "bridges:bridge_large" }, + { "bridges:bridge_large", "bridges:bridge_large", "bridges:bridge_large" }, + { "bridges:bridge_large", "bridges:bridge_large", "bridges:bridge_large" }, + } }); diff --git a/mods/bridges/license.txt b/mods/bridges/license.txt new file mode 100644 index 0000000..aad7f85 --- /dev/null +++ b/mods/bridges/license.txt @@ -0,0 +1,14 @@ +Copyright (C) 2012/2013 Sokomine + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/mods/bridges/mod.conf b/mods/bridges/mod.conf new file mode 100644 index 0000000..5fa31ad --- /dev/null +++ b/mods/bridges/mod.conf @@ -0,0 +1,5 @@ +name = bridges +title = Bridges +author = Sokomine +description = Adds bridges (only one node wide!), slim handrails and a self-building-one-node-wide bridge. +depends = default diff --git a/mods/bucket/README.txt b/mods/bucket/README.txt new file mode 100644 index 0000000..66065ed --- /dev/null +++ b/mods/bucket/README.txt @@ -0,0 +1,7 @@ +Edited version of Minetest 0.4 mod: bucket +========================= + +This version adds priv check for liquids use to limit griefing opportunities. +Grant spill priv to players to allow liquid placement. + +Edits by Shara RedCat. diff --git a/mods/bucket/init.lua b/mods/bucket/init.lua new file mode 100644 index 0000000..c1d630c --- /dev/null +++ b/mods/bucket/init.lua @@ -0,0 +1,239 @@ +-- Edited version of bucket mod +-- See README.txt for licensing and other information. + +minetest.register_privilege("spill", {description = "Can place liquids.", give_to_singleplayer=false,}) + +minetest.register_alias("bucket", "bucket:bucket_empty") +minetest.register_alias("bucket_water", "bucket:bucket_water") +minetest.register_alias("bucket_lava", "bucket:bucket_lava") + +minetest.register_craft({ + output = 'bucket:bucket_empty 1', + recipe = { + {'default:steel_ingot', '', 'default:steel_ingot'}, + {'', 'default:steel_ingot', ''}, + } +}) + +bucket = {} +bucket.liquids = {} + +local function check_protection(pos, name, text) + if minetest.is_protected(pos, name) then + minetest.log("action", (name ~= "" and name or "A mod") + .. " tried to " .. text + .. " at protected position " + .. minetest.pos_to_string(pos) + .. " with a bucket") + minetest.record_protection_violation(pos, name) + return true + end + return false +end + +-- Register a new liquid +-- source = name of the source node +-- flowing = name of the flowing node +-- itemname = name of the new bucket item (or nil if liquid is not takeable) +-- inventory_image = texture of the new bucket item (ignored if itemname == nil) +-- name = text description of the bucket item +-- groups = (optional) groups of the bucket item, for example {water_bucket = 1} +-- This function can be called from any mod (that depends on bucket). +function bucket.register_liquid(source, flowing, itemname, inventory_image, name, groups) + bucket.liquids[source] = { + source = source, + flowing = flowing, + itemname = itemname, + } + bucket.liquids[flowing] = bucket.liquids[source] + + if itemname ~= nil then + minetest.register_craftitem(itemname, { + description = name, + inventory_image = inventory_image, + stack_max = 1, + liquids_pointable = true, + groups = groups, + on_place = function(itemstack, user, pointed_thing) + --priv check here + if minetest.check_player_privs(user.get_player_name(user), {spill=true}) then + + -- Must be pointing to node + if pointed_thing.type ~= "node" then + return + end + + local node = minetest.get_node_or_nil(pointed_thing.under) + local ndef + if node then + ndef = minetest.registered_nodes[node.name] + end + -- Call on_rightclick if the pointed node defines it + if ndef and ndef.on_rightclick and + user and not user:get_player_control().sneak then + return ndef.on_rightclick( + pointed_thing.under, + node, user, + itemstack) or itemstack + end + + local place_liquid = function(pos, node, source, flowing) + if check_protection(pos, + user and user:get_player_name() or "", + "place "..source) then + return + end + minetest.add_node(pos, {name=source}) + minetest.log('action', user:get_player_name()..' placed '..source..' at '..minetest.pos_to_string(pos)) + end + + -- Check if pointing to a buildable node + if ndef and ndef.buildable_to then + -- buildable; replace the node + place_liquid(pointed_thing.under, node, + source, flowing) + else + -- not buildable to; place the liquid above + -- check if the node above can be replaced + local node = minetest.get_node_or_nil(pointed_thing.above) + if node and minetest.registered_nodes[node.name].buildable_to then + place_liquid(pointed_thing.above, + node, source, + flowing) + else + -- do not remove the bucket with the liquid + return + end + end + return {name="bucket:bucket_empty"} + else + minetest.chat_send_player(user:get_player_name(), "You need the spill priv.") + return + end + end + }) + end +end + +minetest.register_craftitem("bucket:bucket_empty", { + description = "Empty Bucket", + inventory_image = "bucket.png", + stack_max = 99, + liquids_pointable = true, + on_use = function(itemstack, user, pointed_thing) + -- Must be pointing to node + if pointed_thing.type ~= "node" then + return + end + -- Check if pointing to a liquid source + local node = minetest.get_node(pointed_thing.under) + local liquiddef = bucket.liquids[node.name] + local item_count = user:get_wielded_item():get_count() + + if liquiddef ~= nil + and liquiddef.itemname ~= nil + and node.name == liquiddef.source then + if check_protection(pointed_thing.under, + user:get_player_name(), + "take ".. node.name) then + return + end + + -- default set to return filled bucket + local giving_back = liquiddef.itemname + + -- check if holding more than 1 empty bucket + if item_count > 1 then + + -- if space in inventory add filled bucked, otherwise drop as item + local inv = user:get_inventory() + if inv:room_for_item("main", {name=liquiddef.itemname}) then + inv:add_item("main", liquiddef.itemname) + else + local pos = user:getpos() + pos.y = math.floor(pos.y + 0.5) + core.add_item(pos, liquiddef.itemname) + end + + -- set to return empty buckets minus 1 + giving_back = "bucket:bucket_empty "..tostring(item_count-1) + + end + + minetest.add_node(pointed_thing.under, {name="air"}) + + return ItemStack(giving_back) + end + end, +}) + +bucket.register_liquid( + "default:water_source", + "default:water_flowing", + "bucket:bucket_water", + "bucket_water.png", + "Water Bucket", + {water_bucket = 1} +) + +bucket.register_liquid( + "default:river_water_source", + "default:river_water_flowing", + "bucket:bucket_river_water", + "bucket_river_water.png", + "River Water Bucket", + {water_bucket = 1} +) + +bucket.register_liquid( + "default:lava_source", + "default:lava_flowing", + "bucket:bucket_lava", + "bucket_lava.png", + "Lava Bucket" +) + +minetest.register_craft({ + type = "fuel", + recipe = "bucket:bucket_lava", + burntime = 60, + replacements = {{"bucket:bucket_lava", "bucket:bucket_empty"}}, +}) + + +-- protected nodes requiring spill priv for placement +-- to add additional nodes, insert new entries for source_list +local source_list = { + "default:water_source", + "default:river_water_source", + "default:lava_source", +} + +for sourcecount = 1, #source_list do + minetest.override_item(source_list[sourcecount], { + on_place = function(itemstack, placer, pointed_thing) + local can_spill = minetest.check_player_privs(placer.get_player_name(placer), {spill=true}) + if not can_spill then + minetest.chat_send_player(placer:get_player_name(), "Ask the Admin if you need to place liquids.") + return + end + return minetest.item_place(itemstack, placer, pointed_thing) + end + }) +end + + +--corium protection +if minetest.get_modpath("technic") then + + minetest.override_item("technic:bucket_corium", { + groups = {not_in_creative_inventory=1}, + }) + minetest.override_item("technic:chernobylite_block", { + groups = {not_in_creative_inventory=1}, + }) + minetest.override_item("technic:corium_source", { + groups = {not_in_creative_inventory=1}, + }) + +end diff --git a/mods/bucket/license.txt b/mods/bucket/license.txt new file mode 100644 index 0000000..ead81cc --- /dev/null +++ b/mods/bucket/license.txt @@ -0,0 +1,21 @@ +License of source code: +----------------------- +Copyright (C) 2011-2012 Kahrl +Copyright (C) 2011-2012 celeron55, Perttu Ahola + +This program 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 of the License, or +(at your option) any later version. + +http://www.gnu.org/licenses/lgpl-2.1.html + +License of media (textures and sounds) +-------------------------------------- +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +Authors of media files +----------------------- +Everything not listed in here: +Copyright (C) 2010-2012 celeron55, Perttu Ahola diff --git a/mods/bucket/mod.conf b/mods/bucket/mod.conf new file mode 100644 index 0000000..dcac9fa --- /dev/null +++ b/mods/bucket/mod.conf @@ -0,0 +1,3 @@ +name = bucket +depends = default +description = Adds priv check for liquids use to limit griefing opportunities. diff --git a/mods/bucket/textures/bucket.png b/mods/bucket/textures/bucket.png new file mode 100644 index 0000000..17b0c49 Binary files /dev/null and b/mods/bucket/textures/bucket.png differ diff --git a/mods/bucket/textures/bucket_lava.png b/mods/bucket/textures/bucket_lava.png new file mode 100644 index 0000000..ac6108d Binary files /dev/null and b/mods/bucket/textures/bucket_lava.png differ diff --git a/mods/bucket/textures/bucket_river_water.png b/mods/bucket/textures/bucket_river_water.png new file mode 100644 index 0000000..d4648bb Binary files /dev/null and b/mods/bucket/textures/bucket_river_water.png differ diff --git a/mods/bucket/textures/bucket_water.png b/mods/bucket/textures/bucket_water.png new file mode 100644 index 0000000..5af836b Binary files /dev/null and b/mods/bucket/textures/bucket_water.png differ diff --git a/mods/butterflies/README.txt b/mods/butterflies/README.txt new file mode 100644 index 0000000..a7f52a0 --- /dev/null +++ b/mods/butterflies/README.txt @@ -0,0 +1,14 @@ +Minetest Game mod: Butterflies +============================== +Adds butterflies to the world on mapgen, which can be caught in a net if the +fireflies mod is also enabled. + +Authors of source code +---------------------- +Shara RedCat (MIT) + +Authors of media (textures) +--------------------------- +Shara RedCat (CC BY-SA 3.0): + butterflies_butterfly_*.png + butterflies_butterfly_*_animated.png \ No newline at end of file diff --git a/mods/butterflies/init.lua b/mods/butterflies/init.lua new file mode 100644 index 0000000..650e7da --- /dev/null +++ b/mods/butterflies/init.lua @@ -0,0 +1,137 @@ +-- butterflies/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("butterflies") + +-- register butterflies +local butter_list = { + {"white", S("White Butterfly")}, + {"red", S("Red Butterfly")}, + {"violet", S("Violet Butterfly")} +} + +for i in ipairs (butter_list) do + local name = butter_list[i][1] + local desc = butter_list[i][2] + + minetest.register_node("butterflies:butterfly_"..name, { + description = desc, + drawtype = "plantlike", + tiles = {{ + name = "butterflies_butterfly_"..name.."_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 3 + }, + }}, + inventory_image = "butterflies_butterfly_"..name..".png", + wield_image = "butterflies_butterfly_"..name..".png", + waving = 1, + paramtype = "light", + sunlight_propagates = true, + buildable_to = true, + walkable = false, + groups = {catchable = 1}, + selection_box = { + type = "fixed", + fixed = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1}, + }, + floodable = true, + on_place = function(itemstack, placer, pointed_thing) + local player_name = placer:get_player_name() + local pos = pointed_thing.above + + if not minetest.is_protected(pos, player_name) and + not minetest.is_protected(pointed_thing.under, player_name) and + minetest.get_node(pos).name == "air" then + minetest.set_node(pos, {name = "butterflies:butterfly_"..name}) + minetest.get_node_timer(pos):start(1) + itemstack:take_item() + end + return itemstack + end, + on_timer = function(pos, elapsed) + if minetest.get_node_light(pos) < 11 then + minetest.set_node(pos, {name = "butterflies:hidden_butterfly_"..name}) + end + minetest.get_node_timer(pos):start(30) + end + }) + + minetest.register_node("butterflies:hidden_butterfly_"..name, { + drawtype = "airlike", + inventory_image = "butterflies_butterfly_"..name..".png", + wield_image = "butterflies_butterfly_"..name..".png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + pointable = false, + diggable = false, + drop = "", + groups = {not_in_creative_inventory = 1}, + floodable = true, + on_place = function(itemstack, placer, pointed_thing) + local player_name = placer:get_player_name() + local pos = pointed_thing.above + + if not minetest.is_protected(pos, player_name) and + not minetest.is_protected(pointed_thing.under, player_name) and + minetest.get_node(pos).name == "air" then + minetest.set_node(pos, {name = "butterflies:hidden_butterfly_"..name}) + minetest.get_node_timer(pos):start(1) + itemstack:take_item() + end + return itemstack + end, + on_timer = function(pos, elapsed) + if minetest.get_node_light(pos) >= 11 then + minetest.set_node(pos, {name = "butterflies:butterfly_"..name}) + end + minetest.get_node_timer(pos):start(30) + end + }) +end + +-- register decoration +minetest.register_decoration({ + name = "butterflies:butterfly", + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + place_offset_y = 2, + sidelen = 80, + fill_ratio = 0.005, + biomes = {"grassland", "deciduous_forest"}, + y_max = 31000, + y_min = 1, + decoration = { + "butterflies:butterfly_white", + "butterflies:butterfly_red", + "butterflies:butterfly_violet" + }, + spawn_by = "group:flower", + num_spawn_by = 1 +}) + +-- get decoration ID +local butterflies = minetest.get_decoration_id("butterflies:butterfly") +minetest.set_gen_notify({decoration = true}, {butterflies}) + +-- start nodetimers +minetest.register_on_generated(function(minp, maxp, blockseed) + local gennotify = minetest.get_mapgen_object("gennotify") + local poslist = {} + + for _, pos in ipairs(gennotify["decoration#"..butterflies] or {}) do + local deco_pos = {x = pos.x, y = pos.y + 3, z = pos.z} + table.insert(poslist, deco_pos) + end + + if #poslist ~= 0 then + for i = 1, #poslist do + local pos = poslist[i] + minetest.get_node_timer(pos):start(1) + end + end +end) diff --git a/mods/butterflies/license.txt b/mods/butterflies/license.txt new file mode 100644 index 0000000..eebdad6 --- /dev/null +++ b/mods/butterflies/license.txt @@ -0,0 +1,58 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (c) 2018 Shara RedCat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2018 Shara RedCat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ \ No newline at end of file diff --git a/mods/butterflies/locale/butterflies.de.tr b/mods/butterflies/locale/butterflies.de.tr new file mode 100644 index 0000000..2f1b982 --- /dev/null +++ b/mods/butterflies/locale/butterflies.de.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=Weißer Schmetterling +Red Butterfly=Roter Schmetterling +Violet Butterfly=Violetter Schmetterling diff --git a/mods/butterflies/locale/butterflies.es.tr b/mods/butterflies/locale/butterflies.es.tr new file mode 100644 index 0000000..59a28eb --- /dev/null +++ b/mods/butterflies/locale/butterflies.es.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=Mariposa blanca +Red Butterfly=Mariposa roja +Violet Butterfly=Mariposa violeta diff --git a/mods/butterflies/locale/butterflies.fr.tr b/mods/butterflies/locale/butterflies.fr.tr new file mode 100644 index 0000000..8f5c094 --- /dev/null +++ b/mods/butterflies/locale/butterflies.fr.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=Papillon blanc +Red Butterfly=Papillon rouge +Violet Butterfly=Papillon violet diff --git a/mods/butterflies/locale/butterflies.it.tr b/mods/butterflies/locale/butterflies.it.tr new file mode 100644 index 0000000..104ec88 --- /dev/null +++ b/mods/butterflies/locale/butterflies.it.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=Farfalla bianca +Red Butterfly=Farfalla rossa +Violet Butterfly=Farfalla viola \ No newline at end of file diff --git a/mods/butterflies/locale/butterflies.ms.tr b/mods/butterflies/locale/butterflies.ms.tr new file mode 100644 index 0000000..b8bde85 --- /dev/null +++ b/mods/butterflies/locale/butterflies.ms.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=Rama-Rama Putih +Red Butterfly=Rama-Rama Merah +Violet Butterfly=Rama-Rama Ungu diff --git a/mods/butterflies/locale/butterflies.ru.tr b/mods/butterflies/locale/butterflies.ru.tr new file mode 100644 index 0000000..7a79ed8 --- /dev/null +++ b/mods/butterflies/locale/butterflies.ru.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=Ð‘ÐµÐ»Ð°Ñ Ð‘Ð°Ð±Ð¾Ñ‡ÐºÐ° +Red Butterfly=КраÑÐ½Ð°Ñ Ð‘Ð°Ð±Ð¾Ñ‡ÐºÐ° +Violet Butterfly=Ð¤Ð¸Ð¾Ð»ÐµÑ‚Ð¾Ð²Ð°Ñ Ð‘Ð°Ð±Ð¾Ñ‡ÐºÐ° diff --git a/mods/butterflies/locale/butterflies.se.tr b/mods/butterflies/locale/butterflies.se.tr new file mode 100644 index 0000000..08cb94c --- /dev/null +++ b/mods/butterflies/locale/butterflies.se.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=Vit fjäril +Red Butterfly=Röd fjäril +Violet Butterfly=Violett fjäril \ No newline at end of file diff --git a/mods/butterflies/locale/butterflies.zh_CN.tr b/mods/butterflies/locale/butterflies.zh_CN.tr new file mode 100644 index 0000000..24e0bd1 --- /dev/null +++ b/mods/butterflies/locale/butterflies.zh_CN.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=白è´è¶ +Red Butterfly=红è´è¶ +Violet Butterfly=ç´«è´è¶ diff --git a/mods/butterflies/locale/butterflies.zh_TW.tr b/mods/butterflies/locale/butterflies.zh_TW.tr new file mode 100644 index 0000000..8d927c1 --- /dev/null +++ b/mods/butterflies/locale/butterflies.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly=白è´è¶ +Red Butterfly=ç´…è´è¶ +Violet Butterfly=ç´«è´è¶ diff --git a/mods/butterflies/locale/template.txt b/mods/butterflies/locale/template.txt new file mode 100644 index 0000000..d89503a --- /dev/null +++ b/mods/butterflies/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: butterflies +White Butterfly= +Red Butterfly= +Violet Butterfly= diff --git a/mods/butterflies/mod.conf b/mods/butterflies/mod.conf new file mode 100644 index 0000000..1c66497 --- /dev/null +++ b/mods/butterflies/mod.conf @@ -0,0 +1,3 @@ +name = butterflies +description = Minetest Game mod: Butterflies +depends = default, flowers diff --git a/mods/butterflies/textures/butterflies_butterfly_red.png b/mods/butterflies/textures/butterflies_butterfly_red.png new file mode 100644 index 0000000..8edfc36 Binary files /dev/null and b/mods/butterflies/textures/butterflies_butterfly_red.png differ diff --git a/mods/butterflies/textures/butterflies_butterfly_red_animated.png b/mods/butterflies/textures/butterflies_butterfly_red_animated.png new file mode 100644 index 0000000..4a2097b Binary files /dev/null and b/mods/butterflies/textures/butterflies_butterfly_red_animated.png differ diff --git a/mods/butterflies/textures/butterflies_butterfly_violet.png b/mods/butterflies/textures/butterflies_butterfly_violet.png new file mode 100644 index 0000000..8b8c29d Binary files /dev/null and b/mods/butterflies/textures/butterflies_butterfly_violet.png differ diff --git a/mods/butterflies/textures/butterflies_butterfly_violet_animated.png b/mods/butterflies/textures/butterflies_butterfly_violet_animated.png new file mode 100644 index 0000000..3f9d72e Binary files /dev/null and b/mods/butterflies/textures/butterflies_butterfly_violet_animated.png differ diff --git a/mods/butterflies/textures/butterflies_butterfly_white.png b/mods/butterflies/textures/butterflies_butterfly_white.png new file mode 100644 index 0000000..db4eaec Binary files /dev/null and b/mods/butterflies/textures/butterflies_butterfly_white.png differ diff --git a/mods/butterflies/textures/butterflies_butterfly_white_animated.png b/mods/butterflies/textures/butterflies_butterfly_white_animated.png new file mode 100644 index 0000000..e7cada3 Binary files /dev/null and b/mods/butterflies/textures/butterflies_butterfly_white_animated.png differ diff --git a/mods/carts/README.txt b/mods/carts/README.txt new file mode 100644 index 0000000..c0be2d7 --- /dev/null +++ b/mods/carts/README.txt @@ -0,0 +1,23 @@ +Carts (formerly boost_cart) +========================== + +Carts, based almost entirely on the mod boost_cart [1], which +itself is based on (and fully compatible with) the carts mod [2]. + +The model was originally designed by stujones11 [3] (CC-0). + +Cart textures are based on original work from PixelBOX by Gambit (permissive +license). + + +[1] https://github.com/SmallJoker/boost_cart/ +[2] https://github.com/PilzAdam/carts/ +[3] https://github.com/stujones11/railcart/ + + +Features +---------- +- A fast cart for your railway or roller coaster (up to 7 m/s!) +- Boost and brake rails +- Rail junction switching with the 'right-left' walking keys +- Handbrake with the 'back' key diff --git a/mods/carts/cart_entity.lua b/mods/carts/cart_entity.lua new file mode 100644 index 0000000..efa1769 --- /dev/null +++ b/mods/carts/cart_entity.lua @@ -0,0 +1,433 @@ +-- carts/cart_entity.lua + +-- support for MT game translation. +local S = carts.get_translator + +local cart_entity = { + initial_properties = { + physical = false, -- otherwise going uphill breaks + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + visual = "mesh", + mesh = "carts_cart.b3d", + visual_size = {x=1, y=1}, + textures = {"carts_cart.png"}, + }, + + driver = nil, + punched = false, -- used to re-send velocity and position + velocity = {x=0, y=0, z=0}, -- only used on punch + old_dir = {x=1, y=0, z=0}, -- random value to start the cart on punch + old_pos = nil, + old_switch = 0, + railtype = nil, + attached_items = {} +} + +function cart_entity:on_rightclick(clicker) + if not clicker or not clicker:is_player() then + return + end + local player_name = clicker:get_player_name() + if self.driver and player_name == self.driver then + self.driver = nil + carts:manage_attachment(clicker, nil) + elseif not self.driver then + self.driver = player_name + carts:manage_attachment(clicker, self.object) + + -- player_api does not update the animation + -- when the player is attached, reset to default animation + player_api.set_animation(clicker, "stand") + end +end + +function cart_entity:on_activate(staticdata, dtime_s) + self.object:set_armor_groups({immortal=1}) + if string.sub(staticdata, 1, string.len("return")) ~= "return" then + return + end + local data = minetest.deserialize(staticdata) + if type(data) ~= "table" then + return + end + self.railtype = data.railtype + if data.old_dir then + self.old_dir = data.old_dir + end +end + +function cart_entity:get_staticdata() + return minetest.serialize({ + railtype = self.railtype, + old_dir = self.old_dir + }) +end + +-- 0.5.x and later: When the driver leaves +function cart_entity:on_detach_child(child) + if child and child:get_player_name() == self.driver then + self.driver = nil + carts:manage_attachment(child, nil) + end +end + +function cart_entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) + local pos = self.object:get_pos() + local vel = self.object:get_velocity() + if not self.railtype or vector.equals(vel, {x=0, y=0, z=0}) then + local node = minetest.get_node(pos).name + self.railtype = minetest.get_item_group(node, "connect_to_raillike") + end + -- Punched by non-player + if not puncher or not puncher:is_player() then + local cart_dir = carts:get_rail_direction(pos, self.old_dir, nil, nil, self.railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return + end + self.velocity = vector.multiply(cart_dir, 2) + self.punched = true + return + end + -- Player digs cart by sneak-punch + if puncher:get_player_control().sneak then + if self.sound_handle then + minetest.sound_stop(self.sound_handle) + end + -- Detach driver and items + if self.driver then + if self.old_pos then + self.object:set_pos(self.old_pos) + end + local player = minetest.get_player_by_name(self.driver) + carts:manage_attachment(player, nil) + end + for _, obj_ in ipairs(self.attached_items) do + if obj_ then + obj_:set_detach() + end + end + -- Pick up cart + local inv = puncher:get_inventory() + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(puncher:get_player_name())) + or not inv:contains_item("main", "carts:cart") then + local leftover = inv:add_item("main", "carts:cart") + -- If no room in inventory add a replacement cart to the world + if not leftover:is_empty() then + minetest.add_item(self.object:get_pos(), leftover) + end + end + self.object:remove() + return + end + -- Player punches cart to alter velocity + if puncher:get_player_name() == self.driver then + if math.abs(vel.x + vel.z) > carts.punch_speed_max then + return + end + end + + local punch_dir = carts:velocity_to_dir(puncher:get_look_dir()) + punch_dir.y = 0 + local cart_dir = carts:get_rail_direction(pos, punch_dir, nil, nil, self.railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return + end + + local punch_interval = 1 + if tool_capabilities and tool_capabilities.full_punch_interval then + punch_interval = tool_capabilities.full_punch_interval + end + time_from_last_punch = math.min(time_from_last_punch or punch_interval, punch_interval) + local f = 2 * (time_from_last_punch / punch_interval) + + self.velocity = vector.multiply(cart_dir, f) + self.old_dir = cart_dir + self.punched = true +end + +local function rail_on_step_event(handler, obj, dtime) + if handler then + handler(obj, dtime) + end +end + +-- sound refresh interval = 1.0sec +local function rail_sound(self, dtime) + if not self.sound_ttl then + self.sound_ttl = 1.0 + return + elseif self.sound_ttl > 0 then + self.sound_ttl = self.sound_ttl - dtime + return + end + self.sound_ttl = 1.0 + if self.sound_handle then + local handle = self.sound_handle + self.sound_handle = nil + minetest.after(0.2, minetest.sound_stop, handle) + end + local vel = self.object:get_velocity() + local speed = vector.length(vel) + if speed > 0 then + self.sound_handle = minetest.sound_play( + "carts_cart_moving", { + object = self.object, + gain = (speed / carts.speed_max) / 2, + loop = true, + }) + end +end + +local function get_railparams(pos) + local node = minetest.get_node(pos) + return carts.railparams[node.name] or {} +end + +local v3_len = vector.length +local function rail_on_step(self, dtime) + local vel = self.object:get_velocity() + if self.punched then + vel = vector.add(vel, self.velocity) + self.object:set_velocity(vel) + self.old_dir.y = 0 + elseif vector.equals(vel, {x=0, y=0, z=0}) then + return + end + + local pos = self.object:get_pos() + local cart_dir = carts:velocity_to_dir(vel) + local same_dir = vector.equals(cart_dir, self.old_dir) + local update = {} + + if self.old_pos and not self.punched and same_dir then + local flo_pos = vector.round(pos) + local flo_old = vector.round(self.old_pos) + if vector.equals(flo_pos, flo_old) then + -- Do not check one node multiple times + return + end + end + + local ctrl, player + + -- Get player controls + if self.driver then + player = minetest.get_player_by_name(self.driver) + if player then + ctrl = player:get_player_control() + end + end + + local stop_wiggle = false + if self.old_pos and same_dir then + -- Detection for "skipping" nodes (perhaps use average dtime?) + -- It's sophisticated enough to take the acceleration in account + local acc = self.object:get_acceleration() + local distance = dtime * (v3_len(vel) + 0.5 * dtime * v3_len(acc)) + + local new_pos, new_dir = carts:pathfinder( + pos, self.old_pos, self.old_dir, distance, ctrl, + self.old_switch, self.railtype + ) + + if new_pos then + -- No rail found: set to the expected position + pos = new_pos + update.pos = true + cart_dir = new_dir + end + elseif self.old_pos and self.old_dir.y ~= 1 and not self.punched then + -- Stop wiggle + stop_wiggle = true + end + + local railparams + + -- dir: New moving direction of the cart + -- switch_keys: Currently pressed L/R key, used to ignore the key on the next rail node + local dir, switch_keys = carts:get_rail_direction( + pos, cart_dir, ctrl, self.old_switch, self.railtype + ) + local dir_changed = not vector.equals(dir, self.old_dir) + + local new_acc = {x=0, y=0, z=0} + if stop_wiggle or vector.equals(dir, {x=0, y=0, z=0}) then + vel = {x = 0, y = 0, z = 0} + local pos_r = vector.round(pos) + if not carts:is_rail(pos_r, self.railtype) + and self.old_pos then + pos = self.old_pos + elseif not stop_wiggle then + pos = pos_r + else + pos.y = math.floor(pos.y + 0.5) + end + update.pos = true + update.vel = true + else + -- Direction change detected + if dir_changed then + vel = vector.multiply(dir, math.abs(vel.x + vel.z)) + update.vel = true + if dir.y ~= self.old_dir.y then + pos = vector.round(pos) + update.pos = true + end + end + -- Center on the rail + if dir.z ~= 0 and math.floor(pos.x + 0.5) ~= pos.x then + pos.x = math.floor(pos.x + 0.5) + update.pos = true + end + if dir.x ~= 0 and math.floor(pos.z + 0.5) ~= pos.z then + pos.z = math.floor(pos.z + 0.5) + update.pos = true + end + + -- Slow down or speed up.. + local acc = dir.y * -4.0 + + -- Get rail for corrected position + railparams = get_railparams(pos) + + -- no need to check for railparams == nil since we always make it exist. + local speed_mod = railparams.acceleration + if speed_mod and speed_mod ~= 0 then + -- Try to make it similar to the original carts mod + acc = acc + speed_mod + else + -- Handbrake or coast + if ctrl and ctrl.down then + acc = acc - 3 + else + acc = acc - 0.4 + end + end + + new_acc = vector.multiply(dir, acc) + end + + -- Limits + local max_vel = carts.speed_max + for _, v in pairs({"x","y","z"}) do + if math.abs(vel[v]) > max_vel then + vel[v] = carts:get_sign(vel[v]) * max_vel + new_acc[v] = 0 + update.vel = true + end + end + + self.object:set_acceleration(new_acc) + self.old_pos = vector.round(pos) + if not vector.equals(dir, {x=0, y=0, z=0}) and not stop_wiggle then + self.old_dir = vector.new(dir) + end + self.old_switch = switch_keys + + if self.punched then + -- Collect dropped items + for _, obj_ in pairs(minetest.get_objects_inside_radius(pos, 1)) do + local ent = obj_:get_luaentity() + -- Careful here: physical_state and disable_physics are item-internal APIs + if ent and ent.name == "__builtin:item" and ent.physical_state then + ent:disable_physics() + obj_:set_attach(self.object, "", {x=0, y=0, z=0}, {x=0, y=0, z=0}) + self.attached_items[#self.attached_items + 1] = obj_ + end + end + self.punched = false + update.vel = true + end + + railparams = railparams or get_railparams(pos) + + if not (update.vel or update.pos) then + rail_on_step_event(railparams.on_step, self, dtime) + return + end + + local yaw = 0 + if self.old_dir.x < 0 then + yaw = 0.5 + elseif self.old_dir.x > 0 then + yaw = 1.5 + elseif self.old_dir.z < 0 then + yaw = 1 + end + self.object:set_yaw(yaw * math.pi) + + local anim = {x=0, y=0} + if dir.y == -1 then + anim = {x=1, y=1} + elseif dir.y == 1 then + anim = {x=2, y=2} + end + self.object:set_animation(anim, 1, 0) + + if update.vel then + self.object:set_velocity(vel) + end + if update.pos then + if dir_changed then + self.object:set_pos(pos) + else + self.object:move_to(pos) + end + end + + -- call event handler + rail_on_step_event(railparams.on_step, self, dtime) +end + +function cart_entity:on_step(dtime) + rail_on_step(self, dtime) + rail_sound(self, dtime) +end + +minetest.register_entity("carts:cart", cart_entity) + +minetest.register_craftitem("carts:cart", { + description = S("Cart") .. "\n" .. S("(Sneak+Click to pick up)"), + inventory_image = minetest.inventorycube("carts_cart_top.png", "carts_cart_front.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:is_player() 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 + if carts:is_rail(pointed_thing.under) then + minetest.add_entity(pointed_thing.under, "carts:cart") + elseif carts:is_rail(pointed_thing.above) then + minetest.add_entity(pointed_thing.above, "carts:cart") + else + return + end + + minetest.sound_play({name = "default_place_node_metal", gain = 0.5}, + {pos = pointed_thing.above}, true) + + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(placer:get_player_name())) then + itemstack:take_item() + end + return itemstack + end, +}) + +minetest.register_craft({ + output = "carts:cart", + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + }, +}) diff --git a/mods/carts/functions.lua b/mods/carts/functions.lua new file mode 100644 index 0000000..a54b594 --- /dev/null +++ b/mods/carts/functions.lua @@ -0,0 +1,248 @@ +function carts:get_sign(z) + if z == 0 then + return 0 + else + return z / math.abs(z) + end +end + +function carts:manage_attachment(player, obj) + if not player then + return + end + local status = obj ~= nil + local player_name = player:get_player_name() + if player_api.player_attached[player_name] == status then + return + end + player_api.player_attached[player_name] = status + + if status then + player:set_attach(obj, "", {x=0, y=-4.5, z=0}, {x=0, y=0, z=0}) + player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0}) + else + player:set_detach() + player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) + end +end + +function carts:velocity_to_dir(v) + if math.abs(v.x) > math.abs(v.z) then + return {x=carts:get_sign(v.x), y=carts:get_sign(v.y), z=0} + else + return {x=0, y=carts:get_sign(v.y), z=carts:get_sign(v.z)} + end +end + +function carts:is_rail(pos, railtype) + local node = minetest.get_node(pos).name + if node == "ignore" then + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(pos, pos) + local area = VoxelArea:new{ + MinEdge = emin, + MaxEdge = emax, + } + local data = vm:get_data() + local vi = area:indexp(pos) + node = minetest.get_name_from_content_id(data[vi]) + end + if minetest.get_item_group(node, "rail") == 0 then + return false + end + if not railtype then + return true + end + return minetest.get_item_group(node, "connect_to_raillike") == railtype +end + +function carts:check_front_up_down(pos, dir_, check_up, railtype) + local dir = vector.new(dir_) + local cur + + -- Front + dir.y = 0 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + -- Up + if check_up then + dir.y = 1 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + end + -- Down + dir.y = -1 + cur = vector.add(pos, dir) + if carts:is_rail(cur, railtype) then + return dir + end + return nil +end + +function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) + local pos = vector.round(pos_) + local cur + local left_check, right_check = true, true + + -- Check left and right + local left = {x=0, y=0, z=0} + local right = {x=0, y=0, z=0} + if dir.z ~= 0 and dir.x == 0 then + left.x = -dir.z + right.x = dir.z + elseif dir.x ~= 0 and dir.z == 0 then + left.z = dir.x + right.z = -dir.x + end + + local straight_priority = ctrl and dir.y ~= 0 + + -- Normal, to disallow rail switching up- & downhill + if straight_priority then + cur = self:check_front_up_down(pos, dir, true, railtype) + if cur then + return cur + end + end + + if ctrl then + if old_switch == 1 then + left_check = false + elseif old_switch == 2 then + right_check = false + end + if ctrl.left and left_check then + cur = self:check_front_up_down(pos, left, false, railtype) + if cur then + return cur, 1 + end + left_check = false + end + if ctrl.right and right_check then + cur = self:check_front_up_down(pos, right, false, railtype) + if cur then + return cur, 2 + end + right_check = true + end + end + + -- Normal + if not straight_priority then + cur = self:check_front_up_down(pos, dir, true, railtype) + if cur then + return cur + end + end + + -- Left, if not already checked + if left_check then + cur = carts:check_front_up_down(pos, left, false, railtype) + if cur then + return cur + end + end + + -- Right, if not already checked + if right_check then + cur = carts:check_front_up_down(pos, right, false, railtype) + if cur then + return cur + end + end + + -- Backwards + if not old_switch then + cur = carts:check_front_up_down(pos, { + x = -dir.x, + y = dir.y, + z = -dir.z + }, true, railtype) + if cur then + return cur + end + end + + return {x=0, y=0, z=0} +end + +function carts:pathfinder(pos_, old_pos, old_dir, distance, ctrl, + pf_switch, railtype) + + local pos = vector.round(pos_) + if vector.equals(old_pos, pos) then + return + end + + local pf_pos = vector.round(old_pos) + local pf_dir = vector.new(old_dir) + distance = math.min(carts.path_distance_max, + math.floor(distance + 1)) + + for i = 1, distance do + pf_dir, pf_switch = self:get_rail_direction( + pf_pos, pf_dir, ctrl, pf_switch or 0, railtype) + + if vector.equals(pf_dir, {x=0, y=0, z=0}) then + -- No way forwards + return pf_pos, pf_dir + end + + pf_pos = vector.add(pf_pos, pf_dir) + + if vector.equals(pf_pos, pos) then + -- Success! Cart moved on correctly + return + end + end + -- Not found. Put cart to predicted position + return pf_pos, pf_dir +end + +function carts:register_rail(name, def_overwrite, railparams) + local def = { + drawtype = "raillike", + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + sounds = default.node_sound_metal_defaults() + } + for k, v in pairs(def_overwrite) do + def[k] = v + end + if not def.inventory_image then + def.wield_image = def.tiles[1] + def.inventory_image = def.tiles[1] + end + + if railparams then + carts.railparams[name] = table.copy(railparams) + end + + minetest.register_node(name, def) +end + +function carts:get_rail_groups(additional_groups) + -- Get the default rail groups and add more when a table is given + local groups = { + dig_immediate = 2, + attached_node = 1, + rail = 1, + connect_to_raillike = minetest.raillike_group("rail") + } + if type(additional_groups) == "table" then + for k, v in pairs(additional_groups) do + groups[k] = v + end + end + return groups +end diff --git a/mods/carts/init.lua b/mods/carts/init.lua new file mode 100644 index 0000000..69d59d9 --- /dev/null +++ b/mods/carts/init.lua @@ -0,0 +1,28 @@ +-- carts/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("carts") + +carts = {} +carts.modpath = minetest.get_modpath("carts") +carts.railparams = {} +carts.get_translator = S + +-- Maximal speed of the cart in m/s (min = -1) +carts.speed_max = 7 +-- Set to -1 to disable punching the cart from inside (min = -1) +carts.punch_speed_max = 5 +-- Maximal distance for the path correction (for dtime peaks) +carts.path_distance_max = 3 + + +dofile(carts.modpath.."/functions.lua") +dofile(carts.modpath.."/rails.lua") +dofile(carts.modpath.."/cart_entity.lua") + +-- Register rails as dungeon loot +if minetest.global_exists("dungeon_loot") then + dungeon_loot.register({ + name = "carts:rail", chance = 0.35, count = {1, 6} + }) +end diff --git a/mods/carts/license.txt b/mods/carts/license.txt new file mode 100644 index 0000000..6c5beb4 --- /dev/null +++ b/mods/carts/license.txt @@ -0,0 +1,54 @@ + +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 SmallJoker +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media +----------------- + +CC-0, see: https://creativecommons.org/share-your-work/public-domain/cc0/, except +if other license is mentioned. + + +Authors +--------- +Originally from PixelBOX (Gambit): + carts_cart_side.png + carts_cart_top.png + carts_cart_front.png* + carts_cart.png* + +sofar + stujones11: + carts_cart.b3d and carts_cart.blend + +hexafraction, modified by sofar + carts_rail_*.png + +http://www.freesound.org/people/YleArkisto/sounds/253159/ - YleArkisto - CC-BY-3.0 + carts_cart_moving.*.ogg diff --git a/mods/carts/locale/carts.de.tr b/mods/carts/locale/carts.de.tr new file mode 100644 index 0000000..89a33ac --- /dev/null +++ b/mods/carts/locale/carts.de.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=Lore +(Sneak+Click to pick up)=(Schleichen u. Klicken zum Aufheben) +Rail=Schiene +Powered Rail=Antriebsschiene +Brake Rail=Bremsschiene diff --git a/mods/carts/locale/carts.es.tr b/mods/carts/locale/carts.es.tr new file mode 100644 index 0000000..c0857a1 --- /dev/null +++ b/mods/carts/locale/carts.es.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=Vagoneta +(Sneak+Click to pick up)=(Agacharse+Clic para recoger) +Rail=Raíl +Powered Rail=Raíl energizado +Brake Rail=Raíl de frenado diff --git a/mods/carts/locale/carts.fr.tr b/mods/carts/locale/carts.fr.tr new file mode 100644 index 0000000..b092f14 --- /dev/null +++ b/mods/carts/locale/carts.fr.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=Chariot +(Sneak+Click to pick up)=(Se baisser + clic pour ramasser) +Rail=Rail +Powered Rail=Rail de traction +Brake Rail=Rail de freinage diff --git a/mods/carts/locale/carts.it.tr b/mods/carts/locale/carts.it.tr new file mode 100644 index 0000000..546471c --- /dev/null +++ b/mods/carts/locale/carts.it.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=Vagone +(Sneak+Click to pick up)=(Strisciare+Click per raccoglierlo) +Rail=Binario +Powered Rail=Binario alimentato +Brake Rail=Binario freno \ No newline at end of file diff --git a/mods/carts/locale/carts.ms.tr b/mods/carts/locale/carts.ms.tr new file mode 100644 index 0000000..e8944e9 --- /dev/null +++ b/mods/carts/locale/carts.ms.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=Pedati +(Sneak+Click to pick up)=(Selinap+Klik untuk ambil balik) +Rail=Landasan +Powered Rail=Landasan Berkuasa +Brake Rail=Landasan Brek diff --git a/mods/carts/locale/carts.ru.tr b/mods/carts/locale/carts.ru.tr new file mode 100644 index 0000000..6ff5be6 --- /dev/null +++ b/mods/carts/locale/carts.ru.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=Вагонетка +(Sneak+Click to pick up)=(ПригнитеÑÑŒ и кликните по вагонетке, чтобы забрать) +Rail=РельÑа +Powered Rail=ÐœÐµÑ…Ð°Ð½Ð¸Ð·Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð ÐµÐ»ÑŒÑа +Brake Rail=РельÑа Ñ Ñ‚Ð¾Ñ€Ð¼Ð¾Ð·Ð¾Ð¼ diff --git a/mods/carts/locale/carts.se.tr b/mods/carts/locale/carts.se.tr new file mode 100644 index 0000000..e40f8ca --- /dev/null +++ b/mods/carts/locale/carts.se.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=Vagn +(Sneak+Click to pick up)=(Shift+Klicka för att plocka upp) +Rail=Räls +Powered Rail=Aktiverad räls +Brake Rail=Broms räls \ No newline at end of file diff --git a/mods/carts/locale/carts.zh_CN.tr b/mods/carts/locale/carts.zh_CN.tr new file mode 100644 index 0000000..953cdef --- /dev/null +++ b/mods/carts/locale/carts.zh_CN.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=矿车 +(Sneak+Click to pick up)=(潜行+å•å‡»ä»¥æ¡èµ·ï¼‰ +Rail=é“轨 +Powered Rail=动力é“轨 +Brake Rail=制动é“轨 diff --git a/mods/carts/locale/carts.zh_TW.tr b/mods/carts/locale/carts.zh_TW.tr new file mode 100644 index 0000000..f6300d4 --- /dev/null +++ b/mods/carts/locale/carts.zh_TW.tr @@ -0,0 +1,6 @@ +# textdomain: carts +Cart=礦車 +(Sneak+Click to pick up)=(潛行+單擊以撿起) +Rail=éµè»Œ +Powered Rail=動力éµè»Œ +Brake Rail=制動éµè»Œ diff --git a/mods/carts/locale/template.txt b/mods/carts/locale/template.txt new file mode 100644 index 0000000..a67d95f --- /dev/null +++ b/mods/carts/locale/template.txt @@ -0,0 +1,6 @@ +# textdomain: carts +Cart= +(Sneak+Click to pick up)= +Rail= +Powered Rail= +Brake Rail= diff --git a/mods/carts/mod.conf b/mods/carts/mod.conf new file mode 100644 index 0000000..0eab35c --- /dev/null +++ b/mods/carts/mod.conf @@ -0,0 +1,4 @@ +name = carts +description = Carts (formerly boost_cart) +depends = default, player_api +optional_depends = dungeon_loot diff --git a/mods/carts/models/carts_cart.b3d b/mods/carts/models/carts_cart.b3d new file mode 100644 index 0000000..4e7eba3 Binary files /dev/null and b/mods/carts/models/carts_cart.b3d differ diff --git a/mods/carts/models/carts_cart.blend b/mods/carts/models/carts_cart.blend new file mode 100644 index 0000000..7d2515e Binary files /dev/null and b/mods/carts/models/carts_cart.blend differ diff --git a/mods/carts/rails.lua b/mods/carts/rails.lua new file mode 100644 index 0000000..8bd2ba1 --- /dev/null +++ b/mods/carts/rails.lua @@ -0,0 +1,64 @@ +-- carts/rails.lua + +-- support for MT game translation. +local S = carts.get_translator + +carts:register_rail("carts:rail", { + description = S("Rail"), + tiles = { + "carts_rail_straight.png", "carts_rail_curved.png", + "carts_rail_t_junction.png", "carts_rail_crossing.png" + }, + inventory_image = "carts_rail_straight.png", + wield_image = "carts_rail_straight.png", + groups = carts:get_rail_groups(), +}, {}) + +minetest.register_craft({ + output = "carts:rail 18", + recipe = { + {"default:steel_ingot", "group:wood", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "group:wood", "default:steel_ingot"}, + } +}) + +minetest.register_alias("default:rail", "carts:rail") + + +carts:register_rail("carts:powerrail", { + description = S("Powered Rail"), + tiles = { + "carts_rail_straight_pwr.png", "carts_rail_curved_pwr.png", + "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png" + }, + groups = carts:get_rail_groups(), +}, {acceleration = 5}) + +minetest.register_craft({ + output = "carts:powerrail 18", + recipe = { + {"default:steel_ingot", "group:wood", "default:steel_ingot"}, + {"default:steel_ingot", "default:mese_crystal", "default:steel_ingot"}, + {"default:steel_ingot", "group:wood", "default:steel_ingot"}, + } +}) + + +carts:register_rail("carts:brakerail", { + description = S("Brake Rail"), + tiles = { + "carts_rail_straight_brk.png", "carts_rail_curved_brk.png", + "carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png" + }, + groups = carts:get_rail_groups(), +}, {acceleration = -3}) + +minetest.register_craft({ + output = "carts:brakerail 18", + recipe = { + {"default:steel_ingot", "group:wood", "default:steel_ingot"}, + {"default:steel_ingot", "default:coal_lump", "default:steel_ingot"}, + {"default:steel_ingot", "group:wood", "default:steel_ingot"}, + } +}) diff --git a/mods/carts/sounds/carts_cart_moving.1.ogg b/mods/carts/sounds/carts_cart_moving.1.ogg new file mode 100644 index 0000000..869e765 Binary files /dev/null and b/mods/carts/sounds/carts_cart_moving.1.ogg differ diff --git a/mods/carts/sounds/carts_cart_moving.2.ogg b/mods/carts/sounds/carts_cart_moving.2.ogg new file mode 100644 index 0000000..b4cc508 Binary files /dev/null and b/mods/carts/sounds/carts_cart_moving.2.ogg differ diff --git a/mods/carts/sounds/carts_cart_moving.3.ogg b/mods/carts/sounds/carts_cart_moving.3.ogg new file mode 100644 index 0000000..e19a782 Binary files /dev/null and b/mods/carts/sounds/carts_cart_moving.3.ogg differ diff --git a/mods/carts/textures/carts_cart.png b/mods/carts/textures/carts_cart.png new file mode 100644 index 0000000..965347c Binary files /dev/null and b/mods/carts/textures/carts_cart.png differ diff --git a/mods/carts/textures/carts_cart_front.png b/mods/carts/textures/carts_cart_front.png new file mode 100644 index 0000000..38955b2 Binary files /dev/null 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 new file mode 100644 index 0000000..f53808c Binary files /dev/null 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 new file mode 100644 index 0000000..d9a31a9 Binary files /dev/null and b/mods/carts/textures/carts_cart_top.png differ diff --git a/mods/carts/textures/carts_rail_crossing.png b/mods/carts/textures/carts_rail_crossing.png new file mode 100644 index 0000000..e10f3b1 Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing.png differ diff --git a/mods/carts/textures/carts_rail_crossing_brk.png b/mods/carts/textures/carts_rail_crossing_brk.png new file mode 100644 index 0000000..14d4e1a Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing_brk.png differ diff --git a/mods/carts/textures/carts_rail_crossing_pwr.png b/mods/carts/textures/carts_rail_crossing_pwr.png new file mode 100644 index 0000000..d763d50 Binary files /dev/null and b/mods/carts/textures/carts_rail_crossing_pwr.png differ diff --git a/mods/carts/textures/carts_rail_curved.png b/mods/carts/textures/carts_rail_curved.png new file mode 100644 index 0000000..b320f0d Binary files /dev/null and b/mods/carts/textures/carts_rail_curved.png differ diff --git a/mods/carts/textures/carts_rail_curved_brk.png b/mods/carts/textures/carts_rail_curved_brk.png new file mode 100644 index 0000000..c5affd8 Binary files /dev/null and b/mods/carts/textures/carts_rail_curved_brk.png differ diff --git a/mods/carts/textures/carts_rail_curved_pwr.png b/mods/carts/textures/carts_rail_curved_pwr.png new file mode 100644 index 0000000..781bbd0 Binary files /dev/null and b/mods/carts/textures/carts_rail_curved_pwr.png differ diff --git a/mods/carts/textures/carts_rail_straight.png b/mods/carts/textures/carts_rail_straight.png new file mode 100644 index 0000000..30dcafe Binary files /dev/null and b/mods/carts/textures/carts_rail_straight.png differ diff --git a/mods/carts/textures/carts_rail_straight_brk.png b/mods/carts/textures/carts_rail_straight_brk.png new file mode 100644 index 0000000..7853ac8 Binary files /dev/null and b/mods/carts/textures/carts_rail_straight_brk.png differ diff --git a/mods/carts/textures/carts_rail_straight_pwr.png b/mods/carts/textures/carts_rail_straight_pwr.png new file mode 100644 index 0000000..e067ff1 Binary files /dev/null and b/mods/carts/textures/carts_rail_straight_pwr.png differ diff --git a/mods/carts/textures/carts_rail_t_junction.png b/mods/carts/textures/carts_rail_t_junction.png new file mode 100644 index 0000000..8b1b946 Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction.png differ diff --git a/mods/carts/textures/carts_rail_t_junction_brk.png b/mods/carts/textures/carts_rail_t_junction_brk.png new file mode 100644 index 0000000..8e3f620 Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction_brk.png differ diff --git a/mods/carts/textures/carts_rail_t_junction_pwr.png b/mods/carts/textures/carts_rail_t_junction_pwr.png new file mode 100644 index 0000000..dd0eede Binary files /dev/null and b/mods/carts/textures/carts_rail_t_junction_pwr.png differ diff --git a/mods/castle_farming/LICENSE b/mods/castle_farming/LICENSE new file mode 100644 index 0000000..456d091 --- /dev/null +++ b/mods/castle_farming/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Minetest Mods Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/castle_farming/README.md b/mods/castle_farming/README.md new file mode 100644 index 0000000..c67b5de --- /dev/null +++ b/mods/castle_farming/README.md @@ -0,0 +1,13 @@ +## Castle farm products + +B: Philipbenr, DanDuncombe, FaceDeer + +Licence: MIT + +=-=-=-=-=-=-=-=-=-= + +Contains farm products useful for decorating a castle: + +* Hide wall and floor coverings +* Bound straw bale +* Straw training dummy diff --git a/mods/castle_farming/hides.lua b/mods/castle_farming/hides.lua new file mode 100644 index 0000000..73a9df2 --- /dev/null +++ b/mods/castle_farming/hides.lua @@ -0,0 +1,32 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_alias("castle:hides", "castle_farming:hides") + +minetest.register_node("castle_farming:hides", { + drawtype = "nodebox", + description = S("Hides"), + inventory_image = "castle_hide.png", + paramtype = "light", + walkable = false, + tiles = {'castle_hide.png'}, + climbable = true, + paramtype2 = "wallmounted", + groups = {dig_immediate=2}, + node_box = { + type = "wallmounted", + wall_top = {-0.5, 0.4375, -0.5, 0.5, 0.5, 0.5}, + wall_bottom = {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.5}, + wall_side = {-0.5, -0.5, -0.5, -0.4375, 0.5, 0.5}, + }, +}) + +minetest.register_craft( { + type = "shapeless", + output = "castle_farming:hides 6", + recipe = { "wool:white" , "bucket:bucket_water" }, + replacements = { + { 'bucket:bucket_water', 'bucket:bucket_empty' } + } +}) diff --git a/mods/castle_farming/init.lua b/mods/castle_farming/init.lua new file mode 100644 index 0000000..efc24dc --- /dev/null +++ b/mods/castle_farming/init.lua @@ -0,0 +1,4 @@ +local MP = minetest.get_modpath(minetest.get_current_modname()) + +dofile(MP.."/hides.lua") +dofile(MP.."/straw.lua") \ No newline at end of file diff --git a/mods/castle_farming/intllib.lua b/mods/castle_farming/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/castle_farming/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/castle_farming/license.txt b/mods/castle_farming/license.txt new file mode 100644 index 0000000..7f5d20e --- /dev/null +++ b/mods/castle_farming/license.txt @@ -0,0 +1,3 @@ +Authored by; Philipbenr, DanDuncombe, FaceDeer + +Licence: MIT diff --git a/mods/castle_farming/locale/es.po b/mods/castle_farming/locale/es.po new file mode 100644 index 0000000..72983b3 --- /dev/null +++ b/mods/castle_farming/locale/es.po @@ -0,0 +1,30 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-27 00:59-0700\n" +"PO-Revision-Date: 2017-04-21 19:47-0500\n" +"Last-Translator: Carlos Barraza \n" +"Language-Team: LANGUAGE \n" +"Language: Español\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: hides.lua:9 +msgid "Hides" +msgstr "Escondite" + +#: straw.lua:13 +msgid "Bound Straw" +msgstr "Paja amarrada" + +#: straw.lua:22 +msgid "Training Dummy" +msgstr "Maniqui de Entrenamiento" diff --git a/mods/castle_farming/locale/pt_br.po b/mods/castle_farming/locale/pt_br.po new file mode 100644 index 0000000..6030f97 --- /dev/null +++ b/mods/castle_farming/locale/pt_br.po @@ -0,0 +1,30 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2017 +# This file is distributed under the same license as the castle_farming package. +# Caio Roberto , 2017. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-27 00:59-0700\n" +"PO-Revision-Date: 2017-06-29 13:00-0330\n" +"Last-Translator: Caio Roberto \n" +"Language-Team: Paulo Slomp FACED UFRGS <00009228@ufrgs.br>\n" +"Language: Brazilian Portuguese\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: hides.lua:9 +msgid "Hides" +msgstr "Esconde-se" + +#: straw.lua:13 +msgid "Bound Straw" +msgstr "Palha Amarrada" + +#: straw.lua:22 +msgid "Training Dummy" +msgstr "Vaca Parada de Madeira (para Laço)" diff --git a/mods/castle_farming/locale/template.pot b/mods/castle_farming/locale/template.pot new file mode 100644 index 0000000..233f90f --- /dev/null +++ b/mods/castle_farming/locale/template.pot @@ -0,0 +1,30 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-27 00:59-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: hides.lua:9 +msgid "Hides" +msgstr "" + +#: straw.lua:13 +msgid "Bound Straw" +msgstr "" + +#: straw.lua:22 +msgid "Training Dummy" +msgstr "" diff --git a/mods/castle_farming/mod.conf b/mods/castle_farming/mod.conf new file mode 100644 index 0000000..0271bd7 --- /dev/null +++ b/mods/castle_farming/mod.conf @@ -0,0 +1,4 @@ +name = castle_farming +depends = default, farming, wool, bucket +optional_depends = intllib, ropes +description = Contains farming products useful for decorating a castle diff --git a/mods/castle_farming/screenshot.png b/mods/castle_farming/screenshot.png new file mode 100644 index 0000000..ecf7139 Binary files /dev/null and b/mods/castle_farming/screenshot.png differ diff --git a/mods/castle_farming/straw.lua b/mods/castle_farming/straw.lua new file mode 100644 index 0000000..aef5312 --- /dev/null +++ b/mods/castle_farming/straw.lua @@ -0,0 +1,75 @@ +minetest.register_alias_force("cottages:straw", "farming:straw") +minetest.register_alias_force("castle:straw", "farming:straw") +minetest.register_alias_force("darkage:straw", "farming:straw") +minetest.register_alias_force("cottages:straw_bale", "castle_farming:bound_straw") +minetest.register_alias_force("darkage:straw_bale", "castle_farming:bound_straw") +minetest.register_alias_force("castle:bound_straw", "castle_farming:bound_straw") + +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_node("castle_farming:bound_straw", { + description = S("Bound Straw"), + drawtype = "normal", + tiles = {"castle_straw_bale.png"}, + groups = {choppy=4, flammable=1, oddly_breakable_by_hand=3}, + sounds = default.node_sound_leaves_defaults(), + paramtype = "light", +}) + +minetest.register_node("castle_farming:straw_dummy", { + description = S("Training Dummy"), + tiles = {"castle_straw_dummy.png"}, + groups = {choppy=4, flammable=1, oddly_breakable_by_hand=3}, + sounds = default.node_sound_leaves_defaults(), + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.125, 0, 0.1875, 0.125}, -- right_leg + {0, -0.5, -0.125, 0.25, 0.1875, 0.125}, -- left_leg + {-0.25, 0.1875, -0.1875, 0.25, 0.875, 0.125}, -- torso + {0.25, 0.1875, -0.125, 0.5, 0.875, 0.125}, -- left_arm + {-0.5, 0.1875, -0.125, -0.25, 0.875, 0.125}, -- right_arm + {-0.25, 0.875, -0.25, 0.25, 1.3125, 0.1875}, -- head + } + } +}) + +minetest.register_craft({ + output = "castle_farming:straw_dummy", + recipe = { + {"group:stick", "castle_farming:bound_straw","group:stick"}, + {"", "castle_farming:bound_straw",""}, + {"group:stick", "","group:stick"}, + }, +}) + +minetest.register_craft({ + output = "castle_farming:bound_straw 6", + type = "shapeless", + recipe = {"farming:straw", "farming:straw", "farming:straw", "farming:straw", "farming:straw", "farming:straw", "ropes:ropesegment",} +}) + +minetest.register_craft({ + output = "castle_farming:bound_straw", + type = "shapeless", + recipe = {"farming:straw", "farming:cotton",} +}) + +minetest.register_craft({ + type = "fuel", + recipe = "castle_farming:bound_straw", + burntime = 10 +}) + +local stick_burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack("default:stick")}}).time + +minetest.register_craft({ + type = "fuel", + recipe = "castle_farming:straw_dummy", + burntime = 10*2 + 4*stick_burn_time +}) diff --git a/mods/castle_farming/textures/LICENSE.txt b/mods/castle_farming/textures/LICENSE.txt new file mode 100644 index 0000000..594d102 --- /dev/null +++ b/mods/castle_farming/textures/LICENSE.txt @@ -0,0 +1,19 @@ +-------------------------------------------- + +16 px textures based on Castle mod +original textures by Philipner + +License Textures: Napiophelios - CC-BY-SA 3.0 + +castle_hide.png +castle_straw_bale.png + +-------------------------------------------- + +Attribution 3.0 Unported (CC BY 3.0) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2015-2016 MasterGollum +Copyright (C) 2015-2016 Gambit + +castle_straw_dummy.png - derived from farming_straw.png \ No newline at end of file diff --git a/mods/castle_farming/textures/castle_hide.png b/mods/castle_farming/textures/castle_hide.png new file mode 100644 index 0000000..3e6f6c4 Binary files /dev/null and b/mods/castle_farming/textures/castle_hide.png differ diff --git a/mods/castle_farming/textures/castle_straw_bale.png b/mods/castle_farming/textures/castle_straw_bale.png new file mode 100644 index 0000000..ad56330 Binary files /dev/null and b/mods/castle_farming/textures/castle_straw_bale.png differ diff --git a/mods/castle_farming/textures/castle_straw_dummy.png b/mods/castle_farming/textures/castle_straw_dummy.png new file mode 100644 index 0000000..265f532 Binary files /dev/null and b/mods/castle_farming/textures/castle_straw_dummy.png differ diff --git a/mods/castle_gates/README.txt b/mods/castle_gates/README.txt new file mode 100644 index 0000000..113bd89 --- /dev/null +++ b/mods/castle_gates/README.txt @@ -0,0 +1,11 @@ +Castle Gates + +Licence: MIT + +see: LICENSE + +=-=-=-=-=-=-=-=-=-= + +This is a mod all about creating castle gates and dungeons. It contains dungeon doors and bars, and also a set of nodes for constructing larger swinging and sliding gates. + +This allows the construction of portcullises and drawbridges as well as conventional swinging doors. Use the screwdriver to reorient gate pieces as needed for these purposes. diff --git a/mods/castle_gates/api.txt b/mods/castle_gates/api.txt new file mode 100644 index 0000000..8d8b4d6 --- /dev/null +++ b/mods/castle_gates/api.txt @@ -0,0 +1,76 @@ +This document is intended primarily for modders interested in adding their own gate nodes and gate types. + +This mod allows for additional gate nodes to be defined in other dependent mods that will work seamlessly with existing gate nodes. The following is a minimalist example that shows a node using all of the features offered by this mod's gate API: + +minetest.register_node("castle_gates:example_gate_piece", { + description = "Example gate", + groups = {castle_gate = 1}, + tiles = {"default_wood.png"}, + paramtype2 = "facedir", + on_rightclick = castle_gates.trigger_gate, + _gate_edges = {"right"=true}, + _gate_hinge = {axis="top", offset={"front","left"}}, +}) + +The key features are: + +* paramtype2 = "facedir" (mandatory) +* "castle_gate" group membership (mandatory) +* on_rightclick = castle_gates.trigger_gate (optional, but recommended) +* _gate_edges = (optional) +* _gate_hinge = (optional) + + +Paramtype2 +========== + +All gate pieces must be orientable via facedir. + +Castle_gate group +================= + +When a gate is triggered by right-clicking on a gate node, the gate code does a "flood fill" operation to find all connected gate nodes. This flood fill operation looks for adjacent nodes that belong to the same castle_gate group, so all gate nodes need to belong to this group. + +Gates defined in this mod all belong to castle_gate=1. + +on_rightclick +============= + +The castle_gates.trigger_gate method is a right-click handler that will trigger the movement of the gate. If you want your gate pieces to respond to a player's right click by opening, use this call to make the gate magic happen. + +Note that if you wish you can embed the call to The castle_gates.trigger_gate inside your own on_rightclick function, so that for example you could make a "locked" gate that will only respond to specific players (you may wish to use a different castle_gate group ID for such a gate). Or you can omit this function, in which case the gate piece will still move with the rest of the gate but right-clicking on it will not trigger the gate's movement. + +_gate_edges +=========== + +This is an optional property you can put on a gate node's definition to prevent flood-fill from extending beyond this node in a particular direction. This is useful if, for example, you want players to be able to build double doors that would otherwise connect together when both doors are closed. + +It consists of a table with directions defined as edges set to true. You can use this template: + +_gate_edges = {right=false, left=false, top=false, bottom=false} + +("front" and "back" are also possible but are unlikely to be of any real use) + +Note that the flood-fill search for gate nodes will flow *around* an edge piece if a path exists, the mere fact that there's an edge piece does not guarantee that the door node beyond the edge will not be considered part of the same door as it. + +_gate_hinge +=========== + +The hinge definition for a node def is of the following form: + +_gate_hinge = {axis=, offset=} + + is one of "top", "bottom", "left", "right", "front" or "back". +Top/bottom, left/right and front/back are interchangeable pairings as far as this code is concerned. +These directions are relative to the orientation of the block. Existing gates use "top", so for +maximum compatibility it's advised that new gate hinges are defined with the same axis. + + is optional. If it is not defined, the gate hinge will try to rotate around the center of the node. + + can be a single direction ("top", "bottom", "left", "right", "front", "back"). If a single direction is +given the hinge will try to rotate around the center of the node that lies in that direction relative to the hinge node. + + can also be a pair of directions given in a table. This is how the *edge* of a node can be made into the +center of rotation. For example, existing gate hinges in this mod have the offset {"front","left"}. This means that the +gate will try to rotate around the center of the edge of the node where the front and left faces intersect. +You should only use direction pairs that form a 90 degree angle. \ No newline at end of file diff --git a/mods/castle_gates/doc.lua b/mods/castle_gates/doc.lua new file mode 100644 index 0000000..ac868e7 --- /dev/null +++ b/mods/castle_gates/doc.lua @@ -0,0 +1,52 @@ +castle_gates.doc = {} + +if not minetest.get_modpath("doc") then + return +end + +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +castle_gates.doc.portcullis_bars_longdesc = S("Heavy wooden bars designed to prevent entry even to siege equipment.") +castle_gates.doc.portcullis_bars_usagehelp = S("Place these bars in a structure together and they will slide as a unified gate when clicked on.") + +castle_gates.doc.portcullis_bars_bottom_longdesc = S("The bottom edge of a portcullis gate, with knobs to lock securely into the floor.") +castle_gates.doc.portcullis_bars_bottom_usagehelp = S("This block can be used to define the edge of a portcullius that meets up with another gate, should you have an arrangement like that. Otherwise it's just decorative.") + +castle_gates.doc.gate_panel_longdesc = S("A basic gate panel.") +castle_gates.doc.gate_panel_usagehelp = S("This gate segment will move in unison with adjoining gate segments when right-clicked.") + +castle_gates.doc.gate_edge_longdesc = S("A gate panel with a defined edge.") +castle_gates.doc.gate_edge_usagehelp = S("The darkened edge of this panel marks the edge of the gate it's a part of. You can use these when building double doors to ensure the two parts swing separately, for example. Note that edges aren't strictly necessary for gates that stand alone.") + +castle_gates.doc.gate_edge_handle_longdesc = S("A gate edge with a handle.") +castle_gates.doc.gate_edge_handle_usagehelp = S("The handle is basically decorative, a door this size can be swung by clicking anywhere on it. But the darkened edge of this panel is useful for defining the edge of a gate when it abuts a partner to the side.") + +castle_gates.doc.gate_hinge_longdesc = S("A hinged gate segment that allows a gate to swing.") +castle_gates.doc.gate_hinge_usagehelp = S("If you have more than one hinge in your gate, make sure the hinges line up correctly otherwise the gate will not be able to swing. The hinge is the protruding block along the edge of the gate panel.") + +castle_gates.doc.gate_slot_longdesc = S("A block with a slot to allow an adjacent sliding gate through.") +castle_gates.doc.gate_slot_usagehelp = S("This block is designed to extend into a neighboring node that a sliding gate passes through, to provide a tight seal for the gate to move through without allowing anything else to squeeze in.") + +castle_gates.doc.gate_slot_reverse_longdesc = S("A block that extends into an adjacent node to provide a tight seal for a large gate.") +castle_gates.doc.gate_slot_reverse_usagehelp = S("Two nodes cannot occupy the same space, but this block extends into a neighboring node's space to allow for gates to form a tight seal. It can be used with sliding gates or swinging gates.") + +doc.add_category("castle_gates", +{ + name = S("Gates"), + description = S("Gates are large multi-node constructions that swing on hinges or slide out of the way when triggered."), + build_formspec = doc.entry_builders.text_and_gallery, +}) + +doc.add_entry("castle_gates", "construction", { + name = S("Gate construction"), + data = { text = +S("Gates are multi-node constructions, usually (though not always) consisting of multiple node types that fit together into a unified whole. The orientation of gate nodes is significant, so a screwdriver will be a helpful tool when constructing gates." +.."\n\n".. +"A gate's extent is determined by a \"flood fill\" operation. When you trigger a gate block, all compatible neighboring blocks will be considered part of the same structure and will move in unison. Only gate blocks that are aligned with each other will be considered part of the same gate. If you wish to build adjoining gates (for example, a large pair of double doors that meet in the center) you'll need to make use of gate edge blocks to prevent it all from being considered one big door. Note that if your gate does not abut any other gates you don't actually need to define its edges this way - you don't have to use edge blocks in this case." +.."\n\n".. +"If a gate has no hinge nodes it will be considered a sliding gate. When triggered, the gate code will search for a direction that the gate can slide in and will move it in that direction at a rate of one block-length per second. Once it reaches an obstruction it will stop, and when triggered again it will try sliding in the opposite direction." +.."\n\n".. +"If a gate has hinge nodes then triggering it will cause the gate to try swinging around the hinge. If the gate has multiple hinges and they don't line up properly the gate will be unable to move. Note that the gate can only exist in 90-degree increments of orientation, but the gate still looks for obstructions in the region it is swinging through and will not swing if there's something in the way.") +}}) \ No newline at end of file diff --git a/mods/castle_gates/doors.lua b/mods/castle_gates/doors.lua new file mode 100644 index 0000000..d5a367e --- /dev/null +++ b/mods/castle_gates/doors.lua @@ -0,0 +1,85 @@ + +-- Used for localization, choose either built-in or intllib. + +local MP, S, NS = nil + +if (minetest.get_modpath("intllib") == nil) then + S = minetest.get_translator("castle_gates") + +else + -- internationalization boilerplate + MP = minetest.get_modpath(minetest.get_current_modname()) + S, NS = dofile(MP.."/intllib.lua") + +end + + +if minetest.get_modpath("doors") then + doors.register("castle_gates:oak_door", { + tiles = {{ name = "castle_door_oak.png", backface_culling = true }}, + description = S("Oak Door"), + inventory_image = "castle_oak_door_inv.png", + protected = true, + groups = { choppy = 2, door = 1 }, + sounds = default.node_sound_wood_defaults(), + recipe = { + {"default:tree", "default:tree"}, + {"default:tree", "default:tree"}, + {"default:tree", "default:tree"}, + } + }) + + local door_recipe + if minetest.get_modpath("xpanes") then + door_recipe = { + {"xpanes:jailbars_flat", "xpanes:jailbars_flat"}, + {"xpanes:jailbars_flat", "xpanes:jailbars_flat"}, + {"xpanes:jailbars_flat", "xpanes:jailbars_flat"}, + } + else + door_recipe = { + {"default:steel_ingot", ""}, + {"", "default:steel_ingot"}, + {"default:steel_ingot", ""}, + } + end + + doors.register("castle_gates:jail_door", { + tiles = {{ name = "castle_door_jail.png", backface_culling = true }}, + description = S("Jail Door"), + inventory_image = "castle_jail_door_inv.png", + protected = true, + groups = { cracky = 2, door = 1, flow_through = 1}, + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + recipe = door_recipe, + }) + + minetest.register_alias("castle:oak_door_a", "castle_gates:oak_door_a") + minetest.register_alias("castle:oak_door_b", "castle_gates:oak_door_b") + minetest.register_alias("castle:jail_door_a", "castle_gates:jail_door_a") + minetest.register_alias("castle:jail_door_b", "castle_gates:jail_door_b") +end + +if minetest.get_modpath("xpanes") then + xpanes.register_pane("jailbars", { + description = S("Jail Bars"), + tiles = {"castle_jailbars.png"}, + drawtype = "airlike", + paramtype = "light", + textures = {"castle_jailbars.png", "castle_jailbars.png", "epic_blank.png"}, + inventory_image = "castle_jailbars.png", + wield_image = "castle_jailbars.png", + sounds = default.node_sound_metal_defaults(), + groups = {cracky=1, pane=1, flow_through=1}, + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}}, + }) +end + +for i = 1, 15 do + minetest.register_alias("castle:jailbars_"..i, "xpanes:jailbars_"..i) +end +minetest.register_alias("castle:jailbars", "xpanes:jailbars") diff --git a/mods/castle_gates/gate_functions.lua b/mods/castle_gates/gate_functions.lua new file mode 100644 index 0000000..41cecfc --- /dev/null +++ b/mods/castle_gates/gate_functions.lua @@ -0,0 +1,399 @@ +local MP = minetest.get_modpath(minetest.get_current_modname()) + +-- Given a facedir, returns a set of all the corresponding directions +local get_dirs = function(facedir) + local dirs = {} + local top = {[0]={x=0, y=1, z=0}, + {x=0, y=0, z=1}, + {x=0, y=0, z=-1}, + {x=1, y=0, z=0}, + {x=-1, y=0, z=0}, + {x=0, y=-1, z=0}} + dirs.back = minetest.facedir_to_dir(facedir) + dirs.top = top[math.floor(facedir/4)] + dirs.right = { + x=dirs.top.y*dirs.back.z - dirs.back.y*dirs.top.z, + y=dirs.top.z*dirs.back.x - dirs.back.z*dirs.top.x, + z=dirs.top.x*dirs.back.y - dirs.back.x*dirs.top.y + } + dirs.front = vector.multiply(dirs.back, -1) + dirs.bottom = vector.multiply(dirs.top, -1) + dirs.left = vector.multiply(dirs.right, -1) + return dirs +end + +-- Returns the axis that dir points along +local dir_to_axis = function(dir) + if dir.x ~= 0 then + return "x" + elseif dir.y ~= 0 then + return "y" + else + return "z" + end +end + +-- Given a hinge definition, turns it into an axis and placement that can be used by the door rotation. +local interpret_hinge = function(hinge_def, pos, node_dirs) + local axis = dir_to_axis(node_dirs[hinge_def.axis]) + + local placement + if type(hinge_def.offset) == "string" then + placement = vector.add(pos, node_dirs[hinge_def.offset]) + elseif type(hinge_def.offset) == "table" then + placement = vector.new(0,0,0) + local divisor = 0 + for _, val in pairs(hinge_def.offset) do + placement = vector.add(placement, node_dirs[val]) + divisor = divisor + 1 + end + placement = vector.add(pos, vector.divide(placement, divisor)) + else + placement = pos + end + + return axis, placement +end + + +-------------------------------------------------------------------------- +-- Rotation (slightly more complex than sliding) + +local facedir_rotate = { + ['x'] = { + [-1] = {[0]=4, 5, 6, 7, 22, 23, 20, 21, 0, 1, 2, 3, 13, 14, 15, 12, 19, 16, 17, 18, 10, 11, 8, 9}, -- 270 degrees + [1] = {[0]=8, 9, 10, 11, 0, 1, 2, 3, 22, 23, 20, 21, 15, 12, 13, 14, 17, 18, 19, 16, 6, 7, 4, 5}, -- 90 degrees + }, + ['y'] = { + [-1] = {[0]=3, 0, 1, 2, 19, 16, 17, 18, 15, 12, 13, 14, 7, 4, 5, 6, 11, 8, 9, 10, 21, 22, 23, 20}, -- 270 degrees + [1] = {[0]=1, 2, 3, 0, 13, 14, 15, 12, 17, 18, 19, 16, 9, 10, 11, 8, 5, 6, 7, 4, 23, 20, 21, 22}, -- 90 degrees + }, + ['z'] = { + [-1] = {[0]=16, 17, 18, 19, 5, 6, 7, 4, 11, 8, 9, 10, 0, 1, 2, 3, 20, 21, 22, 23, 12, 13, 14, 15}, -- 270 degrees + [1] = {[0]=12, 13, 14, 15, 7, 4, 5, 6, 9, 10, 11, 8, 20, 21, 22, 23, 0, 1, 2, 3, 16, 17, 18, 19}, -- 90 degrees + } +} + --90 degrees CW about x-axis: (x, y, z) -> (x, -z, y) + --90 degrees CCW about x-axis: (x, y, z) -> (x, z, -y) + --90 degrees CW about y-axis: (x, y, z) -> (-z, y, x) + --90 degrees CCW about y-axis: (x, y, z) -> (z, y, -x) + --90 degrees CW about z-axis: (x, y, z) -> (y, -x, z) + --90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z) +local rotate_pos = function(axis, direction, pos) + if axis == "x" then + if direction < 0 then + return {x= pos.x, y= -pos.z, z= pos.y} + else + return {x= pos.x, y= pos.z, z= -pos.y} + end + elseif axis == "y" then + if direction < 0 then + return {x= -pos.z, y= pos.y, z= pos.x} + else + return {x= pos.z, y= pos.y, z= -pos.x} + end + else + if direction < 0 then + return {x= -pos.y, y= pos.x, z= pos.z} + else + return {x= pos.y, y= -pos.x, z= pos.z} + end + end +end + +local rotate_pos_displaced = function(pos, origin, axis, direction) + -- position in space relative to origin + local newpos = vector.subtract(pos, origin) + newpos = rotate_pos(axis, direction, newpos) + -- Move back to original reference frame + return vector.add(newpos, origin) +end + +local get_buildable_to = function(pos) + return minetest.registered_nodes[minetest.get_node(pos).name].buildable_to +end + + +local get_door_layout = function(pos, facedir, player) + if facedir > 23 then return nil end -- A bug in another mod once resulted in bad param2s being written to nodes, this will at least prevent crashes if something like that happens again. + + -- This method does a flood-fill looking for all nodes that meet the following criteria: + -- belongs to a "castle_gate" group + -- has the same "back" direction as the initial node + -- is accessible via up, down, left or right directions unless one of those directions goes through an edge that one of the two nodes has marked as a gate edge + local door = {} + + door.all = {} + door.contains_protected_node = false + door.directions = get_dirs(facedir) + door.previous_move = minetest.get_meta(pos):get_string("previous_move") + + -- temporary pointsets used while searching + local to_test = {} + local tested = {} + local can_slide_to = {} + + local castle_gate_group_value -- this will be populated from the first gate node we encounter, which will be the one that was clicked on + + local test_pos = pos + while test_pos ~= nil do + local test_pos_hash = minetest.hash_node_position(test_pos) + tested[test_pos_hash] = true -- track nodes we've looked at + local test_node = minetest.get_node(test_pos) + + if test_node.name == "ignore" then + --array is next to unloaded nodes, too dangerous to do anything. Abort. + return nil + end + + if minetest.is_protected(test_pos, player:get_player_name()) and not minetest.check_player_privs(player, "protection_bypass") then + door.contains_protected_node = true + end + + local test_node_def = minetest.registered_nodes[test_node.name] + if test_node_def.buildable_to then + can_slide_to[test_pos_hash] = true + end + + if test_node_def.paramtype2 == "facedir" and test_node.param2 <= 23 then -- prospective door nodes need to be of type facedir and have a valid param2 + local test_node_dirs = get_dirs(test_node.param2) + local coplanar = vector.equals(test_node_dirs.back, door.directions.back) -- the "back" vector needs to point in the same direction as the rest of the door + + if castle_gate_group_value == nil and test_node_def.groups.castle_gate ~= nil then + castle_gate_group_value = test_node_def.groups.castle_gate -- read the group value from the first gate node encountered + end + + if coplanar and test_node_def.groups.castle_gate == castle_gate_group_value then + local entry = {["pos"] = test_pos, ["node"] = test_node} + table.insert(door.all, entry) -- it's definitely a gate node of some sort. + if test_node_def._gate_hinge ~= nil then -- it's a hinge type of node, need to do extra work + local axis, placement = interpret_hinge(test_node_def._gate_hinge, test_pos, test_node_dirs) + if door.hinge == nil then -- this is the first hinge we've encountered. + door.hinge = {axis=axis, placement=placement} + door.directions = test_node_dirs -- force the door as a whole to use the same reference frame as the first hinge + elseif door.hinge.axis ~= axis then -- there was a previous hinge. Do they rotate on the same axis? + return nil -- Misaligned hinge axes, door cannot rotate. + else + local axis_dir = {x=0, y=0, z=0} + axis_dir[axis] = 1 + local displacement = vector.normalize(vector.subtract(placement, door.hinge.placement)) -- check if this new hinge is displaced relative to the first hinge on any axis other than the rotation axis + if not (vector.equals(displacement, axis_dir) or vector.equals(displacement, vector.multiply(axis_dir, -1))) then + return nil -- Misaligned hinge offset, door cannot rotate. + end + end + end + + can_slide_to[test_pos_hash] = true -- since this is part of the door, other parts of the door can slide into it + + local test_directions = {"top", "bottom", "left", "right"} + for _, dir in pairs(test_directions) do + local adjacent_pos = vector.add(test_pos, door.directions[dir]) + local adjacent_node = minetest.get_node(adjacent_pos) + local adjacent_def = minetest.registered_nodes[adjacent_node.name] + local adjacent_pos_hash = minetest.hash_node_position(adjacent_pos) + + if adjacent_def.buildable_to then + can_slide_to[adjacent_pos_hash] = true + end + + if test_node_def._gate_edges == nil or not test_node_def._gate_edges[dir] then -- if we ourselves are an edge node, don't look in the direction we're an edge in + + if tested[adjacent_pos_hash] == nil then -- don't look at nodes that have already been looked at + if adjacent_def.paramtype2 == "facedir" then -- all doors are facedir nodes so we can pre-screen some targets + local edge_points_back_at_test_pos = false + -- Look at the adjacent node's definition. If it's got gate edges, check if they point back at us. + if adjacent_def._gate_edges ~= nil then + local adjacent_directions = get_dirs(adjacent_node.param2) + for dir, val in pairs(adjacent_def._gate_edges) do + if vector.equals(vector.add(adjacent_pos, adjacent_directions[dir]), test_pos) then + edge_points_back_at_test_pos = true + break + end + end + end + + if not edge_points_back_at_test_pos then + table.insert(to_test, adjacent_pos_hash) + end + end + end + end + end + end + end + + test_pos = table.remove(to_test) + if test_pos ~= nil then + test_pos = minetest.get_position_from_hash(test_pos) + end + end + + if door.hinge == nil then + --sliding door, evaluate which directions it can go + door.can_slide = {top=true, bottom=true, left=true, right=true} + for _,door_node in pairs(door.all) do + door.can_slide.top = door.can_slide.top and can_slide_to[minetest.hash_node_position(vector.add(door_node.pos, door.directions.top))] + door.can_slide.bottom = door.can_slide.bottom and can_slide_to[minetest.hash_node_position(vector.add(door_node.pos, door.directions.bottom))] + door.can_slide.left = door.can_slide.left and can_slide_to[minetest.hash_node_position(vector.add(door_node.pos, door.directions.left))] + door.can_slide.right = door.can_slide.right and can_slide_to[minetest.hash_node_position(vector.add(door_node.pos, door.directions.right))] + end + else + --rotating door, evaluate which direction it can go. Slightly more complicated. + local origin = door.hinge.placement + local axis = door.hinge.axis + local backfront = dir_to_axis(door.directions.back) + local leftright = dir_to_axis(door.directions.right) + + door.swings = {} + + for _, direction in pairs({-1, 1}) do + door.swings[direction] = true + for _, door_node in pairs(door.all) do + origin[axis] = door_node.pos[axis] + if not vector.equals(door_node.pos, origin) then -- There's no obstruction if the node is literally located along the rotation axis + local newpos = rotate_pos_displaced(door_node.pos, origin, axis, direction) + local newnode = minetest.get_node(newpos) + local newdef = minetest.registered_nodes[newnode.name] + if not newdef.buildable_to then -- check if the destination node is free. + door.swings[direction] = false + break + end + + local swing_corner = {} -- the corner of the square "arc" that a Minetest gate swings through + local scan_dir + swing_corner[axis] = door_node.pos[axis] + swing_corner[backfront] = newpos[backfront] + swing_corner[leftright] = door_node.pos[leftright] + if not (vector.equals(newpos, swing_corner) or vector.equals(door_node.pos, swing_corner)) then -- we're right next to the hinge, no need for further testing + scan_dir = vector.direction(newpos, swing_corner) -- get the direction from the new door position toward the swing corner + repeat + newpos = vector.add(newpos, scan_dir) -- we start with newpos on the destination node, which has already been tested. + if not get_buildable_to(newpos) then + door.swings[direction] = false + end + until vector.equals(newpos, swing_corner) or door.swings[direction] == false + + if not (vector.equals(newpos, door_node.pos) or door.swings[direction] == false) then + scan_dir = vector.direction(newpos, door_node.pos) + newpos = vector.add(newpos, scan_dir) -- the first step here is a freebie since we've already checked swing_corner + while not (vector.equals(newpos, door_node.pos) or door.swings[direction] == false) do + if not get_buildable_to(newpos) then + door.swings[direction] = false + end + newpos = vector.add(newpos, scan_dir) + end + end + end + end + + if door.swings[direction] == false then + break + end + + end + end + end + return door +end + + +local slide_gate = function(door, direction) + for _, door_node in pairs(door.all) do + door_node.pos = vector.add(door_node.pos, door.directions[direction]) + end + door.previous_move = direction +end + +local rotate_door = function (door, direction) + if not door.swings[direction] then + return false + end + + local origin = door.hinge.placement + local axis = door.hinge.axis + + for _, door_node in pairs(door.all) do + door_node.pos = rotate_pos_displaced(door_node.pos, origin, axis, direction) + door_node.node.param2 = facedir_rotate[axis][direction][door_node.node.param2] + end + return true +end + + +---------------------------------------------------------------------------------------------------- +-- When creating new gate pieces use this as the "on_rightclick" method of their node definitions +-- if you want the player to be able to trigger the gate by clicking on that particular node. +-- If you just want the node to move with the gate and not trigger it this isn't necessary, +-- only the "castle_gate" group is needed for that. + +castle_gates.trigger_gate = function(pos, node, player) + local door = get_door_layout(pos, node.param2, player) + + if door ~= nil then + for _, door_node in pairs(door.all) do + minetest.set_node(door_node.pos, {name="air"}) + end + + local door_moved = false + if door.can_slide ~= nil then -- this is a sliding door + if door.previous_move == "top" and door.can_slide.top then + slide_gate(door, "top") + door_moved = true + elseif door.previous_move == "bottom" and door.can_slide.bottom then + slide_gate(door, "bottom") + door_moved = true + elseif door.previous_move == "left" and door.can_slide.left then + slide_gate(door, "left") + door_moved = true + elseif door.previous_move == "right" and door.can_slide.right then + slide_gate(door, "right") + door_moved = true + end + + if not door_moved then -- reverse door's direction for next time + if door.previous_move == "top" and door.can_slide.bottom then + door.previous_move = "bottom" + elseif door.previous_move == "bottom" and door.can_slide.top then + door.previous_move = "top" + elseif door.previous_move == "left" and door.can_slide.right then + door.previous_move = "right" + elseif door.previous_move == "right" and door.can_slide.left then + door.previous_move = "left" + else + -- find any open direction + for slide_dir, enabled in pairs(door.can_slide) do + if enabled then + door.previous_move = slide_dir + break + end + end + end + end + elseif door.hinge ~= nil then -- this is a hinged door + if door.previous_move == "deosil" then + door_moved = rotate_door(door, 1) + elseif door.previous_move == "widdershins" then + door_moved = rotate_door(door, -1) + end + + if not door_moved then + if door.previous_move == "deosil" then + door.previous_move = "widdershins" + else + door.previous_move = "deosil" + end + end + end + + for _, door_node in pairs(door.all) do + minetest.set_node(door_node.pos, door_node.node) + minetest.get_meta(door_node.pos):set_string("previous_move", door.previous_move) + end + + if door_moved then + minetest.after(1, function() + castle_gates.trigger_gate(door.all[1].pos, door.all[1].node, player) + end) + end + end +end \ No newline at end of file diff --git a/mods/castle_gates/gate_slots.lua b/mods/castle_gates/gate_slots.lua new file mode 100644 index 0000000..ef30ff9 --- /dev/null +++ b/mods/castle_gates/gate_slots.lua @@ -0,0 +1,146 @@ +local MP, S, NS = nil + +if (minetest.get_modpath("intllib") == nil) then + S = minetest.get_translator("castle_gates") + +else + -- internationalization boilerplate + MP = minetest.get_modpath(minetest.get_current_modname()) + S, NS = dofile(MP.."/intllib.lua") + +end + + +-- copied from castle_masonry in case that mod is not loaded +local get_material_properties = function(material) + local composition_def + local burn_time + if material.composition_material ~= nil then + composition_def = minetest.registered_nodes[material.composition_material] + burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.composition_material)}}).time + else + composition_def = minetest.registered_nodes[material.craft_material] + burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.craft_materia)}}).time + end + + local tiles = material.tile + if tiles == nil then + tiles = composition_def.tile + elseif type(tiles) == "string" then + tiles = {tiles} + end + + local desc = material.desc + if desc == nil then + desc = composition_def.description + end + + return composition_def, burn_time, tiles, desc +end + +local materials +if minetest.get_modpath("castle_masonry") then + materials = castle_masonry.materials +else + materials = {{name="stonebrick", desc=S("Stonebrick"), tile="default_stone_brick.png", craft_material="default:stonebrick"}} +end + +castle_gates.register_gate_slot = function(material) + local composition_def, burn_time, tile, desc = get_material_properties(material) + local mod_name = minetest.get_current_modname() + + minetest.register_node(mod_name..":"..material.name.."_gate_slot", { + drawtype = "nodebox", + description = S("@1 Gate Slot", desc), + _doc_items_longdesc = castle_gates.doc.gate_slot_longdesc, + _doc_items_usagehelp = castle_gates.doc.gate_slot_usagehelp, + tiles = tile, + paramtype = "light", + paramtype2 = "facedir", + groups = composition_def.groups, + sounds = composition_def.sounds, + + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, -- body + {-0.5, -0.5, -0.75, 0.5, 0.5, -1.5}, -- bracket + } + }, + + collision_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, 1.5}, -- body + }, + }) + + minetest.register_node(mod_name..":"..material.name.."_gate_slot_reverse", { + drawtype = "nodebox", + description = S("@1 Gate Slot Reverse", desc), + _doc_items_longdesc = castle_gates.doc.gate_slot_reverse_longdesc, + _doc_items_usagehelp = castle_gates.doc.gate_slot_reverse_usagehelp, + tiles = tile, + paramtype = "light", + paramtype2 = "facedir", + groups = composition_def.groups, + sounds = composition_def.sounds, + + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -1.25, 0.5, 0.5, 0.5}, -- body + } + }, + + collision_box = { + type = "fixed", + fixed = {-0.5, -0.5, -1.25, 0.5, 0.5, 0.5}, -- body + }, + }) + + + minetest.register_craft({ + output = mod_name..":"..material.name.."_gate_slot 2", + recipe = { + {material.craft_material,"",material.craft_material}, + {material.craft_material,"",material.craft_material}, + }, + }) + + minetest.register_craft({ + output = mod_name..":"..material.name.."_gate_slot", + type = "shapeless", + recipe = {mod_name..":"..material.name.."_gate_slot_reverse"}, + }) + minetest.register_craft({ + output = mod_name..":"..material.name.."_gate_slot_reverse", + type = "shapeless", + recipe = {mod_name..":"..material.name.."_gate_slot"}, + }) + + if burn_time > 0 then + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":"..material.name.."_gate_slot", + burntime = burn_time * 2, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":"..material.name.."_gate_slot_reverse", + burntime = burn_time * 2, + }) + end +end + +castle_gates.register_gate_slot_alias = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias(old_mod_name..":"..old_material_name.."_gate_slot", new_mod_name..":"..new_material_name.."_gate_slot") + minetest.register_alias(old_mod_name..":"..old_material_name.."_gate_slot_reverse", new_mod_name..":"..new_material_name.."_gate_slot_reverse") +end +castle_gates.register_gate_slot_alias_force = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias_force(old_mod_name..":"..old_material_name.."_gate_slot", new_mod_name..":"..new_material_name.."_gate_slot") + minetest.register_alias_force(old_mod_name..":"..old_material_name.."_gate_slot_reverse", new_mod_name..":"..new_material_name.."_gate_slot_reverse") +end + +for _, material in pairs(materials) do + castle_gates.register_gate_slot(material) +end diff --git a/mods/castle_gates/gates.lua b/mods/castle_gates/gates.lua new file mode 100644 index 0000000..6c563f0 --- /dev/null +++ b/mods/castle_gates/gates.lua @@ -0,0 +1,287 @@ +local MP, S, NS = nil + +if (minetest.get_modpath("intllib") == nil) then + S = minetest.get_translator("castle_gates") + +else + -- internationalization boilerplate + MP = minetest.get_modpath(minetest.get_current_modname()) + S, NS = dofile(MP.."/intllib.lua") + +end + + +minetest.register_alias("castle_gates:gate_edge", "castle_gates:wood_gate_edge") +minetest.register_alias("castle_gates:gate_edge_handle", "castle_gates:wood_gate_edge_handle") +minetest.register_alias("castle_gates:gate_hinge", "castle_gates:wood_gate_hinge") +minetest.register_alias("castle_gates:gate_panel", "castle_gates:wood_gate_panel") +minetest.register_alias("castle_gates:portcullis_bars", "castle_gates:wood_portcullis_bars") +minetest.register_alias("castle_gates:portcullis_bars_bottom", "castle_gates:wood_portcullis_bars_bottom") + +local register_gates = function(node_prefix, material_description, material_texture, gate_groups, gate_sounds, portcullis_recipe, panel_recipe) + +local portcullis_groups = {castle_gate = 1, flow_through = 1} +local panel_groups = {castle_gate = 1} +for group, val in pairs(gate_groups) do + portcullis_groups[group] = val + panel_groups[group] = val +end + +minetest.register_node("castle_gates:"..node_prefix.."_portcullis_bars", { + drawtype = "nodebox", + description = S("@1 Portcullis Bars", material_description), + _doc_items_longdesc = castle_gates.doc.portcullis_bars_longdesc, + _doc_items_usagehelp = castle_gates.doc.portcullis_bars_usagehelp, + groups = portcullis_groups, + tiles = { + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_portcullis_mask.png)", + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_portcullis_mask.png)", + material_texture.."^[transformR90", + material_texture.."^[transformR90", + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_portcullis_mask.png)", + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_portcullis_mask.png)", + }, + sounds = gate_sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.125, -0.5, -0.5, 0.125, 0.5, -0.25}, -- middle bar + {-0.5, -0.5, -0.5, -0.375, 0.5, -0.25}, -- side bar + {0.375, -0.5, -0.5, 0.5, 0.5, -0.25}, -- side bar + {-0.375, 0.1875, -0.4375, 0.375, 0.3125, -0.3125}, -- crosspiece + {-0.375, -0.3125, -0.4375, 0.375, -0.1875, -0.3125}, -- crosspiece + } + }, + on_rightclick = castle_gates.trigger_gate, +}) + +minetest.register_node("castle_gates:"..node_prefix.."_portcullis_bars_bottom", { + drawtype = "nodebox", + description = S("@1 Portcullis Bottom", material_description), + _doc_items_longdesc = castle_gates.doc.portcullis_bars_bottom_longdesc, + _doc_items_usagehelp = castle_gates.doc.portcullis_bars_bottom_usagehelp, + groups = portcullis_groups, + tiles = { + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_portcullis_mask.png)", + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_portcullis_mask.png)", + material_texture.."^[transformR90", + material_texture.."^[transformR90", + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_portcullis_mask.png)", + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_portcullis_mask.png)", + }, + sounds = gate_sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.125, -0.5, -0.5, 0.125, 0.5, -0.25}, -- middle bar + {-0.5, -0.5, -0.5, -0.375, 0.5, -0.25}, -- side bar + {0.375, -0.5, -0.5, 0.5, 0.5, -0.25}, -- side bar + {-0.375, 0.1875, -0.4375, 0.375, 0.3125, -0.3125}, -- crosspiece + {-0.375, -0.3125, -0.4375, 0.375, -0.1875, -0.3125}, -- crosspiece + {-0.0625, -0.5, -0.4375, 0.0625, -0.625, -0.3125}, -- peg + {0.4375, -0.5, -0.4375, 0.5, -0.625, -0.3125}, -- peg + {-0.5, -0.5, -0.4375, -0.4375, -0.625, -0.3125}, -- peg + } + }, + _gate_edges = {bottom=true}, + on_rightclick = castle_gates.trigger_gate, +}) + +minetest.register_craft({ + output = "castle_gates:"..node_prefix.."_portcullis_bars 3", + recipe = portcullis_recipe, +}) + +minetest.register_craft({ + output = "castle_gates:"..node_prefix.."_portcullis_bars", + recipe = { + {"castle_gates:"..node_prefix.."_portcullis_bars_bottom"} + }, +}) + +minetest.register_craft({ + output = "castle_gates:"..node_prefix.."_portcullis_bars_bottom", + recipe = { + {"castle_gates:"..node_prefix.."_portcullis_bars"} + }, +}) + +-------------------------------------------------------------------------------------------------------------- + +minetest.register_craft({ + output = "castle_gates:"..node_prefix.."_gate_panel 8", + recipe = panel_recipe, +}) + +minetest.register_node("castle_gates:"..node_prefix.."_gate_panel", { + drawtype = "nodebox", + description = S("@1 Gate Door", material_description), + _doc_items_longdesc = castle_gates.doc.gate_panel_longdesc, + _doc_items_usagehelp = castle_gates.doc.gate_panel_usagehelp, + groups = panel_groups, + tiles = { + material_texture.."^[transformR90", + material_texture.."^[transformR90", + material_texture.."^[transformR90", + material_texture.."^[transformR90", + material_texture.."^[transformR90", + material_texture.."^[transformR90", + }, + sounds = gate_sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, -0.25}, + } + }, + on_rightclick = castle_gates.trigger_gate, +}) + +minetest.register_craft({ + output = "castle_gates:"..node_prefix.."_gate_edge", + type = "shapeless", + recipe = {"castle_gates:"..node_prefix.."_gate_panel"}, +}) + +minetest.register_node("castle_gates:"..node_prefix.."_gate_edge", { + drawtype = "nodebox", + description = S("@1 Gate Door Edge", material_description), + _doc_items_longdesc = castle_gates.doc.gate_edge_longdesc, + _doc_items_usagehelp = castle_gates.doc.gate_edge_usagehelp, + groups = panel_groups, + tiles = { + material_texture.."^[transformR90", + material_texture.."^[transformR90", + material_texture.."^[transformR90", + material_texture.."^[transformR90", + material_texture.."^[transformR90^(default_coal_block.png^[mask:castle_door_edge_mask.png^[transformFX)", + material_texture.."^[transformR90^(default_coal_block.png^[mask:castle_door_edge_mask.png)", + }, + sounds = gate_sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, -0.25}, + } + }, + _gate_edges = {right=true}, + on_rightclick = castle_gates.trigger_gate, +}) + +minetest.register_craft({ + output = "castle_gates:"..node_prefix.."_gate_edge_handle", + type = "shapeless", + recipe = {"castle_gates:"..node_prefix.."_gate_edge"}, +}) + +minetest.register_craft({ + output = "castle_gates:"..node_prefix.."_gate_panel", + type = "shapeless", + recipe = {"castle_gates:"..node_prefix.."_gate_edge_handle"}, +}) + +minetest.register_node("castle_gates:"..node_prefix.."_gate_edge_handle", { + drawtype = "nodebox", + description = S("@1 Gate Door With Handle", material_description), + _doc_items_longdesc = castle_gates.doc.gate_edge_handle_longdesc, + _doc_items_usagehelp = castle_gates.doc.gate_edge_handle_usagehelp, + groups = panel_groups, + tiles = { + "castle_steel.png^("..material_texture.."^[mask:castle_door_side_mask.png^[transformR90)", + "castle_steel.png^("..material_texture.."^[mask:castle_door_side_mask.png^[transformR270)", + "castle_steel.png^("..material_texture.."^[transformR90^[mask:castle_door_side_mask.png)", + "castle_steel.png^("..material_texture.."^[transformR90^[mask:(castle_door_side_mask.png^[transformFX))", + material_texture.."^[transformR90^(default_coal_block.png^[mask:castle_door_edge_mask.png^[transformFX)^(castle_steel.png^[mask:castle_door_handle_mask.png^[transformFX)", + material_texture.."^[transformR90^(default_coal_block.png^[mask:castle_door_edge_mask.png)^(castle_steel.png^[mask:castle_door_handle_mask.png)", + }, + sounds = gate_sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, -0.25}, + {4/16, -4/16, -2/16, 6/16, 4/16, -3/16}, + {4/16, -4/16, -9/16, 6/16, 4/16, -10/16}, + {4/16, -4/16, -9/16, 6/16, -3/16, -3/16}, + {4/16, 4/16, -9/16, 6/16, 3/16, -3/16}, + } + }, + _gate_edges = {right=true}, + on_rightclick = castle_gates.trigger_gate, +}) + + +------------------------------------------------------------------------------ + +minetest.register_craft({ + output = "castle_gates:"..node_prefix.."_gate_hinge 3", + recipe = { + {"", "castle_gates:"..node_prefix.."_gate_panel", ""}, + {"default:steel_ingot", "castle_gates:"..node_prefix.."_gate_panel", ""}, + {"", "castle_gates:"..node_prefix.."_gate_panel", ""} + }, +}) + +minetest.register_node("castle_gates:"..node_prefix.."_gate_hinge", { + drawtype = "nodebox", + description = S("@1 Gate Door With Hinge", material_description), + _doc_items_longdesc = castle_gates.doc.gate_hinge_longdesc, + _doc_items_usagehelp = castle_gates.doc.gate_hinge_usagehelp, + groups = panel_groups, + tiles = { + material_texture.."^[transformR90", + }, + sounds = gate_sounds, + paramtype = "light", + paramtype2 = "facedir", + + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, -0.25}, + {-10/16, -4/16, -10/16, -6/16, 4/16, -6/16}, + } + }, + collision_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, -0.25}, + }, + + _gate_hinge = {axis="top", offset={"front","left"}}, + on_rightclick = castle_gates.trigger_gate, +}) + +end + +register_gates("wood", S("Wooden"), "default_wood.png", {choppy = 1, castle_gate=1}, default.node_sound_wood_defaults(), + { + {"group:wood","default:steel_ingot","group:wood" }, + {"group:wood","default:steel_ingot","group:wood" }, + {"group:wood","default:steel_ingot","group:wood" }, + }, + { + {"stairs:slab_wood","stairs:slab_wood", ""}, + {"stairs:slab_wood","stairs:slab_wood", ""}, + } +) + +register_gates("steel", S("Steel"), "default_steel_block.png", {cracky = 1, level = 2, castle_gate=1}, default.node_sound_metal_defaults(), + { + {"","default:steel_ingot","" }, + {"default:steel_ingot","default:steel_ingot","default:steel_ingot" }, + {"","default:steel_ingot","" }, + }, + { + {"stairs:slab_steelblock","stairs:slab_steelblock", ""}, + {"stairs:slab_steelblock","stairs:slab_steelblock", ""}, + } +) diff --git a/mods/castle_gates/init.lua b/mods/castle_gates/init.lua new file mode 100644 index 0000000..3292cef --- /dev/null +++ b/mods/castle_gates/init.lua @@ -0,0 +1,8 @@ +castle_gates = {} + +local modpath = minetest.get_modpath(minetest.get_current_modname()) +dofile(modpath.."/doc.lua") +dofile(modpath.."/gate_functions.lua") +dofile(modpath.."/gate_slots.lua") +dofile(modpath.."/gates.lua") +dofile(modpath.."/doors.lua") diff --git a/mods/castle_gates/intllib.lua b/mods/castle_gates/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/castle_gates/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/castle_gates/license.txt b/mods/castle_gates/license.txt new file mode 100644 index 0000000..5c3c583 --- /dev/null +++ b/mods/castle_gates/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Minetest Mods Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/castle_gates/locale/castle_gates.it.tr b/mods/castle_gates/locale/castle_gates.it.tr new file mode 100644 index 0000000..79d34a0 --- /dev/null +++ b/mods/castle_gates/locale/castle_gates.it.tr @@ -0,0 +1,16 @@ +# textdomain:castle_gates + +Oak Door=Porta di quercia +Jail Door=Porta della prigione +Jail Bars=Sbarre della prigione +@1 Portcullis Bars=Sbarre della saracinesca di @1 +@1 Portcullis Bottom=Estremità inferiore della saracinesca di @1 +@1 Gate Door=Porta di @1 del cancello +@1 Gate Door Edge=Estremità della porta di @1 del cancello +@1 Gate Door With Handle=Porta di @1 con maniglia del cancello +@1 Gate Door With Hinge=Porta di @1 con cardine del cancello +Wooden=legno +Steel=acciaio +Stonebrick=mattone di pietra +@1 Gate Slot=Alloggio di @1 del cancello +@1 Gate Slot Reverse=Rovescio dell'alloggio di @1 del cancello diff --git a/mods/castle_gates/locale/es.po b/mods/castle_gates/locale/es.po new file mode 100644 index 0000000..f1e069b --- /dev/null +++ b/mods/castle_gates/locale/es.po @@ -0,0 +1,274 @@ +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-04-14 22:15-0600\n" +"PO-Revision-Date: 2017-04-28 11:56-0400\n" +"Last-Translator: Carlos Barraza\n" +"Language-Team: LANGUAGE \n" +"Language: Español\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: doc.lua:11 +msgid "Heavy wooden bars designed to prevent entry even to siege equipment." +msgstr "" +"Barras de madera pesadas diseñadas para evitar la entrada incluso a equipo de " +"asedio" + +#: doc.lua:12 +msgid "" +"Place these bars in a structure together and they will slide as a unified " +"gate when clicked on." +msgstr "" +"Coloque estas barras en una estructura juntas y se deslizarán como si " +"estuvieran unidas cuando se le hace clic" + +#: doc.lua:14 +msgid "" +"The bottom edge of a portcullis gate, with knobs to lock securely into the " +"floor." +msgstr "" +"Es el borde inferior de una puerta rastrillo, con perillas para bloquearla " +"con seguridad en el piso" + +#: doc.lua:15 +msgid "" +"This block can be used to define the edge of a portcullius that meets up " +"with another gate, should you have an arrangement like that. Otherwise it's " +"just decorative." +msgstr "" +"Este bloque puede ser usado para definir el borde de una puerta rastrillo " +"que esta cerca de otra puerta, si tiene varias puertas independientes, de " +"lo contrario es simplemente decorativo" + +#: doc.lua:17 +msgid "A basic gate panel." +msgstr "Un panel básico de puerta" + +#: doc.lua:18 +msgid "" +"This gate segment will move in unison with adjoining gate segments when " +"right-clicked." +msgstr "" +"Este segmento de puerta se moverá junto con los demas segmentos de puerta " +"adyacente cuando se haga clic con el botón derecho del ratón" + +#: doc.lua:20 +msgid "A gate panel with a defined edge." +msgstr "Un panel de puerta con un borde." + +#: doc.lua:21 +msgid "" +"The darkened edge of this panel marks the edge of the gate it's a part of. " +"You can use these when building double doors to ensure the two parts swing " +"separately, for example. Note that edges aren't strictly necessary for gates " +"that stand alone." +msgstr "" +"El borde oscurecido de este panel marca el limite de la puerta. Usted puede " +"utilizar estos bloques para construir puertas dobles para asegurar que las " +"dos puertas funcionen por separado, por ejemplo. Tenga en cuenta que los " +"bordes no son estrictamente necesarios para las puertas individuales" + +#: doc.lua:23 +msgid "A gate edge with a handle." +msgstr "Un panel de puerta con pestillo" + +#: doc.lua:24 +msgid "" +"The handle is basically decorative, a door this size can be swung by " +"clicking anywhere on it. But the darkened edge of this panel is useful for " +"defining the edge of a gate when it abuts a partner to the side." +msgstr "" +"El pestillo es básicamente decorativo, una puerta de este tamaño se puede " +"abrir haciendo clic en cualquier parte de ella. Pero el borde oscuro de este " +"panel es útil para definir el borde de la puerta cuando hay otra puerta al " +"lado." + +#: doc.lua:26 +msgid "A hinged gate segment that allows a gate to swing." +msgstr "Un segmento de puerta con bisagra permite que la puerta se abra." + +#: doc.lua:27 +msgid "" +"If you have more than one hinge in your gate, make sure the hinges line up " +"correctly otherwise the gate will not be able to swing. The hinge is the " +"protruding block along the edge of the gate panel." +msgstr "" +"Si tiene más de una bisagra en su puerta, asegúrese de que las bisagras se " +"alineen correctamente, de lo contrario la puerta no será capaz de abrirse. " +"la bisagra es el bloque sobresaliente a lo largo del borde del panel de la " +"puerta." + +#: doc.lua:29 +msgid "A block with a slot to allow an adjacent sliding gate through." +msgstr "" +"Un bloque con una ranura en el medio para que una puerta deslizante pueda " +"pasar a travs de ella." + +#: doc.lua:30 +msgid "" +"This block is designed to extend into a neighboring node that a sliding gate " +"passes through, to provide a tight seal for the gate to move through without " +"allowing anything else to squeeze in." +msgstr "" +"Este bloque está diseñado para un nodo pueda deslizarse a travéz de este, para " +"proporcionar un cierre hermético que solo deja pasar la puerta sin permitir " +"entrar nada mas." + +#: doc.lua:32 +msgid "" +"A block that extends into an adjacent node to provide a tight seal for a " +"large gate." +msgstr "" +"Un bloque con una ranura en el lado para que una puerta deslizante pueda " +"pasar a través de ella." + +#: doc.lua:33 +msgid "" +"Two nodes cannot occupy the same space, but this block extends into a " +"neighboring node's space to allow for gates to form a tight seal. It can be " +"used with sliding gates or swinging gates." +msgstr "" +"Dos nodos no pueden utilizar el mismo espacio, pero este nodo se extiende al " +"espacio de un nodo vecino para permitir que las puertas formen un cierre " +"hermético. Puede utilizarse con puertas deslizantes y con las puertas que se " +"abren rotando." + +#: doc.lua:37 +msgid "Gates" +msgstr "Puertas" + +#: doc.lua:38 +msgid "" +"Gates are large multi-node constructions that swing on hinges or slide out " +"of the way when triggered." +msgstr "" +"Las puertas grandes son construcciones multi nodo que se abren usando " +"bisagras o se deslizan hacia arriba cuando se activan" + +#: doc.lua:43 +msgid "Gate construction" +msgstr "Construcción de Puertas" + +#: doc.lua:45 +msgid "" +"Gates are multi-node constructions, usually (though not always) consisting " +"of multiple node types that fit together into a unified whole. The " +"orientation of gate nodes is significant, so a screwdriver will be a helpful " +"tool when constructing gates.\n" +"\n" +"A gate's extent is determined by a \"flood fill\" operation. When you " +"trigger a gate block, all compatible neighboring blocks will be considered " +"part of the same structure and will move in unison. Only gate blocks that " +"are aligned with each other will be considered part of the same gate. If you " +"wish to build adjoining gates (for example, a large pair of double doors " +"that meet in the center) you'll need to make use of gate edge blocks to " +"prevent it all from being considered one big door. Note that if your gate " +"does not abut any other gates you don't actually need to define its edges " +"this way - you don't have to use edge blocks in this case.\n" +"\n" +"If a gate has no hinge nodes it will be considered a sliding gate. When " +"triggered, the gate code will search for a direction that the gate can slide " +"in and will move it in that direction at a rate of one block-length per " +"second. Once it reaches an obstruction it will stop, and when triggered " +"again it will try sliding in the opposite direction.\n" +"\n" +"If a gate has hinge nodes then triggering it will cause the gate to try " +"swinging around the hinge. If the gate has multiple hinges and they don't " +"line up properly the gate will be unable to move. Note that the gate can " +"only exist in 90-degree increments of orientation, but the gate still looks " +"for obstructions in the region it is swinging through and will not swing if " +"there's something in the way." +msgstr "" +"Las puertas son generalmente construcciones multi nodo (aunque no siempre), " +"que consisten de múltiples tipos de nodos que se acomodan en un todo " +"unificado. La orientación de los nodos de la puerta es importante, por lo que " +"un destornillador será útil para construir las puertas.\n" +"\n" +"La extención de una puerta se determina mediante una operación de \"Llenado de " +"Inundación\". Al activar un bloque de la puerta, todos los bloques vecinos " +"compatibles se considerán parte de la misma estructura y se moveran al unísono. " +"Sólo los bloques de compuerta que estén alineados entre sí se considerarán " +"parte de la misma puerta. Si desea construir puertas adyacentes (por ejemplo, " +"un gran par de puertas dobles que se abran en el centro) tendrá que hacer uso " +"de bloques de borde de puerta para evitar que todo sea considerado solo una " +"gran puerta. Tenga en cuenta que si su puerta no se apoya en ninguna otra " +"puerta, no necesita usar los bordes de puerta en este caso.\n" +"\n" +"Si una puerta no tiene nodos de bisagra se considerará una puerta deslizante. " +"Cuando se ejecuta el codigo de la puerta buscará una dirección en la que la " +"puerta pueda deslizarse y se moverá en esa dirección a una velocidad de un " +"bloque por segundo. Una vez que llega a una obstrucción se detendrá, y cuando " +"se ejecute de nuevo tratará de deslizarse en la dirección opuesta.\n" +"\n" +"Si una puerta tiene nodos de bisagra, entonces al activar la puerta tratara de " +"girar al rededor de la bisagra. Si la puerta tiene bisagras múltiples y no " +"estan bien alineadas, la puerta no podrá moverse. Tenga en cuenta que la " +"puerta sólo puede existir en incrementos de 90 grados de orientación, pero la " +"puerta todavía busca obstrucciones en la región que está moviéndose y no " +"girara si hay algo en el camino." + +#: doors.lua:8 +msgid "Oak Door" +msgstr "Puerta de Roble" + +#: doors.lua:37 +msgid "Jail Door" +msgstr "Puerta de Cárcel" + +#: doors.lua:54 +msgid "Jail Bars" +msgstr "" + +#: gates.lua:23 +#, fuzzy +msgid "@1 Portcullis Bars" +msgstr "Barras de la Puerta Rastrillo" + +#: gates.lua:53 +#, fuzzy +msgid "@1 Portcullis Bottom" +msgstr "Terminación de la Puerta Rastrillo" + +#: gates.lua:113 +#, fuzzy +msgid "@1 Gate Door" +msgstr "Porción de la Puerta" + +#: gates.lua:145 +#, fuzzy +msgid "@1 Gate Door Edge" +msgstr "Borde de la Puerta" + +#: gates.lua:184 +#, fuzzy +msgid "@1 Gate Door With Handle" +msgstr "Pestillo de la Puerta" + +#: gates.lua:227 +#, fuzzy +msgid "@1 Gate Door With Hinge" +msgstr "Bisagra de la Puerta" + +#: gates.lua:256 +msgid "Wooden" +msgstr "" + +#: gates.lua:268 +msgid "Steel" +msgstr "" + +#: gate_slots.lua:36 +msgid "Stonebrick" +msgstr "Ladrillo de Piedra" + +#: gate_slots.lua:45 +msgid "@1 Gate Slot" +msgstr "Espacio para Puerta de @1" + +#: gate_slots.lua:70 +msgid "@1 Gate Slot Reverse" +msgstr "Espacio para Puerta Invertido de @1" diff --git a/mods/castle_gates/locale/it.po b/mods/castle_gates/locale/it.po new file mode 100644 index 0000000..c6c3645 --- /dev/null +++ b/mods/castle_gates/locale/it.po @@ -0,0 +1,282 @@ +# ITALIAN LOCALE FILE FOR THE CASTLE GATES MODULE +# Copyright (C) 2017 Philipbenr And DanDuncombe +# This file is distributed under the same license as the CASTLE GATES package. +# Hamlet <54187342+h4ml3t@users.noreply.github.com> 2017, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: Castle Gates\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-04-14 22:15-0600\n" +"PO-Revision-Date: 2019-11-11 23:23+0100\n" +"Last-Translator: Hamlet <54187342+h4ml3t@users.noreply.github.com>\n" +"Language-Team: \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.2.1\n" + +#: doc.lua:11 +msgid "Heavy wooden bars designed to prevent entry even to siege equipment." +msgstr "" +"Pesanti sbarre di legno progettate per impedire l'accesso perfino " +"all'equipaggiamento da assedio." + +#: doc.lua:12 +msgid "" +"Place these bars in a structure together and they will slide as a unified " +"gate when clicked on." +msgstr "" +"Componete una struttura mettendo insieme queste sbarre ed esse scorreranno " +"come un'unica saracinesca quando ci si cliccherà sopra." + +#: doc.lua:14 +msgid "" +"The bottom edge of a portcullis gate, with knobs to lock securely into the " +"floor." +msgstr "" +"La parte inferiore di una saracinesca, con puntali per bloccarsi saldamente " +"nel pavimento." + +#: doc.lua:15 +msgid "" +"This block can be used to define the edge of a portcullius that meets up " +"with another gate, should you have an arrangement like that. Otherwise it's " +"just decorative." +msgstr "" +"Questo blocco può essere usato per definire l'estremità di una saracinesca " +"che si incontra con un'altra, se doveste avere una tale disposizione. " +"Altrimenti è solo decorativo." + +#: doc.lua:17 +msgid "A basic gate panel." +msgstr "Un pannello di base per cancelli, porte e portoni." + +#: doc.lua:18 +msgid "" +"This gate segment will move in unison with adjoining gate segments when " +"right-clicked." +msgstr "" +"Questo segmento si muoverà all'unisono con altri segmenti adiacenti quando " +"cliccato col tasto destro." + +#: doc.lua:20 +msgid "A gate panel with a defined edge." +msgstr "" +"Un pannello per cancelli, porte e portoni avente un'estremità definita." + +#: doc.lua:21 +msgid "" +"The darkened edge of this panel marks the edge of the gate it's a part of. " +"You can use these when building double doors to ensure the two parts swing " +"separately, for example. Note that edges aren't strictly necessary for gates " +"that stand alone." +msgstr "" +"L'estremità annerita di questo pannello contrassegna il bordo del cancello, " +"porta o portone di cui fa parte. Per esempio potete usarla quando costruite " +"doppi battenti per assicurarvi che le due parti ruotino separatamente. Si " +"noti che queste estremità non sono strettamente necessarie per cancelli, " +"porte e portoni a battente singolo." + +#: doc.lua:23 +msgid "A gate edge with a handle." +msgstr "Una estremità di cancello, porta o portone con una maniglia." + +#: doc.lua:24 +msgid "" +"The handle is basically decorative, a door this size can be swung by " +"clicking anywhere on it. But the darkened edge of this panel is useful for " +"defining the edge of a gate when it abuts a partner to the side." +msgstr "" +"Fondamentalmente la maniglia è decorativa, un cancello o porta di queste " +"dimensioni possono essere aperti cliccando un punto qualunque su di essi. Ma " +"il bordo annerito di questo pannello è utile per stabilire la fine di un " +"battente quando confina con un altro." + +#: doc.lua:26 +msgid "A hinged gate segment that allows a gate to swing." +msgstr "" +"Un segmento di cancello, porta o portone provvisto di un cardine che ne " +"consente la rotazione." + +#: doc.lua:27 +msgid "" +"If you have more than one hinge in your gate, make sure the hinges line up " +"correctly otherwise the gate will not be able to swing. The hinge is the " +"protruding block along the edge of the gate panel." +msgstr "" +"Se avete più di un cardine nel vostro cancello, porta o portone, accertatevi " +"che siano allineati correttamente altrimenti non potrà ruotare. Il cardine è " +"la protuberanza lungo il bordo del pannello." + +#: doc.lua:29 +msgid "A block with a slot to allow an adjacent sliding gate through." +msgstr "" +"Un blocco provvisto di una fessura per consentire a una porta scorrevole di " +"scivolarci attraverso." + +#: doc.lua:30 +msgid "" +"This block is designed to extend into a neighboring node that a sliding gate " +"passes through, to provide a tight seal for the gate to move through without " +"allowing anything else to squeeze in." +msgstr "" +"Questo blocco è progettato per estendersi in un nodo vicino attraverso cui " +"scivoli una porta scorrevole, per fornire una chiusura ermetica alla porta o " +"saracinesca che gli passa attraverso senza permettere a niente altro di " +"intrufolarvisi." + +#: doc.lua:32 +msgid "" +"A block that extends into an adjacent node to provide a tight seal for a " +"large gate." +msgstr "" +"Un blocco che si estende in un nodo adiacente per fornire una chiusura " +"ermetica per un portone." + +#: doc.lua:33 +msgid "" +"Two nodes cannot occupy the same space, but this block extends into a " +"neighboring node's space to allow for gates to form a tight seal. It can be " +"used with sliding gates or swinging gates." +msgstr "" +"Due nodi non possono occupare lo stesso spazio, ma questo blocco si estende " +"nello spazio di un nodo vicino per consentire a cancelli, porte, portoni e " +"saracinesche di formare una chiusura ermetica. Può essere usato con porte " +"scorrevoli o a rotazione." + +#: doc.lua:37 +msgid "Gates" +msgstr "Cancelli, porte, portoni e saracinesche" + +#: doc.lua:38 +msgid "" +"Gates are large multi-node constructions that swing on hinges or slide out " +"of the way when triggered." +msgstr "" +"Cancelli, porte, portoni e saracinesche sono costruzioni multi-nodo che " +"quando vengono attivate ruotano su dei cardini o scivolano via." + +#: doc.lua:43 +msgid "Gate construction" +msgstr "Costruzione di cancelli, porte, portoni e saracinesche" + +#: doc.lua:45 +msgid "" +"Gates are multi-node constructions, usually (though not always) consisting " +"of multiple node types that fit together into a unified whole. The " +"orientation of gate nodes is significant, so a screwdriver will be a helpful " +"tool when constructing gates.\n" +"\n" +"A gate's extent is determined by a \"flood fill\" operation. When you " +"trigger a gate block, all compatible neighboring blocks will be considered " +"part of the same structure and will move in unison. Only gate blocks that " +"are aligned with each other will be considered part of the same gate. If you " +"wish to build adjoining gates (for example, a large pair of double doors " +"that meet in the center) you'll need to make use of gate edge blocks to " +"prevent it all from being considered one big door. Note that if your gate " +"does not abut any other gates you don't actually need to define its edges " +"this way - you don't have to use edge blocks in this case.\n" +"\n" +"If a gate has no hinge nodes it will be considered a sliding gate. When " +"triggered, the gate code will search for a direction that the gate can slide " +"in and will move it in that direction at a rate of one block-length per " +"second. Once it reaches an obstruction it will stop, and when triggered " +"again it will try sliding in the opposite direction.\n" +"\n" +"If a gate has hinge nodes then triggering it will cause the gate to try " +"swinging around the hinge. If the gate has multiple hinges and they don't " +"line up properly the gate will be unable to move. Note that the gate can " +"only exist in 90-degree increments of orientation, but the gate still looks " +"for obstructions in the region it is swinging through and will not swing if " +"there's something in the way." +msgstr "" +"Cancelli, porte, portoni e saracinesche sono costruzioni multi-nodo, di " +"solito (anche se non sempre) costituite da molteplici tipi di nodi che si " +"uniscono in un tutt'uno. L'orientamento è importante, perciò un cacciavite " +"sarà uno strumento utile quando si costruiscono cancelli, porte, ecc.\n" +"\n" +"L'estensione di cancelli e simili è stabilita da un'operazione \"flood fill" +"\" (allagamento riempitivo). Quando attivate un blocco di cancello, tutte le " +"parti limitrofe compatibili verranno considerate parte della stessa " +"struttura e si muoveranno all'unisono. Solamente i blocchi che sono " +"allineati l'un l'altro saranno considerati come parte dello stesso cancello. " +"Se desiderate costruire cancelli confinanti (per esempio, un paio di grossi " +"battenti che si incontrano nel mezzo) dovrete fare uso dei blocchi-estremità " +"per impedire che il tutto sia considerato come un'unica grossa porta. Si " +"noti che se il vostro cancello non confina con nessun altro non avete la " +"necessità di definirne le estremità in questo modo - in questo caso non è " +"necessario che usiate blocchi-estremità.\n" +"\n" +"Se un cancello, ecc. non ha nodi coi cardini sarà considerato come " +"scorrevole. Quando attivato, il programma del cancello cercherà una " +"direzione in cui possa scivolare e lo muoverà in quella direzione al passo " +"della distanza di un nodo al secondo. Quando raggiungerà un ostacolo si " +"fermerà, e quando attivato ancora tenterà di scorrere nella direzione " +"opposta.\n" +"\n" +"Se un cancello, ecc. ha dei nodi coi cardini, attivandolo lo si farà ruotare " +"attorno al cardine. Se il cancello ha più cardini e questi non sono " +"allineati correttamente non riuscirà a muoversi. Si noti che il cancello può " +"svilupparsi solo in incrementi di 90° di orientamento, e controllerà la " +"presenza di ostacoli nella zona in cui ruota e non ruoterà se c'è qualcosa " +"di mezzo." + +#: doors.lua:8 +msgid "Oak Door" +msgstr "Porta di quercia" + +#: doors.lua:37 +msgid "Jail Door" +msgstr "Porta della prigione" + +#: doors.lua:54 +msgid "Jail Bars" +msgstr "Sbarre della prigione" + +#: gates.lua:23 +msgid "@1 Portcullis Bars" +msgstr "Sbarre della saracinesca di @1" + +#: gates.lua:53 +msgid "@1 Portcullis Bottom" +msgstr "Estremità inferiore della saracinesca di @1" + +#: gates.lua:113 +msgid "@1 Gate Door" +msgstr "Porta di @1 del cancello" + +#: gates.lua:145 +msgid "@1 Gate Door Edge" +msgstr "Estremità della porta di @1 del cancello" + +#: gates.lua:184 +msgid "@1 Gate Door With Handle" +msgstr "Porta di @1 con maniglia del cancello" + +#: gates.lua:227 +msgid "@1 Gate Door With Hinge" +msgstr "Porta di @1 con cardine del cancello" + +#: gates.lua:256 +msgid "Wooden" +msgstr "legno" + +#: gates.lua:268 +msgid "Steel" +msgstr "acciaio" + +#: gate_slots.lua:36 +msgid "Stonebrick" +msgstr "mattone di pietra" + +#: gate_slots.lua:45 +msgid "@1 Gate Slot" +msgstr "Alloggio di @1 per cancelli, porte, portoni e saracinesche" + +#: gate_slots.lua:70 +msgid "@1 Gate Slot Reverse" +msgstr "" +"Rovescio dell'alloggio di @1 per cancelli, porte, portoni e saracinesche" diff --git a/mods/castle_gates/locale/template.pot b/mods/castle_gates/locale/template.pot new file mode 100644 index 0000000..8a921e3 --- /dev/null +++ b/mods/castle_gates/locale/template.pot @@ -0,0 +1,210 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-04-14 22:15-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: doc.lua:11 +msgid "Heavy wooden bars designed to prevent entry even to siege equipment." +msgstr "" + +#: doc.lua:12 +msgid "" +"Place these bars in a structure together and they will slide as a unified " +"gate when clicked on." +msgstr "" + +#: doc.lua:14 +msgid "" +"The bottom edge of a portcullis gate, with knobs to lock securely into the " +"floor." +msgstr "" + +#: doc.lua:15 +msgid "" +"This block can be used to define the edge of a portcullius that meets up " +"with another gate, should you have an arrangement like that. Otherwise it's " +"just decorative." +msgstr "" + +#: doc.lua:17 +msgid "A basic gate panel." +msgstr "" + +#: doc.lua:18 +msgid "" +"This gate segment will move in unison with adjoining gate segments when " +"right-clicked." +msgstr "" + +#: doc.lua:20 +msgid "A gate panel with a defined edge." +msgstr "" + +#: doc.lua:21 +msgid "" +"The darkened edge of this panel marks the edge of the gate it's a part of. " +"You can use these when building double doors to ensure the two parts swing " +"separately, for example. Note that edges aren't strictly necessary for gates " +"that stand alone." +msgstr "" + +#: doc.lua:23 +msgid "A gate edge with a handle." +msgstr "" + +#: doc.lua:24 +msgid "" +"The handle is basically decorative, a door this size can be swung by " +"clicking anywhere on it. But the darkened edge of this panel is useful for " +"defining the edge of a gate when it abuts a partner to the side." +msgstr "" + +#: doc.lua:26 +msgid "A hinged gate segment that allows a gate to swing." +msgstr "" + +#: doc.lua:27 +msgid "" +"If you have more than one hinge in your gate, make sure the hinges line up " +"correctly otherwise the gate will not be able to swing. The hinge is the " +"protruding block along the edge of the gate panel." +msgstr "" + +#: doc.lua:29 +msgid "A block with a slot to allow an adjacent sliding gate through." +msgstr "" + +#: doc.lua:30 +msgid "" +"This block is designed to extend into a neighboring node that a sliding gate " +"passes through, to provide a tight seal for the gate to move through without " +"allowing anything else to squeeze in." +msgstr "" + +#: doc.lua:32 +msgid "" +"A block that extends into an adjacent node to provide a tight seal for a " +"large gate." +msgstr "" + +#: doc.lua:33 +msgid "" +"Two nodes cannot occupy the same space, but this block extends into a " +"neighboring node's space to allow for gates to form a tight seal. It can be " +"used with sliding gates or swinging gates." +msgstr "" + +#: doc.lua:37 +msgid "Gates" +msgstr "" + +#: doc.lua:38 +msgid "" +"Gates are large multi-node constructions that swing on hinges or slide out " +"of the way when triggered." +msgstr "" + +#: doc.lua:43 +msgid "Gate construction" +msgstr "" + +#: doc.lua:45 +msgid "" +"Gates are multi-node constructions, usually (though not always) consisting " +"of multiple node types that fit together into a unified whole. The " +"orientation of gate nodes is significant, so a screwdriver will be a helpful " +"tool when constructing gates.\n" +"\n" +"A gate's extent is determined by a \"flood fill\" operation. When you " +"trigger a gate block, all compatible neighboring blocks will be considered " +"part of the same structure and will move in unison. Only gate blocks that " +"are aligned with each other will be considered part of the same gate. If you " +"wish to build adjoining gates (for example, a large pair of double doors " +"that meet in the center) you'll need to make use of gate edge blocks to " +"prevent it all from being considered one big door. Note that if your gate " +"does not abut any other gates you don't actually need to define its edges " +"this way - you don't have to use edge blocks in this case.\n" +"\n" +"If a gate has no hinge nodes it will be considered a sliding gate. When " +"triggered, the gate code will search for a direction that the gate can slide " +"in and will move it in that direction at a rate of one block-length per " +"second. Once it reaches an obstruction it will stop, and when triggered " +"again it will try sliding in the opposite direction.\n" +"\n" +"If a gate has hinge nodes then triggering it will cause the gate to try " +"swinging around the hinge. If the gate has multiple hinges and they don't " +"line up properly the gate will be unable to move. Note that the gate can " +"only exist in 90-degree increments of orientation, but the gate still looks " +"for obstructions in the region it is swinging through and will not swing if " +"there's something in the way." +msgstr "" + +#: doors.lua:8 +msgid "Oak Door" +msgstr "" + +#: doors.lua:37 +msgid "Jail Door" +msgstr "" + +#: doors.lua:54 +msgid "Jail Bars" +msgstr "" + +#: gates.lua:23 +msgid "@1 Portcullis Bars" +msgstr "" + +#: gates.lua:53 +msgid "@1 Portcullis Bottom" +msgstr "" + +#: gates.lua:113 +msgid "@1 Gate Door" +msgstr "" + +#: gates.lua:145 +msgid "@1 Gate Door Edge" +msgstr "" + +#: gates.lua:184 +msgid "@1 Gate Door With Handle" +msgstr "" + +#: gates.lua:227 +msgid "@1 Gate Door With Hinge" +msgstr "" + +#: gates.lua:256 +msgid "Wooden" +msgstr "" + +#: gates.lua:268 +msgid "Steel" +msgstr "" + +#: gate_slots.lua:36 +msgid "Stonebrick" +msgstr "" + +#: gate_slots.lua:45 +msgid "@1 Gate Slot" +msgstr "" + +#: gate_slots.lua:70 +msgid "@1 Gate Slot Reverse" +msgstr "" diff --git a/mods/castle_gates/locale/template.txt b/mods/castle_gates/locale/template.txt new file mode 100644 index 0000000..3817f39 --- /dev/null +++ b/mods/castle_gates/locale/template.txt @@ -0,0 +1,16 @@ +# textdomain:castle_gates + +Oak Door= +Jail Door= +Jail Bars= +@1 Portcullis Bars= +@1 Portcullis Bottom= +@1 Gate Door= +@1 Gate Door Edge= +@1 Gate Door With Handle= +@1 Gate Door With Hinge= +Wooden= +Steel= +Stonebrick= +@1 Gate Slot= +@1 Gate Slot Reverse= diff --git a/mods/castle_gates/locale/update.bat b/mods/castle_gates/locale/update.bat new file mode 100644 index 0000000..e87d44c --- /dev/null +++ b/mods/castle_gates/locale/update.bat @@ -0,0 +1,6 @@ +@echo off +setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION +cd .. +set LIST= +for /r %%X in (*.lua) do set LIST=!LIST! %%X +..\intllib\tools\xgettext.bat %LIST% \ No newline at end of file diff --git a/mods/castle_gates/mod.conf b/mods/castle_gates/mod.conf new file mode 100644 index 0000000..bac9366 --- /dev/null +++ b/mods/castle_gates/mod.conf @@ -0,0 +1,4 @@ +name = castle_gates +description = This is a mod all about creating castles and castle dungeons. Many of the nodes are used for the outer-walls or dungeons. +depends = default +optional_depends = castle_masonry, doors, xpanes, intllib, doc diff --git a/mods/castle_gates/screenshot.png b/mods/castle_gates/screenshot.png new file mode 100644 index 0000000..28fd97b Binary files /dev/null and b/mods/castle_gates/screenshot.png differ diff --git a/mods/castle_gates/textures/LICENSE.txt b/mods/castle_gates/textures/LICENSE.txt new file mode 100644 index 0000000..38224f3 --- /dev/null +++ b/mods/castle_gates/textures/LICENSE.txt @@ -0,0 +1,11 @@ +16 px textures based on Castle mod +original textures by Philipner + +License Textures: Napiophelios - CC-BY-SA 3.0 + +-castle_door_jail.png +-castle_door_oak.png +-castle_jail_door_inv.png +-castle_jailbars.png +-castle_oak_door_inv.png +-castle_steel.png diff --git a/mods/castle_gates/textures/castle_door_edge_mask.png b/mods/castle_gates/textures/castle_door_edge_mask.png new file mode 100644 index 0000000..15fcf12 Binary files /dev/null and b/mods/castle_gates/textures/castle_door_edge_mask.png differ diff --git a/mods/castle_gates/textures/castle_door_handle_mask.png b/mods/castle_gates/textures/castle_door_handle_mask.png new file mode 100644 index 0000000..1200a6e Binary files /dev/null and b/mods/castle_gates/textures/castle_door_handle_mask.png differ diff --git a/mods/castle_gates/textures/castle_door_jail.png b/mods/castle_gates/textures/castle_door_jail.png new file mode 100644 index 0000000..930cf3b Binary files /dev/null and b/mods/castle_gates/textures/castle_door_jail.png differ diff --git a/mods/castle_gates/textures/castle_door_oak.png b/mods/castle_gates/textures/castle_door_oak.png new file mode 100644 index 0000000..2282fb2 Binary files /dev/null and b/mods/castle_gates/textures/castle_door_oak.png differ diff --git a/mods/castle_gates/textures/castle_door_side_mask.png b/mods/castle_gates/textures/castle_door_side_mask.png new file mode 100644 index 0000000..b28f16f Binary files /dev/null and b/mods/castle_gates/textures/castle_door_side_mask.png differ diff --git a/mods/castle_gates/textures/castle_jail_door_inv.png b/mods/castle_gates/textures/castle_jail_door_inv.png new file mode 100644 index 0000000..3ff9da1 Binary files /dev/null and b/mods/castle_gates/textures/castle_jail_door_inv.png differ diff --git a/mods/castle_gates/textures/castle_jailbars.png b/mods/castle_gates/textures/castle_jailbars.png new file mode 100644 index 0000000..bd858a1 Binary files /dev/null and b/mods/castle_gates/textures/castle_jailbars.png differ diff --git a/mods/castle_gates/textures/castle_oak_door_inv.png b/mods/castle_gates/textures/castle_oak_door_inv.png new file mode 100644 index 0000000..1122d51 Binary files /dev/null and b/mods/castle_gates/textures/castle_oak_door_inv.png differ diff --git a/mods/castle_gates/textures/castle_portcullis_mask.png b/mods/castle_gates/textures/castle_portcullis_mask.png new file mode 100644 index 0000000..8d12f83 Binary files /dev/null and b/mods/castle_gates/textures/castle_portcullis_mask.png differ diff --git a/mods/castle_gates/textures/castle_steel.png b/mods/castle_gates/textures/castle_steel.png new file mode 100644 index 0000000..28ecd60 Binary files /dev/null and b/mods/castle_gates/textures/castle_steel.png differ diff --git a/mods/castle_lighting/README.md b/mods/castle_lighting/README.md new file mode 100644 index 0000000..85241a9 --- /dev/null +++ b/mods/castle_lighting/README.md @@ -0,0 +1,18 @@ +## Castle Lighting + +By: Philipbenr, DanDuncombe, FaceDeer + +Licence: MIT + +=-=-=-=-=-=-=-=-=-= + +This mod contains medieval lighting sources suitable for a castle. It includes: + +* Small chandelier and hanging chain +* Lantern box +* Steel floor brasier +* Stone pedestal/column brasier. + +If the castle_masonry mod is installed, brasiers will be generated for all enabled material types. + +Brasiers require fuel to generate a flame. \ No newline at end of file diff --git a/mods/castle_lighting/brasier.lua b/mods/castle_lighting/brasier.lua new file mode 100644 index 0000000..7e80773 --- /dev/null +++ b/mods/castle_lighting/brasier.lua @@ -0,0 +1,267 @@ +if not minetest.get_modpath("fire") then return end + +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +local brasier_longdesc = S("A brasier for producing copious amounts of light and heat.") +local brasier_usagehelp = S("To ignite the brasier place a flammable fuel in its inventory slot. A lump of coal will burn for about half an hour.") + +local brasier_nodebox = { + type = "fixed", + fixed = { + {-0.25, 0, -0.25, 0.25, 0.125, 0.25}, -- base + {-0.375, 0.125, -0.375, 0.375, 0.25, 0.375}, -- mid + {-0.5, 0.25, -0.5, 0.5, 0.375, 0.5}, -- plat + {-0.5, 0.375, 0.375, 0.5, 0.5, 0.5}, -- edge + {-0.5, 0.375, -0.5, 0.5, 0.5, -0.375}, -- edge + {0.375, 0.375, -0.375, 0.5, 0.5, 0.375}, -- edge + {-0.5, 0.375, -0.375, -0.375, 0.5, 0.375}, -- edge + {0.25, -0.5, -0.375, 0.375, 0.125, -0.25}, -- leg + {-0.375, -0.5, 0.25, -0.25, 0.125, 0.375}, -- leg + {0.25, -0.5, 0.25, 0.375, 0.125, 0.375}, -- leg + {-0.375, -0.5, -0.375, -0.25, 0.125, -0.25}, -- leg + {-0.125, -0.0625, -0.125, 0.125, 0, 0.125}, -- bottom_knob + } +} +local brasier_selection_box = { + type = "fixed", + fixed = { + {-0.375, -0.5, -0.375, 0.375, 0.25, 0.375}, -- mid + {-0.5, 0.25, -0.5, 0.5, 0.5, 0.5}, -- plat + } +} + +local brasier_burn = function(pos) + local pos_above = {x=pos.x, y=pos.y+1, z=pos.z} + local node_above = minetest.get_node(pos_above) + local timer = minetest.get_node_timer(pos) + + if timer:is_started() and node_above.name == "epic:permanent_flame" then return end -- already burning, don't burn a new thing. + + local inv = minetest.get_inventory({type="node", pos=pos}) + local item = inv:get_stack("fuel", 1) + local fuel_burned = minetest.get_craft_result({method="fuel", width=1, items={item:peek_item(1)}}).time + + if fuel_burned > 0 and (node_above.name == "air" or node_above.name == "epic:permanent_flame") then + item:set_count(item:get_count() - 1) + inv:set_stack("fuel", 1, item) + + timer:start(fuel_burned * 60) -- one minute of flame per second of burn time, for balance. + + if node_above.name == "air" then + minetest.set_node(pos_above, {name = "epic:permanent_flame"}) + end + else + if node_above.name == "epic:permanent_flame" then + minetest.set_node(pos_above, {name = "air"}) + end + end +end + +local brasier_on_construct = function(pos) + local inv = minetest.get_meta(pos):get_inventory() + inv:set_size("fuel", 1) + + local meta = minetest.get_meta(pos) + meta:set_string("formspec", + "size[8,5.3]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;fuel;3.5,0;1,1;]" .. + "list[current_player;main;0,1.15;8,1;]" .. + "list[current_player;main;0,2.38;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,1.15) + ) +end + +local brasier_on_destruct = function(pos, oldnode) + local pos_above = {x=pos.x, y=pos.y+1, z=pos.z} + local node_above = minetest.get_node(pos_above) + if node_above.name == "epic:permanent_flame" then + minetest.set_node(pos_above, {name = "air"}) + end +end + +local brasier_can_dig = function(pos, player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("fuel") +end + +-- Only allow fuel items to be placed in fuel +local brasier_allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "fuel" then + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + return stack:get_count() + else + return 0 + end + end + return 0 +end + +minetest.register_node("castle_lighting:brasier_floor", { + description = S("Floor Brasier"), + _doc_items_longdesc = brasier_longdesc, + _doc_items_usagehelp = brasier_usagehelp, + tiles = { + "castle_steel.png^(castle_coal_bed.png^[mask:castle_brasier_bed_mask.png)", + "castle_steel.png", + "castle_steel.png", + "castle_steel.png", + "castle_steel.png", + "castle_steel.png", + }, + drawtype = "nodebox", + groups = {cracky=2}, + paramtype = "light", + node_box = brasier_nodebox, + selection_box = brasier_selection_box, + + on_construct = brasier_on_construct, + on_destruct = brasier_on_destruct, + can_dig = brasier_can_dig, + allow_metadata_inventory_put = brasier_allow_metadata_inventory_put, + on_metadata_inventory_put = brasier_burn, + on_timer = brasier_burn, +}) + + +minetest.register_craft({ + output = "castle_lighting:brasier_floor", + recipe = { + {"default:steel_ingot", "default:torch", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + } +}) + +if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then + hopper:add_container({ + {"top", "castle_lighting:brasier_floor", "fuel"}, + {"bottom", "castle_lighting:brasier_floor", "fuel"}, + {"side", "castle_lighting:brasier_floor", "fuel"}, + }) +end + +------------------------------------------------------------------------------------------------------ +-- Masonry brasiers + +local materials +if minetest.get_modpath("castle_masonry") then + materials = castle_masonry.materials +else + materials = {{name="stonebrick", desc=S("Stonebrick"), tile="default_stone_brick.png", craft_material="default:stonebrick"}} +end + +local get_material_properties = function(material) + local composition_def + local burn_time + if material.composition_material ~= nil then + composition_def = minetest.registered_nodes[material.composition_material] + burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.composition_material)}}).time + else + composition_def = minetest.registered_nodes[material.craft_material] + burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.craft_materia)}}).time + end + + local tiles = material.tile + if tiles == nil then + tiles = composition_def.tile + elseif type(tiles) == "string" then + tiles = {tiles} + end + + -- Apply bed of coals to the texture. + if table.getn(tiles) == 1 then + tiles = {tiles[1].."^(castle_coal_bed.png^[mask:castle_brasier_bed_mask.png)", tiles[1], tiles[1], tiles[1], tiles[1], tiles[1]} + else + tiles[1] = tiles[1].."^(castle_coal_bed.png^[mask:castle_brasier_bed_mask.png)" + end + + local desc = material.desc + if desc == nil then + desc = composition_def.description + end + + return composition_def, burn_time, tiles, desc +end + +local pillar_brasier_nodebox = { + type = "fixed", + fixed = { + {-0.375, 0.125, -0.375, 0.375, 0.25, 0.375}, -- mid + {-0.5, 0.25, -0.5, 0.5, 0.375, 0.5}, -- plat + {-0.5, 0.375, 0.375, 0.5, 0.5, 0.5}, -- edge + {-0.5, 0.375, -0.5, 0.5, 0.5, -0.375}, -- edge + {0.375, 0.375, -0.375, 0.5, 0.5, 0.375}, -- edge + {-0.5, 0.375, -0.375, -0.375, 0.5, 0.375}, -- edge + {-0.25,-0.5,-0.25,0.25,0.125,0.25}, -- support + } +} + +local pillar_brasier_selection_box = { + type = "fixed", + fixed = { + {-0.375, 0.125, -0.375, 0.375, 0.25, 0.375}, -- mid + {-0.5, 0.25, -0.5, 0.5, 0.5, 0.5}, -- plat + {-0.25,-0.5,-0.25,0.25,0.125,0.25}, -- support + } +} + +castle_lighting.register_pillar_brasier = function(material) + local composition_def, burn_time, tile, desc = get_material_properties(material) + if burn_time > 0 or composition_def.groups.puts_out_fire then return end -- No wooden brasiers, snow brasiers, or ice brasiers, alas. + + local crossbrace_connectable_groups = {} + for group, val in pairs(composition_def.groups) do + crossbrace_connectable_groups[group] = val + end + crossbrace_connectable_groups.crossbrace_connectable = 1 + + local mod_name = minetest.get_current_modname() + + minetest.register_node(mod_name..":"..material.name.."_pillar_brasier", { + drawtype = "nodebox", + description = S("@1 Brasier", desc), + _doc_items_longdesc = brasier_longdesc, + _doc_items_usagehelp = brasier_usagehelp, + tiles = tile, + paramtype = "light", + paramtype2 = "facedir", + groups = crossbrace_connectable_groups, + sounds = composition_def.sounds, + + node_box = pillar_brasier_nodebox, + selection_box = pillar_brasier_selection_box, + + on_construct = brasier_on_construct, + on_destruct = brasier_on_destruct, + can_dig = brasier_can_dig, + allow_metadata_inventory_put = brasier_allow_metadata_inventory_put, + on_metadata_inventory_put = brasier_burn, + on_timer = brasier_burn, + }) + + minetest.register_craft({ + output = mod_name..":"..material.name.."_pillar_brasier 5", + recipe = { + {material.craft_material,"default:torch",material.craft_material}, + {material.craft_material,material.craft_material,material.craft_material}, + }, + }) + + if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then + hopper:add_container({ + {"top", mod_name..":"..material.name.."_pillar_brasier", "fuel"}, + {"bottom", mod_name..":"..material.name.."_pillar_brasier", "fuel"}, + {"side", mod_name..":"..material.name.."_pillar_brasier", "fuel"}, + }) + end +end + +for _, material in pairs(materials) do + castle_lighting.register_pillar_brasier(material) +end diff --git a/mods/castle_lighting/init.lua b/mods/castle_lighting/init.lua new file mode 100644 index 0000000..7ef9b20 --- /dev/null +++ b/mods/castle_lighting/init.lua @@ -0,0 +1,99 @@ +minetest.register_alias("castle:street_light", "castle_lighting:light") +minetest.register_alias("castle:light", "castle_lighting:light") +minetest.register_alias("castle:chandelier", "castle_lighting:chandelier") +minetest.register_alias("castle:chandelier_chain", "castle_lighting:chandelier_chain") + +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +castle_lighting = {} + +dofile(MP.."/brasier.lua") + +minetest.register_node("castle_lighting:light",{ + drawtype = "glasslike", + description = S("Light Block"), + sunlight_propagates = true, + light_source = 14, + tiles = {"castle_street_light.png"}, + groups = {cracky=2}, + sounds = default.node_sound_glass_defaults(), + paramtype = "light", +}) + +minetest.register_craft({ + output = "castle_lighting:light", + recipe = { + {"default:stick", "default:glass", "default:stick"}, + {"default:glass", "default:torch", "default:glass"}, + {"default:stick", "default:glass", "default:stick"}, + } +}) + +minetest.register_node( "castle_lighting:chandelier", { + drawtype = "plantlike", + description = S("Chandelier"), + paramtype = "light", + wield_image = "castle_chandelier_wield.png", + inventory_image = "castle_chandelier_wield.png", + groups = {cracky=2}, + sounds = default.node_sound_glass_defaults(), + sunlight_propagates = true, + light_source = 14, + tiles = { + { + name = "castle_chandelier.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.0 + }, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {0.35,-0.375,0.35,-0.35,0.5,-0.35}, + + }, + }, +}) + +minetest.register_craft({ + output = "castle_lighting:chandelier", + recipe = { + {"", "", ""}, + {"", "default:steel_ingot", ""}, + {"default:torch","default:torch","default:torch"}, + } +}) + +minetest.register_node( "castle_lighting:chandelier_chain", { + drawtype = "plantlike", + description = S("Chandelier Chain"), + paramtype = "light", + wield_image = "castle_chandelier_chain.png", + inventory_image = "castle_chandelier_chain.png", + groups = {cracky=2}, + sounds = default.node_sound_glass_defaults(), + sunlight_propagates = true, + tiles = {"castle_chandelier_chain.png"}, + selection_box = { + type = "fixed", + fixed = { + {0.1,-0.5,0.1,-0.1,0.5,-0.1}, + + }, + }, +}) + +minetest.register_craft({ + output = "castle_lighting:chandelier_chain 4", + recipe = { + {"", "default:steel_ingot", ""}, + {"", "", ""}, + {"","default:steel_ingot",""}, + } +}) diff --git a/mods/castle_lighting/intllib.lua b/mods/castle_lighting/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/castle_lighting/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/castle_lighting/license.txt b/mods/castle_lighting/license.txt new file mode 100644 index 0000000..456d091 --- /dev/null +++ b/mods/castle_lighting/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Minetest Mods Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/castle_lighting/locale/es.po b/mods/castle_lighting/locale/es.po new file mode 100644 index 0000000..f0faee9 --- /dev/null +++ b/mods/castle_lighting/locale/es.po @@ -0,0 +1,54 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-01 23:52-0700\n" +"PO-Revision-Date: 2017-04-28 12:40-0400\n" +"Last-Translator: Carlos Barraza\n" +"Language-Team: LANGUAGE \n" +"Language: Español\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: brasier.lua:7 +msgid "A brasier for producing copious amounts of light and heat." +msgstr "Un brasero para producir grandes cantidades de luz y calor." + +#: brasier.lua:8 +msgid "" +"To ignite the brasier place a flammable fuel in its inventory slot. A lump " +"of coal will burn for about half an hour." +msgstr "" +"Para encender el brasero coloque un combustible inflamable en su ranura de " +"inventario. Un trozo de carbón arderá durante media hora." + +#: brasier.lua:107 +msgid "Floor Brasier" +msgstr "Brasero con Patas" + +#: brasier.lua:156 +msgid "Stonebrick" +msgstr "Ladrillo de piedra" + +#: brasier.lua:228 +msgid "@1 Brasier" +msgstr "Brasero de @1" + +#: init.lua:17 +msgid "Light Block" +msgstr "Bloque de luz" + +#: init.lua:37 +msgid "Chandelier" +msgstr "Candelero" + +#: init.lua:76 +msgid "Chandelier Chain" +msgstr "Colgante de Candelero" diff --git a/mods/castle_lighting/locale/it.po b/mods/castle_lighting/locale/it.po new file mode 100644 index 0000000..5acbb71 --- /dev/null +++ b/mods/castle_lighting/locale/it.po @@ -0,0 +1,55 @@ +# ITALIAN LOCALE FILE FOR THE CASTLE LIGHTING MODULE +# Copyright (C) 2017 Philipbenr And DanDuncombe +# This file is distributed under the same license as the CASTLE LIGHTING package. +# Hamlet , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: Castle Lighting\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-01 23:52-0700\n" +"PO-Revision-Date: 2017-09-10 22:00+0100\n" +"Last-Translator: H4mlet \n" +"Language-Team: \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.6.10\n" + +#: brasier.lua:7 +msgid "A brasier for producing copious amounts of light and heat." +msgstr "Un braciere per produrre grandi quantità di luce e calore." + +#: brasier.lua:8 +msgid "" +"To ignite the brasier place a flammable fuel in its inventory slot. A lump " +"of coal will burn for about half an hour." +msgstr "" +"Per accendere il braciere mettete del combustibile nella sua casella di " +"inventario. Un grumo di carbone brucerà per circa mezz'ora." + +#: brasier.lua:107 +msgid "Floor Brasier" +msgstr "Braciere da pavimento" + +#: brasier.lua:156 +msgid "Stonebrick" +msgstr "Mattoni di pietra" + +#: brasier.lua:228 +msgid "@1 Brasier" +msgstr "Braciere di @1" + +#: init.lua:17 +msgid "Light Block" +msgstr "Lampada" + +#: init.lua:37 +msgid "Chandelier" +msgstr "Candeliere" + +#: init.lua:76 +msgid "Chandelier Chain" +msgstr "Catena per candeliere" diff --git a/mods/castle_lighting/locale/template.pot b/mods/castle_lighting/locale/template.pot new file mode 100644 index 0000000..e7f0768 --- /dev/null +++ b/mods/castle_lighting/locale/template.pot @@ -0,0 +1,52 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-01 23:52-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: brasier.lua:7 +msgid "A brasier for producing copious amounts of light and heat." +msgstr "" + +#: brasier.lua:8 +msgid "" +"To ignite the brasier place a flammable fuel in its inventory slot. A lump " +"of coal will burn for about half an hour." +msgstr "" + +#: brasier.lua:107 +msgid "Floor Brasier" +msgstr "" + +#: brasier.lua:156 +msgid "Stonebrick" +msgstr "" + +#: brasier.lua:228 +msgid "@1 Brasier" +msgstr "" + +#: init.lua:17 +msgid "Light Block" +msgstr "" + +#: init.lua:37 +msgid "Chandelier" +msgstr "" + +#: init.lua:76 +msgid "Chandelier Chain" +msgstr "" diff --git a/mods/castle_lighting/mod.conf b/mods/castle_lighting/mod.conf new file mode 100644 index 0000000..82e7de7 --- /dev/null +++ b/mods/castle_lighting/mod.conf @@ -0,0 +1,4 @@ +name = castle_lighting +depends = default +optional_depends = intllib, fire, castle_masonry, hopper, doc +description = This mod contains medieval castle lighting solutions diff --git a/mods/castle_lighting/screenshot.png b/mods/castle_lighting/screenshot.png new file mode 100644 index 0000000..354f4a2 Binary files /dev/null and b/mods/castle_lighting/screenshot.png differ diff --git a/mods/castle_lighting/textures/LICENSE.txt b/mods/castle_lighting/textures/LICENSE.txt new file mode 100644 index 0000000..7d7ed99 --- /dev/null +++ b/mods/castle_lighting/textures/LICENSE.txt @@ -0,0 +1,17 @@ +License Textures: Philipner - CC-BY-SA 3.0 + +-castle_chandelier.png +-castle_chandelier_chain.png +-castle_chandelier_wield.png + + +-------------------------------------------- + +16 px textures based on Castle mod +original textures by Philipner + +License Textures: Napiophelios - CC-BY-SA 3.0 + +-castle_street_light.png + +-------------------------------------------- diff --git a/mods/castle_lighting/textures/castle_brasier_bed_mask.png b/mods/castle_lighting/textures/castle_brasier_bed_mask.png new file mode 100644 index 0000000..2c30c88 Binary files /dev/null and b/mods/castle_lighting/textures/castle_brasier_bed_mask.png differ diff --git a/mods/castle_lighting/textures/castle_chandelier.png b/mods/castle_lighting/textures/castle_chandelier.png new file mode 100644 index 0000000..fbc0039 Binary files /dev/null and b/mods/castle_lighting/textures/castle_chandelier.png differ diff --git a/mods/castle_lighting/textures/castle_chandelier_chain.png b/mods/castle_lighting/textures/castle_chandelier_chain.png new file mode 100644 index 0000000..47a526a Binary files /dev/null and b/mods/castle_lighting/textures/castle_chandelier_chain.png differ diff --git a/mods/castle_lighting/textures/castle_chandelier_wield.png b/mods/castle_lighting/textures/castle_chandelier_wield.png new file mode 100644 index 0000000..59dae96 Binary files /dev/null and b/mods/castle_lighting/textures/castle_chandelier_wield.png differ diff --git a/mods/castle_lighting/textures/castle_coal_bed.png b/mods/castle_lighting/textures/castle_coal_bed.png new file mode 100644 index 0000000..e263bcd Binary files /dev/null and b/mods/castle_lighting/textures/castle_coal_bed.png differ diff --git a/mods/castle_lighting/textures/castle_steel.png b/mods/castle_lighting/textures/castle_steel.png new file mode 100644 index 0000000..28ecd60 Binary files /dev/null and b/mods/castle_lighting/textures/castle_steel.png differ diff --git a/mods/castle_lighting/textures/castle_street_light.png b/mods/castle_lighting/textures/castle_street_light.png new file mode 100644 index 0000000..dc3f72e Binary files /dev/null and b/mods/castle_lighting/textures/castle_street_light.png differ diff --git a/mods/castle_masonry/README.md b/mods/castle_masonry/README.md new file mode 100644 index 0000000..0a6c552 --- /dev/null +++ b/mods/castle_masonry/README.md @@ -0,0 +1,38 @@ +## Castle Masonry + +by: Philipbenr, DanDuncombe, FaceDeer + +Licence: MIT + +This is a mod all about creating castles and castle dungeons. Many of the nodes are used for the outer-walls or dungeons. + +Contains: + +* Walls, Corner-walls, +* Castlestone Stairs, Slabs, and Pillars +* Arrowslits and embrasures +* Rubble (to fill the interior of thick castle walls) +* Murder holes and machicolations +* Pillars and crossbraces +* Roof slate +* Paving stone +* Dungeon stone + +Mod settings can allow for the basic castle masonry forms to be made for the following material types (all optional): + +* Cobble +* Desert stone +* Desert stone brick +* Sandstone +* Sandstone brick +* Desert Sandstone +* Desert Sandstone brick +* Silver Sandstone +* Silver Sandstone brick +* Stone +* Stone brick +* Castle wall +* Wood +* Snow +* Ice +* Obsidian Brick diff --git a/mods/castle_masonry/arrow_slits.lua b/mods/castle_masonry/arrow_slits.lua new file mode 100644 index 0000000..61d10a9 --- /dev/null +++ b/mods/castle_masonry/arrow_slits.lua @@ -0,0 +1,166 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +castle_masonry.register_arrowslit = function(material) + local composition_def, burn_time, tile, desc = castle_masonry.get_material_properties(material) + local mod_name = minetest.get_current_modname() + + -- Node Definition + minetest.register_node(mod_name..":arrowslit_"..material.name, { + drawtype = "nodebox", + description = S("@1 Arrowslit", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.375, 0.5, -0.0625, 0.375, 0.3125}, + {0.0625, -0.375, 0.5, 0.5, 0.375, 0.3125}, + {-0.5, 0.375, 0.5, 0.5, 0.5, 0.3125}, + {-0.5, -0.5, 0.5, 0.5, -0.375, 0.3125}, + {0.25, -0.5, 0.3125, 0.5, 0.5, 0.125}, + {-0.5, -0.5, 0.3125, -0.25, 0.5, 0.125}, + }, + }, + }) + + minetest.register_node(mod_name..":arrowslit_"..material.name.."_cross", { + drawtype = "nodebox", + description = S("@1 Arrowslit with Cross", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.125, 0.5, -0.0625, 0.375, 0.3125}, + {0.0625, -0.125, 0.5, 0.5, 0.375, 0.3125}, + {-0.5, 0.375, 0.5, 0.5, 0.5, 0.3125}, + {-0.5, -0.5, 0.5, 0.5, -0.375, 0.3125}, + {0.0625, -0.375, 0.5, 0.5, -0.25, 0.3125}, + {-0.5, -0.375, 0.5, -0.0625, -0.25, 0.3125}, + {-0.5, -0.25, 0.5, -0.1875, -0.125, 0.3125}, + {0.1875, -0.25, 0.5, 0.5, -0.125, 0.3125}, + {0.25, -0.5, 0.3125, 0.5, 0.5, 0.125}, + {-0.5, -0.5, 0.3125, -0.25, 0.5, 0.125}, + }, + }, + }) + + minetest.register_node(mod_name..":arrowslit_"..material.name.."_hole", { + drawtype = "nodebox", + description = S("@1 Arrowslit with Hole", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.375, 0.5, -0.125, 0.375, 0.3125}, + {0.125, -0.375, 0.5, 0.5, 0.375, 0.3125}, + {-0.5, -0.5, 0.5, 0.5, -0.375, 0.3125}, + {0.0625, -0.125, 0.5, 0.125, 0.375, 0.3125}, + {-0.125, -0.125, 0.5, -0.0625, 0.375, 0.3125}, + {-0.5, 0.375, 0.5, 0.5, 0.5, 0.3125}, + {0.25, -0.5, 0.3125, 0.5, 0.5, 0.125}, + {-0.5, -0.5, 0.3125, -0.25, 0.5, 0.125}, + }, + }, + }) + + minetest.register_node(mod_name..":arrowslit_"..material.name.."_embrasure", { + drawtype = "nodebox", + description = S("@1 Embrasure", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, 0.375, -0.125, 0.5, 0.5}, + {0.125, -0.5, 0.375, 0.25, 0.5, 0.5}, + {0.25, -0.5, 0.25, 0.5, 0.5, 0.5}, + {0.375, -0.5, 0.125, 0.5, 0.5, 0.25}, + {-0.5, -0.5, 0.25, -0.25, 0.5, 0.5}, + {-0.5, -0.5, 0.125, -0.375, 0.5, 0.25}, + }, + }, + }) + + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name.." 6", + recipe = { + {material.craft_material,"", material.craft_material}, + {material.craft_material,"", material.craft_material}, + {material.craft_material,"", material.craft_material} }, + }) + + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name.."_cross", + recipe = { + {mod_name..":arrowslit_"..material.name} }, + }) + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name.."_hole", + recipe = { + {mod_name..":arrowslit_"..material.name.."_cross"} }, + }) + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name.."_embrasure", + recipe = { + {mod_name..":arrowslit_"..material.name.."_hole"} }, + }) + minetest.register_craft({ + output = mod_name..":arrowslit_"..material.name, + recipe = { + {mod_name..":arrowslit_"..material.name.."_embrasure"} }, + }) + + if burn_time > 0 then + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":arrowslit_"..material.name, + burntime = burn_time, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":arrowslit_"..material.name.."_cross", + burntime = burn_time, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":arrowslit_"..material.name.."_hole", + burntime = burn_time, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":arrowslit_"..material.name.."_embrasure", + burntime = burn_time, + }) + end +end + + +castle_masonry.register_arrowslit_alias = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias(old_mod_name..":arrowslit_"..old_material_name, new_mod_name..":arrowslit_"..new_material_name) + minetest.register_alias(old_mod_name..":arrowslit_"..old_material_name.."_cross", new_mod_name..":arrowslit_"..new_material_name.."_cross") + minetest.register_alias(old_mod_name..":arrowslit_"..old_material_name.."_hole", new_mod_name..":arrowslit_"..new_material_name.."_hole") + minetest.register_alias(old_mod_name..":arrowslit_"..old_material_name.."_embrasure", new_mod_name..":arrowslit_"..new_material_name.."_embrasure") +end + +castle_masonry.register_arrowslit_alias_force = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias_force(old_mod_name..":arrowslit_"..old_material_name, new_mod_name..":arrowslit_"..new_material_name) + minetest.register_alias_force(old_mod_name..":arrowslit_"..old_material_name.."_cross", new_mod_name..":arrowslit_"..new_material_name.."_cross") + minetest.register_alias_force(old_mod_name..":arrowslit_"..old_material_name.."_hole", new_mod_name..":arrowslit_"..new_material_name.."_hole") + minetest.register_alias_force(old_mod_name..":arrowslit_"..old_material_name.."_embrasure", new_mod_name..":arrowslit_"..new_material_name.."_embrasure") +end diff --git a/mods/castle_masonry/init.lua b/mods/castle_masonry/init.lua new file mode 100644 index 0000000..c0674ae --- /dev/null +++ b/mods/castle_masonry/init.lua @@ -0,0 +1,149 @@ +castle_masonry = {} + +local MP = minetest.get_modpath(minetest.get_current_modname()) +dofile(MP.."/pillars.lua") +dofile(MP.."/arrow_slits.lua") +dofile(MP.."/murder_holes.lua") +dofile(MP.."/stone_wall.lua") +dofile(MP.."/paving.lua") + +local S, NS = dofile(MP.."/intllib.lua") + +local read_setting = function(name, default) + local setting = minetest.settings:get_bool(name) + if setting == nil then return default end + return setting +end + +-- Material definition: +-- { +-- name=, -- the name that will be part of the resulting node names +-- desc=, -- Player-facing name of the material +-- tile=, -- Optional - the texture tile to use for the resulting blocks (can be a single texture or a table, as a normal node definition's tile def). If not set this will be taken from the material it's made out of. +-- craft_material=, -- What source block is used to craft these blocks. +-- composition_material=, -- Optional, this will override the properties of the product with a specific material. Useful if you want to use a group for the craft material (eg, "group:wood") +--} + +castle_masonry.materials = {} +if read_setting("castle_masonry_stonewall", true) then + table.insert(castle_masonry.materials, {name="stonewall", desc=S("Stonewall"), tile="castle_stonewall.png", craft_material="castle_masonry:stonewall"}) +end +if read_setting("castle_masonry_cobble", true) then + table.insert(castle_masonry.materials, {name="cobble", desc=S("Cobble"), tile="default_cobble.png", craft_material="default:cobble"}) +end +if read_setting("castle_masonry_stonebrick", true) then + table.insert(castle_masonry.materials, {name="stonebrick", desc=S("Stonebrick"), tile="default_stone_brick.png", craft_material="default:stonebrick"}) +end +if read_setting("castle_masonry_sandstonebrick", true) then + table.insert(castle_masonry.materials, {name="sandstonebrick", desc=S("Sandstone Brick"), tile="default_sandstone_brick.png", craft_material="default:sandstonebrick"}) +end +if read_setting("castle_masonry_desertstonebrick", true) then + table.insert(castle_masonry.materials, {name="desertstonebrick", desc=S("Desert Stone Brick"), tile="default_desert_stone_brick.png", craft_material="default:desert_stonebrick"}) +end +if read_setting("castle_masonry_desertsandstonebrick", true) then + table.insert(castle_masonry.materials, {name="desertsandstonebrick", desc=S("Desert Sandstone Brick"), tile="default_desert_sandstone_brick.png", craft_material="default:desert_sandstone_brick"}) +end +if read_setting("castle_masonry_silversandstonebrick", true) then + table.insert(castle_masonry.materials, {name="silversandstonebrick", desc=S("Silver Sandstone Brick"), tile="default_silver_sandstone_brick.png", craft_material="default:silver_sandstone_brick"}) +end +if read_setting("castle_masonry_stone", true) then + table.insert(castle_masonry.materials, {name="stone", desc=S("Stone"), tile="default_stone.png", craft_material="default:stone"}) +end +if read_setting("castle_masonry_sandstone", true) then + table.insert(castle_masonry.materials, {name="sandstone", desc=S("Sandstone"), tile="default_sandstone.png", craft_material="default:sandstone"}) +end +if read_setting("castle_masonry_desertstone", true) then + table.insert(castle_masonry.materials, {name="desertstone", desc=S("Desert Stone"), tile="default_desert_stone.png", craft_material="default:desert_stone"}) +end +if read_setting("castle_masonry_desertsandstone", true) then + table.insert(castle_masonry.materials, {name="desertsandstone", desc=S("Desert Sandstone"), tile="default_desert_sandstone.png", craft_material="default:desert_sandstone"}) +end +if read_setting("castle_masonry_silversandstone", true) then + table.insert(castle_masonry.materials, {name="silversandstone", desc=S("Silver Sandstone"), tile="default_silver_sandstone.png", craft_material="default:silver_sandstone"}) +end +if read_setting("castle_masonry_wood", false) then + table.insert(castle_masonry.materials, {name="wood", desc=S("Wood"), tile="default_wood.png", craft_material="group:wood", composition_material="default:wood"}) +end +if read_setting("castle_masonry_ice", false) then + table.insert(castle_masonry.materials, {name="ice", desc=S("Ice"), tile="default_ice.png", craft_material="default:ice"}) +end +if read_setting("castle_masonry_snow", false) then + table.insert(castle_masonry.materials, {name="snow", desc=S("Snow"), tile="default_snow.png", craft_material="default:snow"}) +end +if read_setting("castle_masonry_obsidianbrick", false) then + table.insert(castle_masonry.materials, {name="obsidianbrick", desc=S("Obsidian Brick"), tile="default_obsidian_brick.png", craft_material="default:obsidianbrick"}) +end + +castle_masonry.get_material_properties = function(material) + local composition_def + local burn_time + if material.composition_material ~= nil then + composition_def = minetest.registered_nodes[material.composition_material] + burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.composition_material)}}).time + else + composition_def = minetest.registered_nodes[material.craft_material] + burn_time = minetest.get_craft_result({method="fuel", width=1, items={ItemStack(material.craft_materia)}}).time + end + + local tiles = material.tile + if tiles == nil then + tiles = composition_def.tile + elseif type(tiles) == "string" then + tiles = {tiles} + end + + local desc = material.desc + if desc == nil then + desc = composition_def.description + end + + return composition_def, burn_time, tiles, desc +end + + +if read_setting("castle_masonry_pillar", true) then + for _, material in pairs(castle_masonry.materials) do + castle_masonry.register_pillar(material) + end +end + +if read_setting("castle_masonry_arrowslit", true) then + for _, material in pairs(castle_masonry.materials) do + castle_masonry.register_arrowslit(material) + end +end + +if read_setting("castle_masonry_murderhole", true) then + for _, material in pairs(castle_masonry.materials) do + castle_masonry.register_murderhole(material) + end +end + +minetest.register_alias("castle:pillars_bottom", "castle_masonry:pillars_stonewall_bottom") +minetest.register_alias("castle:pillars_top", "castle_masonry:pillars_stonewall_top") +minetest.register_alias("castle:pillars_middle", "castle_masonry:pillars_stonewall_middle") +minetest.register_alias("castle:arrowslit", "castle_masonry:arrowslit_stonewall") +minetest.register_alias("castle:arrowslit_hole", "castle_masonry:arrowslit_stonewall_hole") +minetest.register_alias("castle:arrowslit_cross", "castle_masonry:arrowslit_stonewall_cross") + +for _, material in pairs(castle_masonry.materials) do + castle_masonry.register_murderhole_alias("castle", material.name, "castle_masonry", material.name) + castle_masonry.register_pillar_alias("castle", material.name, "castle_masonry", material.name) + + -- Arrowslit upgrade has special handling because the castle mod arrow slit is reversed relative to current build-from-inside standard + local lbm_def = { + name = "castle_masonry:arrowslit_flip_front_to_back"..material.name, + nodenames = { + "castle:arrowslit_"..material.name, + "castle:arrowslit_"..material.name.."_cross", + "castle:arrowslit_"..material.name.."_hole", + }, + action = function(pos, node) + local flip_front_to_back = {[0]=2, 3, 0, 1, 6, 7, 4, 5, 10, 7, 8, 9, 14, 15, 12, 13, 18, 19, 16, 17, 22, 23, 20, 21} + node.param2 = flip_front_to_back[node.param2] + node.name = "castle_masonry" .. string.sub(node.name, 7, -1) + minetest.swap_node(pos, node) + end + } + minetest.register_lbm(lbm_def) +end diff --git a/mods/castle_masonry/intllib.lua b/mods/castle_masonry/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/castle_masonry/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/castle_masonry/license.txt b/mods/castle_masonry/license.txt new file mode 100644 index 0000000..5c3c583 --- /dev/null +++ b/mods/castle_masonry/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Minetest Mods Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/castle_masonry/locale/es.po b/mods/castle_masonry/locale/es.po new file mode 100644 index 0000000..6c1ebc1 --- /dev/null +++ b/mods/castle_masonry/locale/es.po @@ -0,0 +1,189 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 23:41-0700\n" +"PO-Revision-Date: 2017-04-28 15:23-0400\n" +"Last-Translator: Carlos Barraza\n" +"Language-Team: Español\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: arrow_slits.lua:12 +msgid "@1 Arrowslit" +msgstr "Aspillera de @1" + +#: arrow_slits.lua:33 +msgid "@1 Arrowslit with Cross" +msgstr "Aspillera con Crus de @1" + +#: arrow_slits.lua:58 +msgid "@1 Arrowslit with Hole" +msgstr "Aspillera con Agujero de @1" + +#: arrow_slits.lua:81 +msgid "@1 Embrasure" +msgstr "Aféizar de @1 " + +#: init.lua:29 +msgid "Stonewall" +msgstr "Pared de piedra" + +#: init.lua:32 +msgid "Cobble" +msgstr "Adoquín" + +#: init.lua:35 +msgid "Stonebrick" +msgstr "Ladrillo de Piedra" + +#: init.lua:38 +msgid "Sandstone Brick" +msgstr "Ladrillo de Arenisca" + +#: init.lua:41 +msgid "Desert Stone Brick" +msgstr "Ladrillo de Piedra del Desierto" + +#: init.lua:44 +msgid "Stone" +msgstr "Piedra" + +#: init.lua:47 +msgid "Sandstone" +msgstr "Arenisca" + +#: init.lua:50 +msgid "Desert Stone" +msgstr "Piedra del Desierto" + +#: init.lua:53 +msgid "Wood" +msgstr "Madera" + +#: init.lua:56 +msgid "Ice" +msgstr "Hielo" + +#: init.lua:59 +msgid "Snow" +msgstr "Nieve" + +#: init.lua:62 +msgid "Obsidian Brick" +msgstr "Ladrillo de Obsidiana" + +#: murder_holes.lua:14 +msgid "@1 Murder Hole" +msgstr "Agujero de @1" + +#: murder_holes.lua:33 +msgid "@1 Machicolation" +msgstr "Matacán de @1" + +#: paving.lua:11 +msgid "Paving Stone" +msgstr "Piedra Pavimentada" + +#: paving.lua:30 +msgid "Pavement Brick" +msgstr "Ladrillo Pavimentado" + +#: paving.lua:40 +msgid "Castle Pavement Stair" +msgstr "Escalera de Castillo Pavimentada" + +#: paving.lua:41 +msgid "Castle Pavement Slab" +msgstr "Pavimento de Castillo" + +#: paving.lua:49 +msgid "Roof Slates" +msgstr "Pizarras de Techo" + +#: pillars.lua:18 +msgid "@1 Pillar Base" +msgstr "Base de Pilar de @1" + +#: pillars.lua:36 +msgid "@1 Half Pillar Base" +msgstr "Base de Medio Pilar de @1" + +#: pillars.lua:54 +msgid "@1 Pillar Top" +msgstr "Parte Superior de Pilar de @1" + +#: pillars.lua:72 +msgid "@1 Half Pillar Top" +msgstr "Parte Superior de Medio Pilar @1" + +#: pillars.lua:90 +msgid "@1 Pillar Middle" +msgstr "Medio Pilar de @1" + +#: pillars.lua:106 +msgid "@1 Half Pillar Middle" +msgstr "Medio del Medio Pilar de @1" + +#: pillars.lua:123 +msgid "@1 Crossbrace" +msgstr "Viga de @1" + +#: pillars.lua:147 +msgid "@1 Extended Crossbrace" +msgstr "Viga Extendida de @1" + +#: stone_wall.lua:11 +msgid "Castle Wall" +msgstr "Pared de Castillo" + +#: stone_wall.lua:22 +msgid "Castle Rubble" +msgstr "Escombros de Castillo" + +#: stone_wall.lua:57 +msgid "Castle Corner" +msgstr "Esquina de Castillo" + +#: stone_wall.lua:78 +msgid "Stone Wall" +msgstr "Pared de Piedra" + +#: stone_wall.lua:86 +msgid "Rubble" +msgstr "Escombros" + +#: stone_wall.lua:100 +msgid "Castle Stonewall Stair" +msgstr "Escalera de Pared de Castillo" + +#: stone_wall.lua:101 +msgid "Castle Stonewall Slab" +msgstr "Losa de Pared de Castillo" + +#: stone_wall.lua:108 +msgid "Castle Rubble Stair" +msgstr "Escalera de Escombro de Castillo" + +#: stone_wall.lua:109 +msgid "Castle Rubble Slab" +msgstr "Losa de Escombro de Castillo" + +#: stone_wall.lua:117 stone_wall.lua:143 +msgid "Dungeon Stone" +msgstr "Piedra de Mazmorra" + +#: stone_wall.lua:156 +msgid "Dungeon Stone Stair" +msgstr "Escalera de Piedra de Mazmorra" + +#: stone_wall.lua:157 +msgid "Dungeon Stone Slab" +msgstr "Losa de Piedra de Mazmorra" diff --git a/mods/castle_masonry/locale/fr.po b/mods/castle_masonry/locale/fr.po new file mode 100644 index 0000000..5a73d18 --- /dev/null +++ b/mods/castle_masonry/locale/fr.po @@ -0,0 +1,189 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 23:41-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: arrow_slits.lua:12 +msgid "@1 Arrowslit" +msgstr "Meurtrière en @1" + +#: arrow_slits.lua:33 +msgid "@1 Arrowslit with Cross" +msgstr "Meurtrière en croix en @1" + +#: arrow_slits.lua:58 +msgid "@1 Arrowslit with Hole" +msgstr "Meurtrière avec trou en @1" + +#: arrow_slits.lua:81 +msgid "@1 Embrasure" +msgstr "Embrasure en @1" + +#: init.lua:29 +msgid "Stonewall" +msgstr "Pierre brune" + +#: init.lua:32 +msgid "Cobble" +msgstr "Pavé" + +#: init.lua:35 +msgid "Stonebrick" +msgstr "Brique de pierre" + +#: init.lua:38 +msgid "Sandstone Brick" +msgstr "Brique de grès" + +#: init.lua:41 +msgid "Desert Stone Brick" +msgstr "Brique de pierre du désert" + +#: init.lua:44 +msgid "Stone" +msgstr "Pierre" + +#: init.lua:47 +msgid "Sandstone" +msgstr "Grès" + +#: init.lua:50 +msgid "Desert Stone" +msgstr "Pierre du désert" + +#: init.lua:53 +msgid "Wood" +msgstr "Bois" + +#: init.lua:56 +msgid "Ice" +msgstr "Glace" + +#: init.lua:59 +msgid "Snow" +msgstr "Neige" + +#: init.lua:62 +msgid "Obsidian Brick" +msgstr "Brique d'obsidienne" + +#: murder_holes.lua:14 +msgid "@1 Murder Hole" +msgstr "Trou en @1" + +#: murder_holes.lua:33 +msgid "@1 Machicolation" +msgstr "Machicoulis en @1" + +#: paving.lua:11 +msgid "Paving Stone" +msgstr "Pierre de pavage" + +#: paving.lua:30 +msgid "Pavement Brick" +msgstr "Brique de pavage" + +#: paving.lua:40 +msgid "Castle Pavement Stair" +msgstr "Escaliers de chateau pavé" + +#: paving.lua:41 +msgid "Castle Pavement Slab" +msgstr "Dalle de chateau pavé" + +#: paving.lua:49 +msgid "Roof Slates" +msgstr "Toiture en ardoise" + +#: pillars.lua:18 +msgid "@1 Pillar Base" +msgstr "Base de pilier en @1" + +#: pillars.lua:36 +msgid "@1 Half Pillar Base" +msgstr "Base de demi pilier en @1" + +#: pillars.lua:54 +msgid "@1 Pillar Top" +msgstr "Haut de pilier en @1" + +#: pillars.lua:72 +msgid "@1 Half Pillar Top" +msgstr "Haut de demi pilier en @1" + +#: pillars.lua:90 +msgid "@1 Pillar Middle" +msgstr "Milieu de pilier en @1" + +#: pillars.lua:106 +msgid "@1 Half Pillar Middle" +msgstr "Milieu de demi pilier en @1" + +#: pillars.lua:123 +msgid "@1 Crossbrace" +msgstr "Travers en @1" + +#: pillars.lua:147 +msgid "@1 Extended Crossbrace" +msgstr "Travers entendu en @1" + +#: stone_wall.lua:11 +msgid "Castle Wall" +msgstr "Pierre brune" + +#: stone_wall.lua:22 +msgid "Castle Rubble" +msgstr "Gravats de chateau" + +#: stone_wall.lua:57 +msgid "Castle Corner" +msgstr "Angle de chateau" + +#: stone_wall.lua:78 +msgid "Stone Wall" +msgstr "Mur de pierre" + +#: stone_wall.lua:86 +msgid "Rubble" +msgstr "Décombre" + +#: stone_wall.lua:100 +msgid "Castle Stonewall Stair" +msgstr "Escalier en pierre brune" + +#: stone_wall.lua:101 +msgid "Castle Stonewall Slab" +msgstr "Dalle en pierre brune" + +#: stone_wall.lua:108 +msgid "Castle Rubble Stair" +msgstr "Escalier en gravats de chateau" + +#: stone_wall.lua:109 +msgid "Castle Rubble Slab" +msgstr "Dalle en gravats de chateau" + +#: stone_wall.lua:117 stone_wall.lua:143 +msgid "Dungeon Stone" +msgstr "Pierre de dongeon" + +#: stone_wall.lua:156 +msgid "Dungeon Stone Stair" +msgstr "Escalier en pierre de dongeon" + +#: stone_wall.lua:157 +msgid "Dungeon Stone Slab" +msgstr "Dalle en pierre de dongeon" diff --git a/mods/castle_masonry/locale/it.po b/mods/castle_masonry/locale/it.po new file mode 100644 index 0000000..3b71932 --- /dev/null +++ b/mods/castle_masonry/locale/it.po @@ -0,0 +1,191 @@ +# ITALIAN LOCALE FILE FOR THE CASTLE MASONRY MODULE +# Copyright (C) 2017 Philipbenr And DanDuncombe +# This file is distributed under the same license as the CASTLE MASONRY package. +# Hamlet , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: Castle Masonry\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 23:41-0700\n" +"PO-Revision-Date: 2017-09-10 22:36+0100\n" +"Last-Translator: H4mlet \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language: it\n" +"X-Generator: Poedit 1.6.10\n" + +#: arrow_slits.lua:12 +msgid "@1 Arrowslit" +msgstr "Feritoia per frecce di @1" + +#: arrow_slits.lua:33 +msgid "@1 Arrowslit with Cross" +msgstr "Feritoia a croce per frecce di @1" + +#: arrow_slits.lua:58 +msgid "@1 Arrowslit with Hole" +msgstr "Feritoia a foro per frecce di @1" + +#: arrow_slits.lua:81 +msgid "@1 Embrasure" +msgstr "Feritoia di @1" + +#: init.lua:29 +msgid "Stonewall" +msgstr "muro di pietra" + +#: init.lua:32 +msgid "Cobble" +msgstr "ciottoli" + +#: init.lua:35 +msgid "Stonebrick" +msgstr "mattoni di pietra" + +#: init.lua:38 +msgid "Sandstone Brick" +msgstr "mattoni di arenaria del deserto" + +#: init.lua:41 +msgid "Desert Stone Brick" +msgstr "mattoni di pietra del deserto" + +#: init.lua:44 +msgid "Stone" +msgstr "pietra" + +#: init.lua:47 +msgid "Sandstone" +msgstr "arenaria" + +#: init.lua:50 +msgid "Desert Stone" +msgstr "pietra del deserto" + +#: init.lua:53 +msgid "Wood" +msgstr "legno" + +#: init.lua:56 +msgid "Ice" +msgstr "ghiaccio" + +#: init.lua:59 +msgid "Snow" +msgstr "neve" + +#: init.lua:62 +msgid "Obsidian Brick" +msgstr "mattoni di ossidiana" + +#: murder_holes.lua:14 +msgid "@1 Murder Hole" +msgstr "Buca assassina di @1" + +#: murder_holes.lua:33 +msgid "@1 Machicolation" +msgstr "Caditoia di @1" + +#: paving.lua:11 +msgid "Paving Stone" +msgstr "Pietra pavimentale" + +#: paving.lua:30 +msgid "Pavement Brick" +msgstr "Mattoni pavimentali" + +#: paving.lua:40 +msgid "Castle Pavement Stair" +msgstr "Scala pavimentale del castello" + +#: paving.lua:41 +msgid "Castle Pavement Slab" +msgstr "Lastra pavimentale del castello" + +#: paving.lua:49 +msgid "Roof Slates" +msgstr "Tegole di ardesia" + +#: pillars.lua:18 +msgid "@1 Pillar Base" +msgstr "Base della colonna di @1" + +#: pillars.lua:36 +msgid "@1 Half Pillar Base" +msgstr "Mezza base della colonna di @1" + +#: pillars.lua:54 +msgid "@1 Pillar Top" +msgstr "Capitello di @1" + +#: pillars.lua:72 +msgid "@1 Half Pillar Top" +msgstr "Mezzo capitello di @1" + +#: pillars.lua:90 +msgid "@1 Pillar Middle" +msgstr "Fusto della colonna di @1" + +#: pillars.lua:106 +msgid "@1 Half Pillar Middle" +msgstr "Mezzo fusto della colonna di @1" + +#: pillars.lua:123 +msgid "@1 Crossbrace" +msgstr "Costolone di @1" + +#: pillars.lua:147 +msgid "@1 Extended Crossbrace" +msgstr "Costolone esteso di @1" + +#: stone_wall.lua:11 +msgid "Castle Wall" +msgstr "Muro del castello" + +#: stone_wall.lua:22 +msgid "Castle Rubble" +msgstr "Detriti del castello" + +#: stone_wall.lua:57 +msgid "Castle Corner" +msgstr "Angolo del castello" + +#: stone_wall.lua:78 +msgid "Stone Wall" +msgstr "Muro di pietra" + +#: stone_wall.lua:86 +msgid "Rubble" +msgstr "Detriti" + +#: stone_wall.lua:100 +msgid "Castle Stonewall Stair" +msgstr "Scala del castello in muro di pietra" + +#: stone_wall.lua:101 +msgid "Castle Stonewall Slab" +msgstr "Lastra del castello in muro di pietra" + +#: stone_wall.lua:108 +msgid "Castle Rubble Stair" +msgstr "Scala del castello in detriti" + +#: stone_wall.lua:109 +msgid "Castle Rubble Slab" +msgstr "Lastra del castello in detriti" + +#: stone_wall.lua:117 stone_wall.lua:143 +msgid "Dungeon Stone" +msgstr "Pietra del sotterraneo" + +#: stone_wall.lua:156 +msgid "Dungeon Stone Stair" +msgstr "Scala di pietra del sotterraneo" + +#: stone_wall.lua:157 +msgid "Dungeon Stone Slab" +msgstr "Lastra di pietra del sotterraneo" diff --git a/mods/castle_masonry/locale/template.pot b/mods/castle_masonry/locale/template.pot new file mode 100644 index 0000000..93b2f4c --- /dev/null +++ b/mods/castle_masonry/locale/template.pot @@ -0,0 +1,189 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-21 23:41-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: arrow_slits.lua:12 +msgid "@1 Arrowslit" +msgstr "" + +#: arrow_slits.lua:33 +msgid "@1 Arrowslit with Cross" +msgstr "" + +#: arrow_slits.lua:58 +msgid "@1 Arrowslit with Hole" +msgstr "" + +#: arrow_slits.lua:81 +msgid "@1 Embrasure" +msgstr "" + +#: init.lua:29 +msgid "Stonewall" +msgstr "" + +#: init.lua:32 +msgid "Cobble" +msgstr "" + +#: init.lua:35 +msgid "Stonebrick" +msgstr "" + +#: init.lua:38 +msgid "Sandstone Brick" +msgstr "" + +#: init.lua:41 +msgid "Desert Stone Brick" +msgstr "" + +#: init.lua:44 +msgid "Stone" +msgstr "" + +#: init.lua:47 +msgid "Sandstone" +msgstr "" + +#: init.lua:50 +msgid "Desert Stone" +msgstr "" + +#: init.lua:53 +msgid "Wood" +msgstr "" + +#: init.lua:56 +msgid "Ice" +msgstr "" + +#: init.lua:59 +msgid "Snow" +msgstr "" + +#: init.lua:62 +msgid "Obsidian Brick" +msgstr "" + +#: murder_holes.lua:14 +msgid "@1 Murder Hole" +msgstr "" + +#: murder_holes.lua:33 +msgid "@1 Machicolation" +msgstr "" + +#: paving.lua:11 +msgid "Paving Stone" +msgstr "" + +#: paving.lua:30 +msgid "Pavement Brick" +msgstr "" + +#: paving.lua:40 +msgid "Castle Pavement Stair" +msgstr "" + +#: paving.lua:41 +msgid "Castle Pavement Slab" +msgstr "" + +#: paving.lua:49 +msgid "Roof Slates" +msgstr "" + +#: pillars.lua:18 +msgid "@1 Pillar Base" +msgstr "" + +#: pillars.lua:36 +msgid "@1 Half Pillar Base" +msgstr "" + +#: pillars.lua:54 +msgid "@1 Pillar Top" +msgstr "" + +#: pillars.lua:72 +msgid "@1 Half Pillar Top" +msgstr "" + +#: pillars.lua:90 +msgid "@1 Pillar Middle" +msgstr "" + +#: pillars.lua:106 +msgid "@1 Half Pillar Middle" +msgstr "" + +#: pillars.lua:123 +msgid "@1 Crossbrace" +msgstr "" + +#: pillars.lua:147 +msgid "@1 Extended Crossbrace" +msgstr "" + +#: stone_wall.lua:11 +msgid "Castle Wall" +msgstr "" + +#: stone_wall.lua:22 +msgid "Castle Rubble" +msgstr "" + +#: stone_wall.lua:57 +msgid "Castle Corner" +msgstr "" + +#: stone_wall.lua:78 +msgid "Stone Wall" +msgstr "" + +#: stone_wall.lua:86 +msgid "Rubble" +msgstr "" + +#: stone_wall.lua:100 +msgid "Castle Stonewall Stair" +msgstr "" + +#: stone_wall.lua:101 +msgid "Castle Stonewall Slab" +msgstr "" + +#: stone_wall.lua:108 +msgid "Castle Rubble Stair" +msgstr "" + +#: stone_wall.lua:109 +msgid "Castle Rubble Slab" +msgstr "" + +#: stone_wall.lua:117 stone_wall.lua:143 +msgid "Dungeon Stone" +msgstr "" + +#: stone_wall.lua:156 +msgid "Dungeon Stone Stair" +msgstr "" + +#: stone_wall.lua:157 +msgid "Dungeon Stone Slab" +msgstr "" diff --git a/mods/castle_masonry/mod.conf b/mods/castle_masonry/mod.conf new file mode 100644 index 0000000..0ef13bc --- /dev/null +++ b/mods/castle_masonry/mod.conf @@ -0,0 +1,4 @@ +name = castle_masonry +depends = default +optional_depends = moreblocks, stairs, building_blocks, asphalt, streets, intllib +description = This is a mod all about creating castles and castle dungeons. Many of the nodes are used for the outer-walls or dungeons. diff --git a/mods/castle_masonry/murder_holes.lua b/mods/castle_masonry/murder_holes.lua new file mode 100644 index 0000000..090c399 --- /dev/null +++ b/mods/castle_masonry/murder_holes.lua @@ -0,0 +1,91 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +------------------------------------------------------------------------------------- + +castle_masonry.register_murderhole = function(material) + local composition_def, burn_time, tile, desc = castle_masonry.get_material_properties(material) + local mod_name = minetest.get_current_modname() + + -- Node Definition + minetest.register_node(mod_name..":hole_"..material.name, { + drawtype = "nodebox", + description = S("@1 Murder Hole", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-8/16,-8/16,-8/16,-4/16,8/16,8/16}, + {4/16,-8/16,-8/16,8/16,8/16,8/16}, + {-4/16,-8/16,-8/16,4/16,8/16,-4/16}, + {-4/16,-8/16,8/16,4/16,8/16,4/16}, + }, + }, + }) + + minetest.register_node(mod_name..":machicolation_"..material.name, { + drawtype = "nodebox", + description = S("@1 Machicolation", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0, -0.5, 0.5, 0.5, 0}, + {-0.5, -0.5, 0, -0.25, 0.5, 0.5}, + {0.25, -0.5, 0, 0.5, 0.5, 0.5}, + }, + }, + }) + + minetest.register_craft({ + output = mod_name..":hole_"..material.name.." 4", + recipe = { + {"",material.craft_material, "" }, + {material.craft_material,"", material.craft_material}, + {"",material.craft_material, ""} + }, + }) + + minetest.register_craft({ + output = mod_name..":machicolation_"..material.name, + type="shapeless", + recipe = {mod_name..":hole_"..material.name}, + }) + minetest.register_craft({ + output = mod_name..":hole_"..material.name, + type="shapeless", + recipe = {mod_name..":machicolation_"..material.name}, + }) + + if burn_time > 0 then + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":hole_"..material.name, + burntime = burn_time, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":machicolation_"..material.name, + burntime = burn_time, + }) + end +end + +castle_masonry.register_murderhole_alias = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias(old_mod_name..":hole_"..old_material_name, new_mod_name..":hole_"..new_material_name) + minetest.register_alias(old_mod_name..":machicolation_"..old_material_name, new_mod_name..":machicolation_"..new_material_name) +end + +castle_masonry.register_murderhole_alias_force = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias_force(old_mod_name..":hole_"..old_material_name, new_mod_name..":hole_"..new_material_name) + minetest.register_alias_force(old_mod_name..":machicolation_"..old_material_name, new_mod_name..":machicolation_"..new_material_name) +end \ No newline at end of file diff --git a/mods/castle_masonry/paving.lua b/mods/castle_masonry/paving.lua new file mode 100644 index 0000000..a6c5c42 --- /dev/null +++ b/mods/castle_masonry/paving.lua @@ -0,0 +1,109 @@ +minetest.register_alias("castle:pavement", "castle_masonry:pavement_brick") +minetest.register_alias("castle:pavement_brick", "castle_masonry:pavement_brick") +minetest.register_alias("castle:roofslate", "castle_masonry:roofslate") + + +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_node("castle_masonry:pavement_brick", { + description = S("Paving Stone"), + drawtype = "normal", + tiles = {"castle_pavement_brick.png"}, + groups = {cracky=2}, + paramtype = "light", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "castle_masonry:pavement_brick 4", + recipe = { + {"default:stone", "default:cobble"}, + {"default:cobble", "default:stone"}, + } +}) + + +if minetest.get_modpath("moreblocks") then + stairsplus:register_all("castle", "pavement_brick", "castle_masonry:pavement_brick", { + description = S("Pavement Brick"), + tiles = {"castle_pavement_brick.png"}, + groups = {cracky=2, not_in_creative_inventory=1}, + sounds = default.node_sound_stone_defaults(), + sunlight_propagates = true, + }) +elseif minetest.get_modpath("stairs") then + stairs.register_stair_and_slab("pavement_brick", "castle_masonry:pavement_brick", + {cracky=2}, + {"castle_pavement_brick.png"}, + S("Castle Pavement Stair"), + S("Castle Pavement Slab"), + default.node_sound_stone_defaults() + ) +end + + +minetest.register_node("castle_masonry:roofslate", { + drawtype = "raillike", + description = S("Roof Slates"), + inventory_image = "castle_slate.png", + paramtype = "light", + walkable = false, + tiles = {'castle_slate.png'}, + climbable = true, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + groups = {cracky=3,attached_node=1}, + sounds = default.node_sound_glass_defaults(), +}) + +local mod_building_blocks = minetest.get_modpath("building_blocks") +local mod_streets = minetest.get_modpath("streets") or minetest.get_modpath("asphalt") + +if mod_building_blocks then + minetest.register_craft({ + output = "castle_masonry:roofslate 4", + recipe = { + { "building_blocks:Tar" , "default:gravel" }, + { "default:gravel", "building_blocks:Tar" } + } + }) + + minetest.register_craft( { + output = "castle_masonry:roofslate 4", + recipe = { + { "default:gravel", "building_blocks:Tar" }, + { "building_blocks:Tar" , "default:gravel" } + } + }) +end + +if mod_streets then + minetest.register_craft( { + output = "castle_masonry:roofslate 4", + recipe = { + { "streets:asphalt" , "default:gravel" }, + { "default:gravel", "streets:asphalt" } + } + }) + + minetest.register_craft( { + output = "castle_masonry:roofslate 4", + recipe = { + { "default:gravel", "streets:asphalt" }, + { "streets:asphalt" , "default:gravel" } + } + }) +end + +if not (mod_building_blocks or mod_streets) then + minetest.register_craft({ + type = "cooking", + output = "castle_masonry:roofslate", + recipe = "default:gravel", + }) + +end \ No newline at end of file diff --git a/mods/castle_masonry/pillars.lua b/mods/castle_masonry/pillars.lua new file mode 100644 index 0000000..082f82e --- /dev/null +++ b/mods/castle_masonry/pillars.lua @@ -0,0 +1,314 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +castle_masonry.register_pillar = function(material) + local composition_def, burn_time, tile, desc = castle_masonry.get_material_properties(material) + local crossbrace_connectable_groups = {} + for group, val in pairs(composition_def.groups) do + crossbrace_connectable_groups[group] = val + end + crossbrace_connectable_groups.crossbrace_connectable = 1 + + local mod_name = minetest.get_current_modname() + + -- Node Definition + minetest.register_node(mod_name..":pillar_"..material.name.."_bottom", { + drawtype = "nodebox", + description = S("@1 Pillar Base", desc), + tiles = tile, + groups = crossbrace_connectable_groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5,-0.5,-0.5,0.5,-0.375,0.5}, + {-0.375,-0.375,-0.375,0.375,-0.125,0.375}, + {-0.25,-0.125,-0.25,0.25,0.5,0.25}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_bottom_half", { + drawtype = "nodebox", + description = S("@1 Half Pillar Base", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, 0, 0.5, -0.375, 0.5}, + {-0.375, -0.375, 0.125, 0.375, -0.125, 0.5}, + {-0.25, -0.125, 0.25, 0.25, 0.5, 0.5}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_top", { + drawtype = "nodebox", + description = S("@1 Pillar Top", desc), + tiles = tile, + groups = crossbrace_connectable_groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5,0.3125,-0.5,0.5,0.5,0.5}, + {-0.375,0.0625,-0.375,0.375,0.3125,0.375}, + {-0.25,-0.5,-0.25,0.25,0.0625,0.25}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_top_half", { + drawtype = "nodebox", + description = S("@1 Half Pillar Top", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.3125, 0, 0.5, 0.5, 0.5}, + {-0.375, 0.0625, 0.125, 0.375, 0.3125, 0.5}, + {-0.25, -0.5, 0.25, 0.25, 0.0625, 0.5}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_middle", { + drawtype = "nodebox", + description = S("@1 Pillar Middle", desc), + tiles = tile, + groups = crossbrace_connectable_groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.25,-0.5,-0.25,0.25,0.5,0.25}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_middle_half", { + drawtype = "nodebox", + description = S("@1 Half Pillar Middle", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, 0.25, 0.25, 0.5, 0.5}, + }, + }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_crossbrace", + { + drawtype = "nodebox", + description = S("@1 Crossbrace", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "connected", + fixed = {-0.25,0.25,-0.25,0.25,0.5,0.25}, + connect_front = {-0.25,0.25,-0.75,0.25,0.5,-0.25}, -- -Z + connect_left = {-0.25,0.25,-0.25,-0.75,0.5,0.25}, -- -X + connect_back = {-0.25,0.25,0.25,0.25,0.5,0.75}, -- +Z + connect_right = {0.25,0.25,-0.25,0.75,0.5,0.25}, -- +X + }, + connects_to = { + mod_name..":pillar_"..material.name.."_crossbrace", + mod_name..":pillar_"..material.name.."_extended_crossbrace", + "group:crossbrace_connectable"}, + connect_sides = { "front", "left", "back", "right" }, + }) + + minetest.register_node(mod_name..":pillar_"..material.name.."_extended_crossbrace", + { + drawtype = "nodebox", + description = S("@1 Extended Crossbrace", desc), + tiles = tile, + groups = composition_def.groups, + sounds = composition_def.sounds, + paramtype = "light", + paramtype2 = "facedir", + node_box = { + type = "fixed", + fixed = {-1.25,0.25,-0.25,1.25,0.5,0.25}, + }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_bottom 4", + recipe = { + {"",material.craft_material,""}, + {"",material.craft_material,""}, + {material.craft_material,material.craft_material,material.craft_material} }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_top 4", + recipe = { + {material.craft_material,material.craft_material,material.craft_material}, + {"",material.craft_material,""}, + {"",material.craft_material,""} }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_middle 2", + recipe = { + {material.craft_material}, + {material.craft_material}, + {material.craft_material} }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_crossbrace 10", + recipe = { + {material.craft_material,"",material.craft_material}, + {"",material.craft_material,""}, + {material.craft_material,"",material.craft_material} }, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_middle_half 2", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_middle"}, + }) + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_middle", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_middle_half", mod_name..":pillar_"..material.name.."_middle_half"}, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_top_half 2", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_top"}, + }) + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_top", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_top_half", mod_name..":pillar_"..material.name.."_top_half"}, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_bottom_half 2", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_bottom"}, + }) + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_bottom", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_bottom_half", mod_name..":pillar_"..material.name.."_bottom_half"}, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_extended_crossbrace", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_crossbrace"}, + }) + + minetest.register_craft({ + output = mod_name..":pillar_"..material.name.."_crossbrace", + type="shapeless", + recipe = {mod_name..":pillar_"..material.name.."_extended_crossbrace"}, + }) + + if burn_time > 0 then + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_top", + burntime = burn_time*5/4, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_top_half", + burntime = burn_time*5/8, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_bottom", + burntime = burn_time*5/4, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_bottom_half", + burntime = burn_time*5/8, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_middle", + burntime = burn_time*6/4, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_middle_half", + burntime = burn_time*6/8, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_crossbrace", + burntime = burn_time*5/10, + }) + minetest.register_craft({ + type = "fuel", + recipe = mod_name..":pillar_"..material.name.."_extended_crossbrace", + burntime = burn_time*5/10, + }) + end + +end + +-- The original castle mod had "pillars_", plural, which didn't match the arrowslit and murderhole standard. +castle_masonry.register_pillar_alias = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_bottom", new_mod_name..":pillar_"..new_material_name.."_bottom") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_bottom_half", new_mod_name..":pillar_"..new_material_name.."_bottom_half") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_crossbrace", new_mod_name..":pillar_"..new_material_name.."_crossbrace") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_middle", new_mod_name..":pillar_"..new_material_name.."_middle") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_middle_half", new_mod_name..":pillar_"..new_material_name.."_middle_half") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_top", new_mod_name..":pillar_"..new_material_name.."_top") + minetest.register_alias(old_mod_name..":pillars_"..old_material_name.."_top_half", new_mod_name..":pillar_"..new_material_name.."_top_half") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_bottom", new_mod_name..":pillar_"..new_material_name.."_bottom") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_bottom_half", new_mod_name..":pillar_"..new_material_name.."_bottom_half") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_crossbrace", new_mod_name..":pillar_"..new_material_name.."_crossbrace") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_middle", new_mod_name..":pillar_"..new_material_name.."_middle") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_middle_half", new_mod_name..":pillar_"..new_material_name.."_middle_half") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_top", new_mod_name..":pillar_"..new_material_name.."_top") + minetest.register_alias(old_mod_name..":pillar_"..old_material_name.."_top_half", new_mod_name..":pillar_"..new_material_name.."_top_half") +end + +castle_masonry.register_arrowslit_alias_force = function(old_mod_name, old_material_name, new_mod_name, new_material_name) + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_bottom", new_mod_name..":pillar_"..new_material_name.."_bottom") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_bottom_half", new_mod_name..":pillar_"..new_material_name.."_bottom_half") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_crossbrace", new_mod_name..":pillar_"..new_material_name.."_crossbrace") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_middle", new_mod_name..":pillar_"..new_material_name.."_middle") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_middle_half", new_mod_name..":pillar_"..new_material_name.."_middle_half") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_top", new_mod_name..":pillar_"..new_material_name.."_top") + minetest.register_alias_force(old_mod_name..":pillars_"..old_material_name.."_top_half", new_mod_name..":pillar_"..new_material_name.."_top_half") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_bottom", new_mod_name..":pillar_"..new_material_name.."_bottom") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_bottom_half", new_mod_name..":pillar_"..new_material_name.."_bottom_half") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_crossbrace", new_mod_name..":pillar_"..new_material_name.."_crossbrace") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_middle", new_mod_name..":pillar_"..new_material_name.."_middle") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_middle_half", new_mod_name..":pillar_"..new_material_name.."_middle_half") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_top", new_mod_name..":pillar_"..new_material_name.."_top") + minetest.register_alias_force(old_mod_name..":pillar_"..old_material_name.."_top_half", new_mod_name..":pillar_"..new_material_name.."_top_half") +end \ No newline at end of file diff --git a/mods/castle_masonry/settingtypes.txt b/mods/castle_masonry/settingtypes.txt new file mode 100644 index 0000000..ca58fb8 --- /dev/null +++ b/mods/castle_masonry/settingtypes.txt @@ -0,0 +1,24 @@ +[Materials] + +castle_masonry_stonewall (Stonewall) bool true +castle_masonry_cobble (Cobble) bool true +castle_masonry_stonebrick (Stone Brick) bool true +castle_masonry_sandstonebrick (Sandstone Brick) bool true +castle_masonry_desertstonebrick (Desert Stone Brick) bool true +castle_masonry_desertsandstonebrick (Desert Sandstone Brick) bool true +castle_masonry_silversandstonebrick (Silver Sandstone Brick) bool true +castle_masonry_stone (Stone) bool true +castle_masonry_sandstone (Sandstone) bool true +castle_masonry_desertstone (Desert Stone) bool true +castle_masonry_desertsandstone (Desert Sandstone) bool true +castle_masonry_silversandstone (Silver Sandstone) bool true +castle_masonry_wood (Wood) bool false +castle_masonry_ice (Ice) bool false +castle_masonry_snow (Snow) bool false +castle_masonry_obsidianbrick (Obsidian Brick) bool false + +[Forms] + +castle_masonry_pillar (Pillars) bool true +castle_masonry_arrowslit (Arrow slits) bool true +castle_masonry_murderhole (Murder holes and machicolations) bool true diff --git a/mods/castle_masonry/stone_wall.lua b/mods/castle_masonry/stone_wall.lua new file mode 100644 index 0000000..ae598e0 --- /dev/null +++ b/mods/castle_masonry/stone_wall.lua @@ -0,0 +1,160 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_alias("castle:stonewall", "castle_masonry:stonewall") +minetest.register_alias("castle:dungeon_stone", "castle_masonry:dungeon_stone") +minetest.register_alias("castle:rubble", "castle_masonry:rubble") +minetest.register_alias("castle:stonewall_corner", "castle_masonry:stonewall_corner") + +minetest.register_node("castle_masonry:stonewall", { + description = S("Castle Wall"), + drawtype = "normal", + tiles = {"castle_stonewall.png"}, + paramtype = "light", + drop = "castle_masonry:stonewall", + groups = {cracky=3}, + sunlight_propagates = false, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("castle_masonry:rubble", { + description = S("Castle Rubble"), + drawtype = "normal", + tiles = {"castle_rubble.png"}, + paramtype = "light", + groups = {crumbly=3,falling_node=1}, + sounds = default.node_sound_gravel_defaults(), +}) + +minetest.register_craft({ + output = "castle_masonry:stonewall", + recipe = { + {"default:cobble"}, + {"default:desert_stone"}, + } +}) + +minetest.register_craft({ + output = "castle_masonry:rubble", + recipe = { + {"castle_masonry:stonewall"}, + } +}) + +minetest.register_craft({ + output = "castle_masonry:rubble 2", + recipe = { + {"default:gravel"}, + {"default:desert_stone"}, + } +}) + +minetest.register_node("castle_masonry:stonewall_corner", { + drawtype = "normal", + paramtype = "light", + paramtype2 = "facedir", + description = S("Castle Corner"), + tiles = {"castle_corner_stonewall_tb.png^[transformR90", + "castle_corner_stonewall_tb.png^[transformR180", + "castle_corner_stonewall1.png", + "castle_stonewall.png", + "castle_stonewall.png", + "castle_corner_stonewall2.png"}, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "castle_masonry:stonewall_corner", + recipe = { + {"", "castle_masonry:stonewall"}, + {"castle_masonry:stonewall", "default:sandstone"}, + } +}) + +if minetest.get_modpath("moreblocks") then + stairsplus:register_all("castle_masonry", "stonewall", "castle_masonry:stonewall", { + description = S("Stone Wall"), + tiles = {"castle_stonewall.png"}, + groups = {cracky=3, not_in_creative_inventory=1}, + sounds = default.node_sound_stone_defaults(), + sunlight_propagates = true, + }) + + stairsplus:register_all("castle_masonry", "rubble", "castle_masonry:rubble", { + description = S("Rubble"), + tiles = {"castle_rubble.png"}, + groups = {cracky=3, not_in_creative_inventory=1}, + sounds = default.node_sound_gravel_defaults(), + sunlight_propagates = true, + }) + + stairsplus:register_stair_alias("castle", "stonewall", "castle_masonry", "stonewall") + stairsplus:register_stair_alias("castle", "rubble", "castle_masonry", "rubble") + +elseif minetest.get_modpath("stairs") then + stairs.register_stair_and_slab("stonewall", "castle_masonry:stonewall", + {cracky=3}, + {"castle_stonewall.png"}, + S("Castle Stonewall Stair"), + S("Castle Stonewall Slab"), + default.node_sound_stone_defaults() + ) + + stairs.register_stair_and_slab("rubble", "castle_masonry:rubble", + {cracky=3}, + {"castle_rubble.png"}, + S("Castle Rubble Stair"), + S("Castle Rubble Slab"), + default.node_sound_stone_defaults() + ) +end + +-------------------------------------------------------------------------------------------------------------- + +minetest.register_node("castle_masonry:dungeon_stone", { + description = S("Dungeon Stone"), + drawtype = "normal", + tiles = {"castle_dungeon_stone.png"}, + groups = {cracky=2}, + paramtype = "light", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "castle_masonry:dungeon_stone 2", + recipe = { + {"default:stonebrick", "default:obsidian"}, + } +}) + +minetest.register_craft({ + output = "castle_masonry:dungeon_stone 2", + recipe = { + {"default:stonebrick"}, + {"default:obsidian"}, + } +}) + + +if minetest.get_modpath("moreblocks") then + stairsplus:register_all("castle", "dungeon_stone", "castle_masonry:dungeon_stone", { + description = S("Dungeon Stone"), + tiles = {"castle_dungeon_stone.png"}, + groups = {cracky=2, not_in_creative_inventory=1}, + sounds = default.node_sound_stone_defaults(), + sunlight_propagates = true, + }) + + stairsplus:register_stair_alias("castle", "dungeon_stone", "castle_masonry", "dungeon_stone") + +elseif minetest.get_modpath("stairs") then + stairs.register_stair_and_slab("dungeon_stone", "castle_masonry:dungeon_stone", + {cracky=2}, + {"castle_dungeon_stone.png"}, + S("Dungeon Stone Stair"), + S("Dungeon Stone Slab"), + default.node_sound_stone_defaults() + ) +end \ No newline at end of file diff --git a/mods/castle_masonry/textures/LICENSE.txt b/mods/castle_masonry/textures/LICENSE.txt new file mode 100644 index 0000000..306be33 --- /dev/null +++ b/mods/castle_masonry/textures/LICENSE.txt @@ -0,0 +1,21 @@ +-------------------------------------------- + +License Textures: Philipner - CC-BY-SA 3.0 + +-castle_corner_stonewall_tb.png +-castle_corner_stonewall1.png +-castle_corner_stonewall2.png + +-------------------------------------------- + +16 px textures based on Castle mod +original textures by Philipner + +License Textures: Napiophelios - CC-BY-SA 3.0 + +-castle_pavement_brick.png +-castle_rubble.png +-castle_slate.png +-castle_stonewall.png + +-------------------------------------------- diff --git a/mods/castle_masonry/textures/castle_corner_stonewall1.png b/mods/castle_masonry/textures/castle_corner_stonewall1.png new file mode 100644 index 0000000..0a9c091 Binary files /dev/null and b/mods/castle_masonry/textures/castle_corner_stonewall1.png differ diff --git a/mods/castle_masonry/textures/castle_corner_stonewall2.png b/mods/castle_masonry/textures/castle_corner_stonewall2.png new file mode 100644 index 0000000..d9d7d0c Binary files /dev/null and b/mods/castle_masonry/textures/castle_corner_stonewall2.png differ diff --git a/mods/castle_masonry/textures/castle_corner_stonewall_tb.png b/mods/castle_masonry/textures/castle_corner_stonewall_tb.png new file mode 100644 index 0000000..d72d78d Binary files /dev/null and b/mods/castle_masonry/textures/castle_corner_stonewall_tb.png differ diff --git a/mods/castle_masonry/textures/castle_dungeon_stone.png b/mods/castle_masonry/textures/castle_dungeon_stone.png new file mode 100644 index 0000000..6a2c154 Binary files /dev/null and b/mods/castle_masonry/textures/castle_dungeon_stone.png differ diff --git a/mods/castle_masonry/textures/castle_pavement_brick.png b/mods/castle_masonry/textures/castle_pavement_brick.png new file mode 100644 index 0000000..fd10e0f Binary files /dev/null and b/mods/castle_masonry/textures/castle_pavement_brick.png differ diff --git a/mods/castle_masonry/textures/castle_rubble.png b/mods/castle_masonry/textures/castle_rubble.png new file mode 100644 index 0000000..fbaa32c Binary files /dev/null and b/mods/castle_masonry/textures/castle_rubble.png differ diff --git a/mods/castle_masonry/textures/castle_slate.png b/mods/castle_masonry/textures/castle_slate.png new file mode 100644 index 0000000..a7de1ea Binary files /dev/null and b/mods/castle_masonry/textures/castle_slate.png differ diff --git a/mods/castle_masonry/textures/castle_stonewall.png b/mods/castle_masonry/textures/castle_stonewall.png new file mode 100644 index 0000000..b8f823f Binary files /dev/null and b/mods/castle_masonry/textures/castle_stonewall.png differ diff --git a/mods/castle_weapons/README.txt b/mods/castle_weapons/README.txt new file mode 100644 index 0000000..62ec203 --- /dev/null +++ b/mods/castle_weapons/README.txt @@ -0,0 +1,16 @@ +=-=-=-=-=-=-=-=-=-= + +Castles Mod +by: Philipbenr And DanDuncombe + +=-=-=-=-=-=-=-=-=-= + +Licence: MIT, LGPLv2.1 (Crossbow) + +see: LICENSE + +=-=-=-=-=-=-=-=-=-= + +This mod contains a crossbow with bolts, suitable for ranged combat. The crossbow is sourced from the "shooter" mod. + +It also contains a battleaxe for fighting up close and personal. \ No newline at end of file diff --git a/mods/castle_weapons/battleaxe.lua b/mods/castle_weapons/battleaxe.lua new file mode 100644 index 0000000..9a784dc --- /dev/null +++ b/mods/castle_weapons/battleaxe.lua @@ -0,0 +1,30 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +minetest.register_alias("castle:battleaxe", "castle_weapons:battleaxe") + +minetest.register_tool("castle_weapons:battleaxe", { + description = S("Battleaxe"), + inventory_image = "castle_battleaxe.png", + tool_capabilities = { + full_punch_interval = 1.2, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.10, [2]=0.90, [3]=0.50}, uses=40, maxlevel=3}, + snappy={times={[1]=1.90, [2]=0.90, [3]=0.30}, uses=40, maxlevel=3}, + }, + damage_groups = {fleshy=10, knockback = 2}, + }, +}) + +--[[ +minetest.register_craft({ + output = "castle_weapons:battleaxe", + recipe = { + {"default:steel_ingot", "default:steel_ingot","default:steel_ingot"}, + {"default:steel_ingot", "default:stick","default:steel_ingot"}, + {"", "default:stick",""} + } +}) +--]] diff --git a/mods/castle_weapons/crossbow.lua b/mods/castle_weapons/crossbow.lua new file mode 100644 index 0000000..6d5e3d7 --- /dev/null +++ b/mods/castle_weapons/crossbow.lua @@ -0,0 +1,490 @@ +--[[ +Minetest Mod - Simple Shooter [shooter] 0.5.3 +======================================= + +License Source Code: 2013 Stuart Jones - LGPL v2.1 + +License Textures: Stuart Jones - WTFPL + +Licence Models: Stuart Jones - CC-BY-SA 3.0 + +License Sounds: freesound.org + +--]] +minetest.register_alias('crossbow', 'castle_weapons:crossbow') +minetest.register_alias('bolt', 'castle_weapons:crossbow_bolt') +minetest.register_alias('castle:crossbow', 'castle_weapons:crossbow') +minetest.register_alias('castle:bolt', 'castle_weapons:crossbow_bolt') +minetest.register_alias('castle:crossbow_bolt', 'castle_weapons:crossbow_bolt') +minetest.register_alias('castle:crossbow_loaded', 'castle_weapons:crossbow_loaded') + +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP..'/intllib.lua') + +local crossbow={} + +CROSSBOW_USES = 300 +CROSSBOW_BOLT_TOOL_CAPS = {damage_groups={fleshy=4}} +CROSSBOW_BOLT_LIFETIME = 60-- 1 minute +CROSSBOW_ENABLE_PARTICLE_FX = false +CROSSBOW_ENABLE_PROTECTION = true +CROSSBOW_EXPLOSION_TEXTURE = 'castle_crossbow_hit.png' +CROSSBOW_ALLOW_NODES = true +CROSSBOW_ALLOW_ENTITIES = true +CROSSBOW_ALLOW_PLAYERS = true +CROSSBOW_PLAYER_OFFSET = {x=0, y=1, z=0} +CROSSBOW_ENTITY_OFFSET = {x=0, y=0, z=0} +CROSSBOW_ENTITIES = { +'zombies:1arm', +'zombies:crawler', +'zombies:normal', +'scorpion:big', +'scorpion:boss', +'scorpion:little', +'scorpion:pet', +'farm_mobs:goat_he', +'farm_mobs:goat_she', +'farm_mobs:dog', +'fantasy_mobs:fairy', +'fantasy_mobs:gnome', +'fantasy_mobs:goblin', +'fantasy_mobs:mummy', +'fantasy_mobs:larva', +'fantasy_mobs:larva_pet', +'fantasy_mobs:cavefreak_slash', +'fantasy_mobs:cavefreak_fire', +'desert_life:ostrich', +'desert_life:armadillo', +'epic:ocean_guardian', +'arctic_life:penguin', +'arctic_life:walrus', +'desert_life:ostrich', +'desert_life:armadillo', +'mobs_animal:bunny', +'mobs_animal:chicken', +'mobs_animal:cow', +'mobs_animal:kitten', +'mobs_animal:panda', +'mobs_animal:sheep_white', +'mobs_animal:pumba', +'mob_horse:horse', +'mobs_monster:dirt_monster', +'mobs_monster:dungeon_master', +'mobs_monster:lava_flan', +'mobs_monster:mese_monster', +'mobs_monster:oerkki', +'mobs_monster:sand_monster', +'mobs_monster:spider', +'mobs_monster:stone_monster', +'mobs_monster:tree_monster', +'mobs_crocs:crocodile', +'mobs_crocs:crocodile_swim', +'mobs_crocs:crocodile_float', +'mobs_turtles:turtle', +'mobs_turtles:seaturtle' +} + +if minetest.is_singleplayer() == true then + CROSSBOW_ALLOW_ENTITIES = true + CROSSBOW_ALLOW_PLAYERS = true +end + +local allowed_entities = {} +for _,v in ipairs(CROSSBOW_ENTITIES) do + allowed_entities[v] = 1 +end + +local function get_dot_product(v1, v2) + return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z +end + +local function get_particle_pos(p, v, d) + return vector.add(p, vector.multiply(v, {x=d, y=d, z=d})) +end + +function crossbow:spawn_particles(pos, texture) + if CROSSBOW_ENABLE_PARTICLE_FX == true then + if type(texture) ~= 'string' then + texture = CROSSBOW_EXPLOSION_TEXTURE + end + local spread = {x=0.1, y=0.1, z=0.1} + minetest.add_particlespawner({ + amount = 15, + time = 0.3, + minpos = vector.subtract(pos, spread), + maxpos = vector.add(pos, spread), + minvel = {x=-1, y=1, z=-1}, + maxvel = {x=1, y=2, z=1}, + minacc = {x=-2, y=-2, z=-2}, + maxacc = {x=2, y=-2, z=2}, + minexptime = 0.1, + maxexptime = 0.75, + minsize = 1, + maxsize = 2, + collisiondetection = false, + texture = texture, + }) + end +end + +function crossbow:punch_node(pos, def) + local node = minetest.get_node(pos) + if not node then + return + end + local item = minetest.registered_items[node.name] + if not item then + return + end + if CROSSBOW_ENABLE_PROTECTION then + if minetest.is_protected(pos, def.name) then + return + end + end + if item.groups then + for k, v in pairs(def.groups) do + local level = item.groups[k] or 0 + if level >= v then + minetest.remove_node(pos) + if item.tiles then + if item.tiles[1] then + crossbow:spawn_particles(pos, item.tiles[1]) + end + end + break + end + end + end +end + +function crossbow:is_valid_object(object) + if object then + if object:is_player() == true then + return CROSSBOW_ALLOW_PLAYERS + end + if CROSSBOW_ALLOW_ENTITIES == true then + local luaentity = object:get_luaentity() + if luaentity then + if luaentity.name then + if allowed_entities[luaentity.name] then + return true + end + end + end + end + end +end + +function crossbow:get_intersect_pos(ray, plane, collisionbox) + local v = vector.subtract(ray.pos, plane.pos) + local r1 = get_dot_product(v, plane.normal) + local r2 = get_dot_product(ray.dir, plane.normal) + if r2 ~= 0 then + local t = -(r1 / r2) + local td = vector.multiply(ray.dir, {x=t, y=t, z=t}) + local pt = vector.add(ray.pos, td) + local pd = vector.subtract(pt, plane.pos) + if math.abs(pd.x) < collisionbox[4] and + math.abs(pd.y) < collisionbox[5] and + math.abs(pd.z) < collisionbox[6] then + return pt + end + end +end + +function crossbow:process_round(round) + local target = {object=nil, distance=10000} + local p1 = round.pos + local v1 = round.ray + for _,ref in ipairs(castle.objects) do + local p2 = vector.add(ref.pos, ref.offset) + if p1 and p2 and ref.name ~= round.name then + local d = vector.distance(p1, p2) + if d < round.def.step and d < target.distance then + local ray = {pos=p1, dir=v1} + local plane = {pos=p2, normal={x=-1, y=0, z=-1}} + local pos = crossbow:get_intersect_pos(ray, plane, ref.collisionbox) + if pos then + target.object = ref.object + target.pos = pos + target.distance = d + end + end + end + end + if target.object and target.pos then + local success, pos = minetest.line_of_sight(p1, target.pos, 1) + if success then + local user = minetest.get_player_by_name(round.name) + if user then + target.object:punch(user, nil, round.def.tool_caps, v1) + crossbow:spawn_particles(target.pos, CROSSBOW_EXPLOSION_TEXTURE) + end + return 1 + elseif pos and CROSSBOW_ALLOW_NODES == true then + crossbow:punch_node(pos, round.def) + return 1 + end + elseif CROSSBOW_ALLOW_NODES == true then + local d = round.def.step + local p2 = vector.add(p1, vector.multiply(v1, {x=d, y=d, z=d})) + local success, pos = minetest.line_of_sight(p1, p2, 1) + if pos then + crossbow:punch_node(pos, round.def) + return 1 + end + end +end + +local function get_animation_frame(dir) + local angle = math.atan(dir.y) + local frame = 90 - math.floor(angle * 360 / math.pi) + if frame < 1 then + frame = 1 + elseif frame > 180 then + frame = 180 + end + return frame +end + +local function get_target_pos(p1, p2, dir, offset) + local d = vector.distance(p1, p2) - offset + local td = vector.multiply(dir, {x=d, y=d, z=d}) + return vector.add(p1, td) +end + +local function punch_object(puncher, object) + if puncher and crossbow:is_valid_object(object) then + if puncher ~= object then + local dir = puncher:get_look_dir() + local p1 = puncher:getpos() + local p2 = object:getpos() + local tpos = get_target_pos(p1, p2, dir, 0) + crossbow:spawn_particles(tpos, CROSSBOW_EXPLOSION_TEXTURE) + object:punch(puncher, nil, CROSSBOW_BOLT_TOOL_CAPS, dir) + end + end +end + +local function stop_crossbow_bolt(object, pos, stuck) + local acceleration = {x=0, y=-10, z=0} + if stuck == true then + pos = pos or object:getpos() + acceleration = {x=0, y=0, z=0} + object:moveto(pos) + end + object:set_properties({ + physical = true, + collisionbox = {-1/8,-1/8,-1/8, 1/8,1/8,1/8}, + }) + object:setvelocity({x=0, y=0, z=0}) + object:setacceleration(acceleration) +end + +minetest.register_craftitem('castle_weapons:crossbow_bolt', { + description = S('Bolt'), + inventory_image = 'castle_crossbow_bolt_inv.png', +}) + +minetest.register_entity('castle_weapons:crossbow_bolt_entity', { + physical = false, + visual = 'mesh', + mesh = 'castle_crossbow_bolt.b3d', + visual_size = {x=1.0, y=1.0}, + textures = { + 'castle_crossbow_bolt_uv.png' + }, + timer = 0, + lifetime = CROSSBOW_BOLT_LIFETIME, + player = nil, + state = 'init', + node_pos = nil, + collisionbox = {0,0,0, 0,0,0}, + on_activate = function(self, staticdata) + self.object:set_armor_groups({immortal=1}) + if staticdata == 'expired' then + self.object:remove() + end + end, + on_punch = function(self, puncher) + if puncher then + if puncher:is_player() then + local stack = 'castle_weapons:crossbow_bolt' + local inv = puncher:get_inventory() + if inv:room_for_item('main', stack) then + inv:add_item('main', stack) + self.object:remove() + end + end + end + end, + on_step = function(self, dtime) + if self.state == 'init' then + return + end + self.timer = self.timer + dtime + self.lifetime = self.lifetime - dtime + if self.lifetime < 0 then + self.object:remove() + return + elseif self.state == 'dropped' then + return + elseif self.state == 'stuck' then + if self.timer > 1 then + if self.node_pos then + local node = minetest.get_node(self.node_pos) + if node.name then + local item = minetest.registered_items[node.name] + if item then + if not item.walkable then + self.state = 'dropped' + stop_crossbow_bolt(self.object) + return + end + end + end + end + self.timer = 0 + end + return + end + if self.timer > 0.2 then + local pos = self.object:getpos() + local dir = vector.normalize(self.object:getvelocity()) + local frame = get_animation_frame(dir) + self.object:set_animation({x=frame, y=frame}, 0) + local objects = minetest.get_objects_inside_radius(pos, 5) + for _,obj in ipairs(objects) do + if crossbow:is_valid_object(obj) then + local collisionbox = {-0.25,-1.0,-0.25, 0.25,0.8,0.25} + local offset = CROSSBOW_PLAYER_OFFSET + if not obj:is_player() then + offset = CROSSBOW_ENTITY_OFFSET + local ent = obj:get_luaentity() + if ent then + local def = minetest.registered_entities[ent.name] + collisionbox = def.collisionbox or collisionbox + end + end + local opos = vector.add(obj:getpos(), offset) + local ray = {pos=pos, dir=dir} + local plane = {pos=opos, normal={x=-1, y=0, z=-1}} + local ipos = crossbow:get_intersect_pos(ray, plane, collisionbox) + if ipos then + punch_object(self.player, obj) + end + end + end + local p = vector.add(pos, vector.multiply(dir, {x=5, y=5, z=5})) + local _, npos = minetest.line_of_sight(pos, p, 1) + if npos then + local node = minetest.get_node(npos) + local tpos = get_target_pos(pos, npos, dir, 0.66) + self.node_pos = npos + self.state = 'stuck' + stop_crossbow_bolt(self.object, tpos, true) + minetest.sound_play('castle_crossbow_bolt', {gain = 0.08, max_hear_distance = 2}) + end + self.timer = 0 + end + end, + get_staticdata = function(self) + return 'expired' + end, +}) + + minetest.register_tool('castle_weapons:crossbow_loaded', { + description = S('Crossbow'), + inventory_image = 'castle_crossbow_loaded.png', + groups = {not_in_creative_inventory=1}, + on_use = function(itemstack, user, pointed_thing) + minetest.sound_play('castle_crossbow_click', {object=user}) + if not minetest.settings:get_bool('creative_mode') then + itemstack:add_wear(65535/CROSSBOW_USES) + end + itemstack = 'castle_weapons:crossbow 1 '..itemstack:get_wear() + local pos = user:getpos() + local dir = user:get_look_dir() + local yaw = user:get_look_yaw() + if pos and dir and yaw then + pos.y = pos.y + 1.5 + local obj = minetest.add_entity(pos, 'castle_weapons:crossbow_bolt_entity') + local ent = nil + if obj then + ent = obj:get_luaentity() + end + if ent then + obj:set_properties({ + textures = {'castle_crossbow_bolt_uv.png'} + }) + minetest.sound_play('castle_crossbow_shoot', {object=obj}) + local frame = get_animation_frame(dir) + obj:setyaw(yaw + math.pi) + obj:set_animation({x=frame, y=frame}, 0) + obj:setvelocity({x=dir.x * 20, y=dir.y * 20, z=dir.z * 20}) + if pointed_thing.type ~= 'nothing' then + local ppos = minetest.get_pointed_thing_position(pointed_thing, false) + local _, npos = minetest.line_of_sight(pos, ppos, 1) + if npos then + ppos = npos + pointed_thing.type = 'node' + end + if pointed_thing.type == 'object' then + punch_object(user, pointed_thing.ref) + elseif pointed_thing.type == 'node' then + local node = minetest.get_node(ppos) + local tpos = get_target_pos(pos, ppos, dir, 0.66) + minetest.after(0.2, function(object, pos, npos) + ent.node_pos = npos + ent.state = 'stuck' + stop_crossbow_bolt(object, pos, true) + minetest.sound_play('castle_crossbow_bolt', {gain = 0.08, max_hear_distance = 2}) + end, obj, tpos, ppos) + return itemstack + end + end + obj:setacceleration({x=dir.x * -3, y=-5, z=dir.z * -3}) + ent.player = ent.player or user + ent.state = 'flight' + end + end + return itemstack + end, + }) + +minetest.register_tool('castle_weapons:crossbow', { + description = S('Crossbow'), + inventory_image = 'castle_crossbow_inv.png', + on_use = function(itemstack, user, pointed_thing) + local inv = user:get_inventory() +if inv:contains_item('main', 'castle_weapons:crossbow_bolt') then + minetest.sound_play('castle_crossbow_reload', {object=user}) + if not minetest.settings:get_bool('creative_mode') then + inv:remove_item('main', 'castle_weapons:crossbow_bolt 1') + end + return 'castle_weapons:crossbow_loaded 1 '..itemstack:get_wear() + end + minetest.sound_play('castle_crossbow_click', {object=user}) + end, +}) + +----------- +--Crafting +----------- + +minetest.register_craft({ + output = 'castle_weapons:crossbow', + recipe = { + {'default:steel_ingot', 'default:stick', 'default:steel_ingot'}, + {'farming:string', 'farming:string', 'farming:string'}, + {'', 'default:stick', ''}, + } +}) + +minetest.register_craft({ + output = 'castle_weapons:crossbow_bolt', + recipe = { + {'epic:arrow_tip', 'default:stick'}, + } +}) diff --git a/mods/castle_weapons/init.lua b/mods/castle_weapons/init.lua new file mode 100644 index 0000000..20d3df3 --- /dev/null +++ b/mods/castle_weapons/init.lua @@ -0,0 +1,7 @@ +local MP = minetest.get_modpath(minetest.get_current_modname()) + +dofile(MP.."/crossbow.lua") +dofile(MP.."/battleaxe.lua") + + + diff --git a/mods/castle_weapons/intllib.lua b/mods/castle_weapons/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/castle_weapons/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/castle_weapons/license.txt b/mods/castle_weapons/license.txt new file mode 100644 index 0000000..456d091 --- /dev/null +++ b/mods/castle_weapons/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Minetest Mods Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/castle_weapons/locale/it.po b/mods/castle_weapons/locale/it.po new file mode 100644 index 0000000..e83b45f --- /dev/null +++ b/mods/castle_weapons/locale/it.po @@ -0,0 +1,31 @@ +# ITALIAN LOCALE FILE FOR THE CASTLE WEAPONS MODULE +# Copyright (C) 2017 Philipbenr And DanDuncombe +# This file is distributed under the same license as the CASTLE WEAPONS package. +# Hamlet , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: Castle Weapons\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-25 19:35-0700\n" +"PO-Revision-Date: 2017-09-10 22:49+0100\n" +"Last-Translator: H4mlet \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language: it\n" +"X-Generator: Poedit 1.6.10\n" + +#: battleaxe.lua:8 +msgid "Battleaxe" +msgstr "Ascia da guerra" + +#: crossbow.lua:244 +msgid "Bolt" +msgstr "Quadrello" + +#: crossbow.lua:357 crossbow.lua:416 +msgid "Crossbow" +msgstr "Balestra" diff --git a/mods/castle_weapons/locale/template.pot b/mods/castle_weapons/locale/template.pot new file mode 100644 index 0000000..79f7a19 --- /dev/null +++ b/mods/castle_weapons/locale/template.pot @@ -0,0 +1,29 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-25 19:35-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: battleaxe.lua:8 +msgid "Battleaxe" +msgstr "" + +#: crossbow.lua:244 +msgid "Bolt" +msgstr "" + +#: crossbow.lua:357 crossbow.lua:416 +msgid "Crossbow" +msgstr "" diff --git a/mods/castle_weapons/mod.conf b/mods/castle_weapons/mod.conf new file mode 100644 index 0000000..d19c9bb --- /dev/null +++ b/mods/castle_weapons/mod.conf @@ -0,0 +1,4 @@ +name = castle_weapons +depends = default +optional_depends = intllib +description = Provides several medieval weapons for use around castles diff --git a/mods/castle_weapons/models/LICENSE.txt b/mods/castle_weapons/models/LICENSE.txt new file mode 100644 index 0000000..7c019e6 --- /dev/null +++ b/mods/castle_weapons/models/LICENSE.txt @@ -0,0 +1,10 @@ +License Textures: Stuart Jones - WTFPL + +-castle_crossbow_bolt_inv.png +-castle_crossbow_bolt_uv.png +-castle_crossbow_hit.png + +Licence Models: Stuart Jones - CC-BY-SA 3.0 + +-castle_crossbow_bolt.b3d +-castle_crossbow_bolt.blend \ No newline at end of file diff --git a/mods/castle_weapons/models/castle_crossbow_bolt.b3d b/mods/castle_weapons/models/castle_crossbow_bolt.b3d new file mode 100644 index 0000000..d24be3c Binary files /dev/null and b/mods/castle_weapons/models/castle_crossbow_bolt.b3d differ diff --git a/mods/castle_weapons/models/castle_crossbow_bolt.blend b/mods/castle_weapons/models/castle_crossbow_bolt.blend new file mode 100644 index 0000000..4cf5f43 Binary files /dev/null and b/mods/castle_weapons/models/castle_crossbow_bolt.blend differ diff --git a/mods/castle_weapons/models/castle_crossbow_bolt_uv.png b/mods/castle_weapons/models/castle_crossbow_bolt_uv.png new file mode 100644 index 0000000..b7d29c5 Binary files /dev/null and b/mods/castle_weapons/models/castle_crossbow_bolt_uv.png differ diff --git a/mods/castle_weapons/screenshot.png b/mods/castle_weapons/screenshot.png new file mode 100644 index 0000000..d23d181 Binary files /dev/null and b/mods/castle_weapons/screenshot.png differ diff --git a/mods/castle_weapons/sounds/LICENSE.txt b/mods/castle_weapons/sounds/LICENSE.txt new file mode 100644 index 0000000..b127b0e --- /dev/null +++ b/mods/castle_weapons/sounds/LICENSE.txt @@ -0,0 +1,19 @@ +License Sounds +------------------ + +(From Simple Shooter mod by Stuart Jones) +-castle_crossbow_click.ogg +-castle_crossbow_shoot.ogg +-castle_crossbow_reload.ogg + +Author : freesound.org +License : Attribution 3.0 Unported (CC BY 3.0) +CC0 1.0 Universal (CC0 1.0) + +------------------ + +(From Minetest Game:default mod) +-default_wood_footstep.1.ogg +(renamed to : castle_crossbow_bolt.ogg) +Author : Mito551 +License : (CC BY-SA) diff --git a/mods/castle_weapons/sounds/castle_crossbow_bolt.ogg b/mods/castle_weapons/sounds/castle_crossbow_bolt.ogg new file mode 100644 index 0000000..34f63a1 Binary files /dev/null and b/mods/castle_weapons/sounds/castle_crossbow_bolt.ogg differ diff --git a/mods/castle_weapons/sounds/castle_crossbow_click.ogg b/mods/castle_weapons/sounds/castle_crossbow_click.ogg new file mode 100644 index 0000000..8e60db8 Binary files /dev/null and b/mods/castle_weapons/sounds/castle_crossbow_click.ogg differ diff --git a/mods/castle_weapons/sounds/castle_crossbow_reload.ogg b/mods/castle_weapons/sounds/castle_crossbow_reload.ogg new file mode 100644 index 0000000..47f7245 Binary files /dev/null and b/mods/castle_weapons/sounds/castle_crossbow_reload.ogg differ diff --git a/mods/castle_weapons/sounds/castle_crossbow_shoot.ogg b/mods/castle_weapons/sounds/castle_crossbow_shoot.ogg new file mode 100644 index 0000000..9ce9176 Binary files /dev/null and b/mods/castle_weapons/sounds/castle_crossbow_shoot.ogg differ diff --git a/mods/castle_weapons/textures/LICENSE.txt b/mods/castle_weapons/textures/LICENSE.txt new file mode 100644 index 0000000..0ecff29 --- /dev/null +++ b/mods/castle_weapons/textures/LICENSE.txt @@ -0,0 +1,25 @@ +-------------------------------------------- + +License Textures: Stuart Jones - WTFPL +-castle_crossbow_bolt_inv.png +-castle_crossbow_bolt_uv.png +-castle_crossbow_hit.png + +Licence Models: Stuart Jones - CC-BY-SA 3.0 +-castle_crossbow_bolt.b3d +-castle_crossbow_bolt.blend + + +-------------------------------------------- + +16 px textures based on Castle mod +original textures by Philipner + +License Textures: Napiophelios - CC-BY-SA 3.0 + +-castle_battleaxe.png +-castle_crossbow_bolt_inv.png +-castle_crossbow_hit.png +-castle_crossbow_loaded.png + +-------------------------------------------- diff --git a/mods/castle_weapons/textures/castle_battleaxe.png b/mods/castle_weapons/textures/castle_battleaxe.png new file mode 100644 index 0000000..4f7f738 Binary files /dev/null and b/mods/castle_weapons/textures/castle_battleaxe.png differ diff --git a/mods/castle_weapons/textures/castle_crossbow_bolt_inv.png b/mods/castle_weapons/textures/castle_crossbow_bolt_inv.png new file mode 100644 index 0000000..87cd847 Binary files /dev/null and b/mods/castle_weapons/textures/castle_crossbow_bolt_inv.png differ diff --git a/mods/castle_weapons/textures/castle_crossbow_hit.png b/mods/castle_weapons/textures/castle_crossbow_hit.png new file mode 100644 index 0000000..0a2b2f3 Binary files /dev/null and b/mods/castle_weapons/textures/castle_crossbow_hit.png differ diff --git a/mods/castle_weapons/textures/castle_crossbow_inv.png b/mods/castle_weapons/textures/castle_crossbow_inv.png new file mode 100644 index 0000000..39bcf07 Binary files /dev/null and b/mods/castle_weapons/textures/castle_crossbow_inv.png differ diff --git a/mods/castle_weapons/textures/castle_crossbow_loaded.png b/mods/castle_weapons/textures/castle_crossbow_loaded.png new file mode 100644 index 0000000..ca2dca7 Binary files /dev/null and b/mods/castle_weapons/textures/castle_crossbow_loaded.png differ diff --git a/mods/caverealms_lite/README.md b/mods/caverealms_lite/README.md new file mode 100644 index 0000000..4ab76b8 --- /dev/null +++ b/mods/caverealms_lite/README.md @@ -0,0 +1,31 @@ +# caverealms-lite + +Based on the original minetest-caverealms mod (https://github.com/HeroOfTheWinds/minetest-caverealms/). + +Adds underground realms to minetest. + +This caverealms fork provides all the biomes and decorations from the original caverealms, with several additions and without the overhead of generating caves. This lowers the server resources the mod requires, for example CPU and RAM. This also removes the large lava spills created by the original caverealms. + +It is specifically written to work with the mgvalleys mapgen, but will work using other mapgens as well. The mapgen used will determine the shape and size of individual caves. Mapgens that generate only smaller caves may be less suitable for use with this fork than mgvalleys. + +Note: For worlds where the original caverealms is already in use, this fork is not advised as a replacement. If used in this way, some unknown nodes and other minor issues should be expected. + + +## License and Contributors + +Source code: FreeBSD License (Simplified) +The original caverealms was licensed as WTFPL. + +Contributors: +- Zeno, Shara RedCat - This rewrite +- HeroOfTheWinds, Zeno - Original mod + + +## Recommended Additions + +- VanessaE's HDX texturepacks provide alternative textures. For example, +https://gitlab.com/VanessaE/hdx-128. +- ethereal mod unlocks additional content (https://notabug.org/tenplus1/ethereal). +- mobs_monster mod allows Dungeon Masters to spawn in the Dungeon Master's Lair biome (https://notabug.org/tenplus1/mobs_monster). +- mobs_redo is required to run mobs_monster (https://notabug.org/tenplus1/mobs_redo). +- abritorch adds coloured torches made with caverealms items (https://github.com/Ezhh/abritorch). diff --git a/mods/caverealms_lite/config.lua b/mods/caverealms_lite/config.lua new file mode 100644 index 0000000..dbfb4aa --- /dev/null +++ b/mods/caverealms_lite/config.lua @@ -0,0 +1,53 @@ +local CONFIG_FILE_PREFIX = "caverealms." + +caverealms.config = {} + +-- This function based on kaeza/minetest-irc/config.lua and used under the +-- terms of BSD 2-clause license. +local function setting(stype, name, default) + local value + if stype == "bool" then + value = minetest.settings:get_bool(CONFIG_FILE_PREFIX..name) + elseif stype == "string" then + value = minetest.settings:get(CONFIG_FILE_PREFIX..name) + elseif stype == "number" then + value = tonumber(minetest.settings:get(CONFIG_FILE_PREFIX..name)) + end + if value == nil then + value = default + end + caverealms.config[name] = value +end + +--generation settings +setting("number", "ymin", -22000) --bottom realm limit +setting("number", "ymax", -1500) --top realm limit +setting("number", "tcave", 0.75) --cave threshold + +--decoration chances +setting("number", "stagcha", 0.003) --chance of stalagmites +setting("number", "stalcha", 0.003) --chance of stalactites + +setting("number", "h_lag", 8) --max height for stalagmites +setting("number", "h_lac", 8) --...stalactites +setting("number", "crystal", 0.0002) --chance of glow crystal formations +setting("number", "h_cry", 8) --max height of glow crystals +setting("number", "h_clac", 8) --max height of glow crystal stalactites + +setting("number", "gemcha", 0.03) --chance of small glow gems +setting("number", "mushcha", 0.04) --chance of mushrooms +setting("number", "myccha", 0.03) --chance of mycena mushrooms +setting("number", "wormcha", 0.015) --chance of glow worms +setting("number", "giantcha", 0.001) --chance of giant mushrooms +setting("number", "icicha", 0.035) --chance of icicles +setting("number", "flacha", 0.04) --chance of constant flames + +--realm limits for Dungeon Masters' Lair +setting("number", "dm_top", -14000) --upper limit +setting("number", "dm_bot", -16000) --lower limit + +--should DMs spawn in DM Lair? +setting("bool", "dm_spawn", true) + +--Deep cave settings +setting("number", "deep_cave", -7000) -- upper limit diff --git a/mods/caverealms_lite/crafting.lua b/mods/caverealms_lite/crafting.lua new file mode 100644 index 0000000..52da277 --- /dev/null +++ b/mods/caverealms_lite/crafting.lua @@ -0,0 +1,145 @@ +--thin ice to water +minetest.register_craft({ + output = "default:water_source", + type = "shapeless", + recipe = {"caverealms:thin_ice"} +}) + +--use for coal dust +minetest.register_craft({ + output = "default:coalblock", + recipe = { + {"caverealms:coal_dust","caverealms:coal_dust","caverealms:coal_dust"}, + {"caverealms:coal_dust","caverealms:coal_dust","caverealms:coal_dust"}, + {"caverealms:coal_dust","caverealms:coal_dust","caverealms:coal_dust"} + } +}) + +-- DM statue +minetest.register_craft({ + output = "caverealms:dm_statue", + recipe = { + {"caverealms:glow_ore","caverealms:hot_cobble","caverealms:glow_ore"}, + {"caverealms:hot_cobble","caverealms:hot_cobble","caverealms:hot_cobble"}, + {"caverealms:hot_cobble","caverealms:hot_cobble","caverealms:hot_cobble"} + } +}) + +-- Glow obsidian brick +minetest.register_craft({ + output = "caverealms:glow_obsidian_brick 4", + recipe = { + {"caverealms:glow_obsidian", "caverealms:glow_obsidian"}, + {"caverealms:glow_obsidian", "caverealms:glow_obsidian"} + } +}) + +minetest.register_craft({ + output = "caverealms:glow_obsidian_brick_2 4", + recipe = { + {"caverealms:glow_obsidian_2", "caverealms:glow_obsidian_2"}, + {"caverealms:glow_obsidian_2", "caverealms:glow_obsidian_2"} + } +}) + +-- Glow obsidian glass +minetest.register_craft({ + output = "caverealms:glow_obsidian_glass 5", + recipe = { + {"default:glass", "default:glass", "default:glass"}, + {"default:glass", "default:glass", "caverealms:glow_obsidian"} + } +}) + +minetest.register_craft({ + output = "caverealms:glow_obsidian_glass 5", + recipe = { + {"default:glass", "default:glass", "default:glass"}, + {"default:glass", "default:glass", "caverealms:glow_obsidian_2"} + } +}) + +-- Requires ethereal:fish_raw +if minetest.get_modpath("ethereal") then + + -- Professional Fishing Rod + minetest.register_craftitem("caverealms:angler_rod", { + description = "Pro Fishing Rod", + inventory_image = "caverealms_angler_rod.png", + wield_image = "caverealms_angler_rod.png" + }) + + minetest.register_craft({ + output = "caverealms:angler_rod", + recipe = { + {"","","default:steel_ingot"}, + {"", "default:steel_ingot", "caverealms:mushroom_gills"}, + {"default:steel_ingot", "", "caverealms:mushroom_gills"}, + } + }) + + -- Glow Bait + minetest.register_craftitem("caverealms:glow_bait", { + description = "Glow Bait", + inventory_image = "caverealms_glow_bait.png", + wield_image = "caverealms_glow_bait.png", + }) + + minetest.register_craft({ + output = "caverealms:glow_bait 9", + recipe = { + {"caverealms:glow_worm_green"}, + } + }) + + -- default ethereal fish + local fish = { + {"ethereal:fish_raw"}, + } + + -- Pro Fishing Rod (Baited) + minetest.register_craftitem("caverealms:angler_rod_baited", { + description = "Baited Pro Fishing Rod", + inventory_image = "caverealms_angler_rod_baited.png", + wield_image = "caverealms_angler_rod_weild.png", + stack_max = 1, + liquids_pointable = true, + + on_use = function (itemstack, user, pointed_thing) + + if pointed_thing.type ~= "node" then + return + end + + local node = minetest.get_node(pointed_thing.under).name + + if (node == "default:water_source" + or node == "default:river_water_source") + and math.random(1, 100) < 35 then + + local type = fish[math.random(1, #fish)][1] + local inv = user:get_inventory() + + if inv:room_for_item("main", {name = type}) then + + inv:add_item("main", {name = type}) + + if (math.random() < 0.6) then + return ItemStack("caverealms:angler_rod_baited") + else + return ItemStack("caverealms:angler_rod") + end + else + minetest.chat_send_player(user:get_player_name(), + "Inventory full, Fish Got Away!") + end + end + end, + }) + + minetest.register_craft({ + type = "shapeless", + output = "caverealms:angler_rod_baited", + recipe = {"caverealms:angler_rod", "caverealms:glow_bait"}, + }) +end diff --git a/mods/caverealms_lite/docs/caverealms_lite_biomes.txt b/mods/caverealms_lite/docs/caverealms_lite_biomes.txt new file mode 100644 index 0000000..d1591ee --- /dev/null +++ b/mods/caverealms_lite/docs/caverealms_lite_biomes.txt @@ -0,0 +1,19 @@ +Biome #, Biome name, "floor node" + + +0, None +1, Moss, "caverealms:stone_with_moss" +2, Fungal, "caverealms:stone_with_lichen" +3, Algae, "caverealms:stone_with_algae" +4, Glaciated, "caverealms:thin_ice" + +The following are "deep realms" + +5, Deep Glaciated, "default:ice" +6, DM, "caverealms:hot_cobble" +7, Salt Crystal, "caverealms:stone_with_salt" +8, Glow Obsidian, "caverealms:glow_obsidian" + OR "caverealms:glow_obsidian2" +9, Coal, "default:coalblock" + OR "caverealms:coal_dust" + OR "default:desert_sand" diff --git a/mods/caverealms_lite/dungeon_master.lua b/mods/caverealms_lite/dungeon_master.lua new file mode 100644 index 0000000..e93ea8c --- /dev/null +++ b/mods/caverealms_lite/dungeon_master.lua @@ -0,0 +1,16 @@ +mobs:spawn({ + name = "mobs_monster:dungeon_master", + nodes = {"caverealms:hot_cobble"}, + max_light = 12, + min_light = 0, + chance = 7000, + active_object_count = 2, + max_height = -8000, + on_spawn = function(self, pos) + self.hp_max = 70 + self.health = 70 + self.damage = 5 + self.shoot_interval = 1.5 + self.dogshoot_switch = 0 + end +}) diff --git a/mods/caverealms_lite/functions.lua b/mods/caverealms_lite/functions.lua new file mode 100644 index 0000000..2be9e10 --- /dev/null +++ b/mods/caverealms_lite/functions.lua @@ -0,0 +1,409 @@ +local H_LAG = caverealms.config.h_lag --15 --max height for stalagmites +local H_LAC = caverealms.config.h_lac --20 --...stalactites +local H_CRY = caverealms.config.h_cry --9 --max height of glow crystals +local H_CLAC = caverealms.config.h_clac --13 --max height of glow crystal stalactites + +function caverealms:above_solid(x,y,z,area,data) + local c_air = minetest.get_content_id("air") + + local ai = area:index(x,y+1,z-3) + if data[ai] == c_air then + return false + else + return true + end +end + +function caverealms:below_solid(x,y,z,area,data) + local c_air = minetest.get_content_id("air") + + local ai = area:index(x,y-1,z-3) + if data[ai] == c_air then + return false + else + return true + end +end + +--stalagmite spawner +function caverealms:stalagmite(x,y,z, area, data) + + if not caverealms:below_solid(x,y,z,area,data) then + return + end + + --contest ids + local c_stone = minetest.get_content_id("default:stone") + + local top = math.random(6,H_LAG) --grab a random height for the stalagmite + for j = 0, top do --y + for k = -3, 3 do + for l = -3, 3 do + if j == 0 then + if k*k + l*l <= 9 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_stone + end + elseif j <= top/5 then + if k*k + l*l <= 4 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_stone + end + elseif j <= top/5 * 3 then + if k*k + l*l <= 1 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_stone + end + else + local vi = area:index(x, y+j, z-3) + data[vi] = c_stone + end + end + end + end +end + +--stalactite spawner +function caverealms:stalactite(x,y,z, area, data) + + if not caverealms:above_solid(x,y,z,area,data) then + return + end + + --contest ids + local c_stone = minetest.get_content_id("default:stone")--("caverealms:limestone") + + local bot = math.random(-H_LAC, -6) --grab a random height for the stalagmite + for j = bot, 0 do --y + for k = -3, 3 do + for l = -3, 3 do + if j >= -1 then + if k*k + l*l <= 9 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_stone + end + elseif j >= bot/5 then + if k*k + l*l <= 4 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_stone + end + elseif j >= bot/5 * 3 then + if k*k + l*l <= 1 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = c_stone + end + else + local vi = area:index(x, y+j, z-3) + data[vi] = c_stone + end + end + end + end +end + +--glowing crystal stalagmite spawner +function caverealms:crystal_stalagmite(x,y,z, area, data, biome) + + if not caverealms:below_solid(x,y,z,area,data) then + return + end + + --contest ids + local c_stone = minetest.get_content_id("default:stone") + local c_crystal = minetest.get_content_id("caverealms:glow_crystal") + local c_crystore = minetest.get_content_id("caverealms:glow_ore") + local c_emerald = minetest.get_content_id("caverealms:glow_emerald") + local c_emore = minetest.get_content_id("caverealms:glow_emerald_ore") + local c_mesecry = minetest.get_content_id("caverealms:glow_mese") + local c_meseore = minetest.get_content_id("default:stone_with_mese") + local c_ruby = minetest.get_content_id("caverealms:glow_ruby") + local c_rubore = minetest.get_content_id("caverealms:glow_ruby_ore") + local c_ameth = minetest.get_content_id("caverealms:glow_amethyst") + local c_amethore = minetest.get_content_id("caverealms:glow_amethyst_ore") + local c_ice = minetest.get_content_id("default:ice") + local c_thinice = minetest.get_content_id("caverealms:thin_ice") + + --for randomness + local mode = 1 + if math.random(15) == 1 then + mode = 2 + end + if biome == 3 then + if math.random(25) == 1 then + mode = 2 + else + mode = 1 + end + end + if biome == 4 or biome == 5 then + if math.random(3) == 1 then + mode = 2 + end + end + + local stalids = { + { {c_crystore, c_crystal}, {c_emore, c_emerald} }, + { {c_emore, c_emerald}, {c_crystore, c_crystal} }, + { {c_emore, c_emerald}, {c_meseore, c_mesecry} }, + { {c_ice, c_thinice}, {c_crystore, c_crystal}}, + { {c_ice, c_thinice}, {c_crystore, c_crystal}}, + { {c_rubore, c_ruby}, {c_meseore, c_mesecry}}, + { {c_crystore, c_crystal}, {c_rubore, c_ruby} }, + { {c_rubore, c_ruby}, {c_emore, c_emerald}}, + { {c_amethore, c_ameth}, {c_meseore, c_mesecry} }, + } + + local nid_a + local nid_b + local nid_s = c_stone --stone base, will be rewritten to ice in certain biomes + + if biome > 3 and biome < 6 then + if mode == 1 then + nid_a = c_ice + nid_b = c_thinice + nid_s = c_ice + else + nid_a = c_crystore + nid_b = c_crystal + end + elseif mode == 1 then + nid_a = stalids[biome][1][1] + nid_b = stalids[biome][1][2] + else + nid_a = stalids[biome][2][1] + nid_b = stalids[biome][2][2] + end + + local top = math.random(5,H_CRY) --grab a random height for the stalagmite + for j = 0, top do --y + for k = -3, 3 do + for l = -3, 3 do + if j == 0 then + if k*k + l*l <= 9 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = nid_s + end + elseif j <= top/5 then + if k*k + l*l <= 4 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = nid_a + end + elseif j <= top/5 * 3 then + if k*k + l*l <= 1 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = nid_b + end + else + local vi = area:index(x, y+j, z-3) + data[vi] = nid_b + end + end + end + end +end + +--crystal stalactite spawner +function caverealms:crystal_stalactite(x,y,z, area, data, biome) + + if not caverealms:above_solid(x,y,z,area,data) then + return + end + + --contest ids + local c_stone = minetest.get_content_id("default:stone") + local c_crystore = minetest.get_content_id("caverealms:glow_ore") + local c_crystal = minetest.get_content_id("caverealms:glow_crystal") + local c_emerald = minetest.get_content_id("caverealms:glow_emerald") + local c_emore = minetest.get_content_id("caverealms:glow_emerald_ore") + local c_mesecry = minetest.get_content_id("caverealms:glow_mese") + local c_meseore = minetest.get_content_id("default:stone_with_mese") + local c_ruby = minetest.get_content_id("caverealms:glow_ruby") + local c_rubore = minetest.get_content_id("caverealms:glow_ruby_ore") + local c_ameth = minetest.get_content_id("caverealms:glow_amethyst") + local c_amethore = minetest.get_content_id("caverealms:glow_amethyst_ore") + local c_ice = minetest.get_content_id("default:ice") + local c_thinice = minetest.get_content_id("caverealms:hanging_thin_ice") + + --for randomness + local mode = 1 + if math.random(15) == 1 then + mode = 2 + end + if biome == 3 then + if math.random(25) == 1 then + mode = 2 + else + mode = 1 + end + end + if biome == 4 or biome == 5 then + if math.random(3) == 1 then + mode = 2 + end + end + + local stalids = { + { {c_crystore, c_crystal}, {c_emore, c_emerald} }, + { {c_emore, c_emerald}, {c_crystore, c_crystal} }, + { {c_emore, c_emerald}, {c_meseore, c_mesecry} }, + { {c_ice, c_thinice}, {c_crystore, c_crystal}}, + { {c_ice, c_thinice}, {c_crystore, c_crystal}}, + { {c_rubore, c_ruby}, {c_meseore, c_mesecry}}, + { {c_crystore, c_crystal}, {c_rubore, c_ruby} }, + { {c_rubore, c_ruby}, {c_emore, c_emerald}}, + { {c_amethore, c_ameth}, {c_meseore, c_mesecry} }, + } + + local nid_a + local nid_b + local nid_s = c_stone --stone base, will be rewritten to ice in certain biomes + + if biome > 3 and biome < 6 then + if mode == 1 then + nid_a = c_ice + nid_b = c_thinice + nid_s = c_ice + else + nid_a = c_crystore + nid_b = c_crystal + end + elseif mode == 1 then + nid_a = stalids[biome][1][1] + nid_b = stalids[biome][1][2] + else + nid_a = stalids[biome][2][1] + nid_b = stalids[biome][2][2] + end + + local bot = math.random(-H_CLAC, -6) --grab a random height for the stalagmite + for j = bot, 0 do --y + for k = -3, 3 do + for l = -3, 3 do + if j >= -1 then + if k*k + l*l <= 9 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = nid_s + end + elseif j >= bot/5 then + if k*k + l*l <= 4 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = nid_a + end + elseif j >= bot/5 * 3 then + if k*k + l*l <= 1 then + local vi = area:index(x+k, y+j, z+l-3) + data[vi] = nid_b + end + else + local vi = area:index(x, y+j, z-3) + data[vi] = nid_b + end + end + end + end +end + +--glowing crystal stalagmite spawner +function caverealms:salt_stalagmite(x,y,z, area, data, biome) + + if not caverealms:below_solid(x,y,z,area,data) then + return + end + + --contest ids + local c_stone = minetest.get_content_id("default:stone") + local c_salt = minetest.get_content_id("caverealms:salt_crystal") + + local scale = math.random(2, 4) + if scale == 2 then + for j = -3, 3 do + for k = -3, 3 do + local vi = area:index(x+j, y, z+k) + data[vi] = c_stone + if math.abs(j) ~= 3 and math.abs(k) ~= 3 then + local vi = area:index(x+j, y+1, z+k) + data[vi] = c_stone + end + end + end + else + for j = -4, 4 do + for k = -4, 4 do + local vi = area:index(x+j, y, z+k) + data[vi] = c_stone + if math.abs(j) ~= 4 and math.abs(k) ~= 4 then + local vi = area:index(x+j, y+1, z+k) + data[vi] = c_stone + end + end + end + end + for j = 2, scale + 2 do --y + for k = -2, scale - 2 do + for l = -2, scale - 2 do + local vi = area:index(x+k, y+j, z+l) + data[vi] = c_salt -- make cube + end + end + end +end + +--function to create giant 'shrooms +function caverealms:giant_shroom(x, y, z, area, data) + + if not caverealms:below_solid(x,y,z,area,data) then + return + end + + local c_cap + local c_stem + + --as usual, grab the content ID's + if minetest.get_modpath("ethereal") then + c_stem = minetest.get_content_id("ethereal:mushroom_trunk") + c_cap = minetest.get_content_id("ethereal:mushroom") + else + c_stem = minetest.get_content_id("caverealms:mushroom_stem") + c_cap = minetest.get_content_id("caverealms:mushroom_cap") + end + + local c_gills = minetest.get_content_id("caverealms:mushroom_gills") + + z = z - 5 + --cap + for k = -5, 5 do + for l = -5, 5 do + if k*k + l*l <= 25 then + local vi = area:index(x+k, y+5, z+l) + data[vi] = c_cap + end + if k*k + l*l <= 16 then + local vi = area:index(x+k, y+6, z+l) + data[vi] = c_cap + vi = area:index(x+k, y+5, z+l) + data[vi] = c_gills + end + if k*k + l*l <= 9 then + local vi = area:index(x+k, y+7, z+l) + data[vi] = c_cap + end + if k*k + l*l <= 4 then + local vi = area:index(x+k, y+8, z+l) + data[vi] = c_cap + end + end + end + --stem + for j = 0, 5 do + for k = -1,1 do + local vi = area:index(x+k, y+j, z) + data[vi] = c_stem + if k == 0 then + local ai = area:index(x, y+j, z+1) + data[ai] = c_stem + ai = area:index(x, y+j, z-1) + data[ai] = c_stem + end + end + end +end diff --git a/mods/caverealms_lite/init.lua b/mods/caverealms_lite/init.lua new file mode 100644 index 0000000..5cc8a2c --- /dev/null +++ b/mods/caverealms_lite/init.lua @@ -0,0 +1,333 @@ +caverealms = {} --create a container for functions and constants + +--grab a shorthand for the filepath of the mod +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +--load companion lua files +dofile(modpath.."/config.lua") --configuration file; holds various constants +dofile(modpath.."/crafting.lua") --crafting recipes +dofile(modpath.."/nodes.lua") --node definitions +dofile(modpath.."/functions.lua") --function definitions +dofile(modpath.."/plants.lua") + +if minetest.get_modpath("mobs_monster") then + if caverealms.config.dm_spawn == true then + dofile(modpath.."/dungeon_master.lua") --special DMs for DM's Lair biome + end +end + +-- Parameters + +local YMIN = caverealms.config.ymin -- Approximate realm limits. +local YMAX = caverealms.config.ymax +local TCAVE = caverealms.config.tcave --0.5 -- Cave threshold. 1 = small rare caves, 0.5 = 1/3rd ground volume, 0 = 1/2 ground volume +local BLEND = 128 -- Cave blend distance near YMIN, YMAX + +local STAGCHA = caverealms.config.stagcha --0.002 --chance of stalagmites +local STALCHA = caverealms.config.stalcha --0.003 --chance of stalactites +local CRYSTAL = caverealms.config.crystal --0.007 --chance of glow crystal formations +local GEMCHA = caverealms.config.gemcha --0.03 --chance of small glow gems +local MUSHCHA = caverealms.config.mushcha --0.04 --chance of mushrooms +local MYCCHA = caverealms.config.myccha --0.03 --chance of mycena mushrooms +local WORMCHA = caverealms.config.wormcha --0.03 --chance of glow worms +local GIANTCHA = caverealms.config.giantcha --0.001 -- chance of giant mushrooms +local ICICHA = caverealms.config.icicha --0.035 -- chance of icicles +local FLACHA = caverealms.config.flacha --0.04 --chance of constant flames + +local DM_TOP = caverealms.config.dm_top -- -4000 --level at which Dungeon Master Realms start to appear +local DM_BOT = caverealms.config.dm_bot -- -5000 --level at which "" ends +local DEEP_CAVE = caverealms.config.deep_cave -- -7000 --level at which deep cave biomes take over + +-- 2D noise for biome + +local np_biome = { + offset = 0, + scale = 1, + spread = {x=200, y=200, z=200}, + seed = 9130, + octaves = 3, + persist = 0.5 +} + +-- Stuff + +subterrain = {} + + +-- On generated function + +minetest.register_on_generated(function(minp, maxp, seed) + --if out of range of caverealms limits + if minp.y > YMAX or maxp.y < YMIN then + return --quit; otherwise, you'd have stalagmites all over the place + end + + --easy reference to commonly used values + local t1 = os.clock() + local x1 = maxp.x + local y1 = maxp.y + local z1 = maxp.z + local x0 = minp.x + local y0 = minp.y + local z0 = minp.z + + --print ("[caverealms] chunk minp ("..x0.." "..y0.." "..z0..")") --tell people you are generating a chunk + + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + local data = vm:get_data() + + --grab content IDs + local c_air = minetest.get_content_id("air") + local c_stone = minetest.get_content_id("default:stone") + + local c_water = minetest.get_content_id("default:water_source") + local c_lava = minetest.get_content_id("default:lava_source") + local c_ice = minetest.get_content_id("default:ice") + local c_thinice = minetest.get_content_id("caverealms:thin_ice") + local c_crystal = minetest.get_content_id("caverealms:glow_crystal") + local c_gem = minetest.get_content_id("caverealms:glow_gem") + local c_saltgem = minetest.get_content_id("caverealms:salt_gem") + local c_spike = minetest.get_content_id("caverealms:spike") + local c_moss = minetest.get_content_id("caverealms:stone_with_moss") + local c_lichen = minetest.get_content_id("caverealms:stone_with_lichen") + local c_algae = minetest.get_content_id("caverealms:stone_with_algae") + local c_salt = minetest.get_content_id("caverealms:stone_with_salt") + local c_hcobble = minetest.get_content_id("caverealms:hot_cobble") + local c_gobsidian = minetest.get_content_id("caverealms:glow_obsidian") + local c_gobsidian2 = minetest.get_content_id("caverealms:glow_obsidian_2") + local c_coalblock = minetest.get_content_id("default:coalblock") + local c_desand = minetest.get_content_id("default:desert_sand") + local c_coaldust = minetest.get_content_id("caverealms:coal_dust") + local c_fungus = minetest.get_content_id("caverealms:fungus") + local c_mycena = minetest.get_content_id("caverealms:mycena") + local c_worm = minetest.get_content_id("caverealms:glow_worm") + local c_worm_green = minetest.get_content_id("caverealms:glow_worm_green") + local c_fire_vine = minetest.get_content_id("caverealms:fire_vine") + local c_iciu = minetest.get_content_id("caverealms:icicle_up") + local c_icid = minetest.get_content_id("caverealms:icicle_down") + local c_flame = minetest.get_content_id("caverealms:constant_flame") + + --mandatory values + local sidelen = x1 - x0 + 1 --length of a mapblock + local chulens = {x=sidelen, y=sidelen, z=sidelen} --table of chunk edges + local chulens2D = {x=sidelen, y=sidelen, z=1} + local minposxyz = {x=x0, y=y0, z=z0} --bottom corner + local minposxz = {x=x0, y=z0} --2D bottom corner + + local nvals_biome = minetest.get_perlin_map(np_biome, chulens2D):get2dMap_flat({x=x0+150, y=z0+50}) --2D noise for biomes (will be 3D humidity/temp later) + + local nixyz = 1 --3D node index + local nixz = 1 --2D node index + local nixyz2 = 1 --second 3D index for second loop + + + for z = z0, z1 do -- for each xy plane progressing northwards + --increment indices + nixyz = nixyz + 1 + + + --decoration loop + for y = y0, y1 do -- for each x row progressing upwards + + local c_selected_worm = c_worm + + local is_deep = false + if y < DEEP_CAVE then + is_deep = true + end + + + local vi = area:index(x0, y, z) + for x = x0, x1 do -- for each node do + + --determine biome + local biome = 0 --preliminary declaration + local n_biome = nvals_biome[nixz] --make an easier reference to the noise + + --compare noise values to determine a biome + if n_biome <= -0.5 then + if is_deep and n_biome <= -0.25 then + biome = 8 --glow obsidian + else + biome = 2 --fungal + c_selected_worm = c_worm_green + end + + elseif n_biome < 0 then + biome = 0 -- none + + elseif n_biome < 0.5 then + if is_deep and n_biome <= 0.25 then + biome = 7 --salt crystal + else + biome = 1 --moss + end + + elseif n_biome < 0.65 then + biome = 0 + + elseif n_biome < 0.85 then + if is_deep and n_biome <= 0.75 then + biome = 9 --coal dust + else + biome = 3 --algae + c_selected_worm = c_worm_green + end + + else + if is_deep and n_biome <= .95 then + biome = 5 --deep glaciated + else + biome = 4 --glaciated + end + end + + --print(biome) + + if biome > 0 then + if y <= DM_TOP and y >= DM_BOT then + biome = 6 --DUNGEON MASTER'S LAIR + c_selected_worm = c_fire_vine + end + + --ceiling + local ai = area:index(x,y+1,z) --above index + if data[ai] == c_stone and data[vi] == c_air then --ceiling + if math.random() < ICICHA and (biome == 4 or biome == 5) then + data[vi] = c_icid + end + if math.random() < WORMCHA then + data[vi] = c_selected_worm + local bi = area:index(x,y-1,z) + data[bi] = c_selected_worm + if math.random(2) == 1 then + local bbi = area:index(x,y-2,z) + data[bbi] = c_selected_worm + if math.random(2) ==1 then + local bbbi = area:index(x,y-3,z) + data[bbbi] = c_selected_worm + end + end + end + if math.random() < STALCHA then + caverealms:stalactite(x,y,z, area, data) + end + if math.random() < CRYSTAL then + caverealms:crystal_stalactite(x,y,z, area, data, biome) + end + end + --ground + local bi = area:index(x,y-1,z) --below index + if data[bi] == c_stone and data[vi] == c_air then --ground + local ai = area:index(x,y+1,z) + --place floor material, add plants/decorations + if biome == 1 then + data[vi] = c_moss + if math.random() < GEMCHA then + data[ai] = c_gem + end + elseif biome == 2 then + data[vi] = c_lichen + if math.random() < MUSHCHA then --mushrooms + data[ai] = c_fungus + end + if math.random() < MYCCHA then --mycena mushrooms + data[ai] = c_mycena + end + if math.random() < GIANTCHA then --giant mushrooms + caverealms:giant_shroom(x, y, z, area, data) + end + elseif biome == 3 then + data[vi] = c_algae + elseif biome == 4 then + data[vi] = c_thinice + local bi = area:index(x,y-1,z) + data[bi] = c_thinice + if math.random() < ICICHA then --if glaciated, place icicles + data[ai] = c_iciu + end + elseif biome == 5 then + data[vi] = c_ice + local bi = area:index(x,y-1,z) + data[bi] = c_ice + if math.random() < ICICHA then --if glaciated, place icicles + data[ai] = c_iciu + end + elseif biome == 6 then + data[vi] = c_hcobble + if math.random() < FLACHA then --neverending flames + data[ai] = c_flame + end + elseif biome == 7 then + local bi = area:index(x,y-1,z) + data[vi] = c_salt + data[bi] = c_salt + if math.random() < GEMCHA then + data[ai] = c_saltgem + end + if math.random() < STAGCHA then + caverealms:salt_stalagmite(x,y,z, area, data) + end + elseif biome == 8 then + local bi = area:index(x,y-1,z) + if math.random() < 0.5 then + data[vi] = c_gobsidian + data[bi] = c_gobsidian + else + data[vi] = c_gobsidian2 + data[bi] = c_gobsidian2 + end + if math.random() < FLACHA then --neverending flames + data[ai] = c_flame + end + elseif biome == 9 then + local bi = area:index(x,y-1,z) + if math.random() < 0.05 then + data[vi] = c_coalblock + data[bi] = c_coalblock + elseif math.random() < 0.15 then + data[vi] = c_coaldust + data[bi] = c_coaldust + else + data[vi] = c_desand + data[bi] = c_desand + end + if math.random() < FLACHA * 0.75 then --neverending flames + data[ai] = c_flame + end + if math.random() < GEMCHA then + data[ai] = c_spike + end + end + + if math.random() < STAGCHA then + caverealms:stalagmite(x,y,z, area, data) + end + if math.random() < CRYSTAL then + caverealms:crystal_stalagmite(x,y,z, area, data, biome) + end + end + + end + nixyz2 = nixyz2 + 1 + nixz = nixz + 1 + vi = vi + 1 + end + nixz = nixz - sidelen --shift the 2D index back + end + nixz = nixz + sidelen --shift the 2D index up a layer + end + + --send data back to voxelmanip + vm:set_data(data) + --calc lighting + vm:set_lighting({day=0, night=0}) + vm:calc_lighting() + --write it to world + vm:write_to_map(data) + + --local chugent = math.ceil((os.clock() - t1) * 1000) --grab how long it took + --print ("[caverealms] "..chugent.." ms") --tell people how long +end) +print("[caverealms] loaded!") diff --git a/mods/caverealms_lite/license.txt b/mods/caverealms_lite/license.txt new file mode 100644 index 0000000..6e9767f --- /dev/null +++ b/mods/caverealms_lite/license.txt @@ -0,0 +1,26 @@ +Copyright (c) 2017, Craig Robbins and contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those +of the authors and should not be interpreted as representing official policies, +either expressed or implied, of the FreeBSD Project. diff --git a/mods/caverealms_lite/mod.conf b/mods/caverealms_lite/mod.conf new file mode 100644 index 0000000..30200dd --- /dev/null +++ b/mods/caverealms_lite/mod.conf @@ -0,0 +1,4 @@ +name = caverealms +depends = default, stairs +optional_depends = ethereal, mobs +description = A mod for Minetest to add underground realms. diff --git a/mods/caverealms_lite/nodes.lua b/mods/caverealms_lite/nodes.lua new file mode 100644 index 0000000..9198a94 --- /dev/null +++ b/mods/caverealms_lite/nodes.lua @@ -0,0 +1,522 @@ +--glowing crystal +minetest.register_node("caverealms:glow_crystal", { + description = "Glow Sapphire", + tiles = {"caverealms_glow_crystal.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + light_source = 13, + paramtype = "light", + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, +}) + +--glowing emerald +minetest.register_node("caverealms:glow_emerald", { + description = "Glow Emerald", + tiles = {"caverealms_glow_emerald.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + light_source = 13, + paramtype = "light", + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, +}) + +--glowing mese crystal blocks +minetest.register_node("caverealms:glow_mese", { + description = "Glow Mese Crystal", + tiles = {"caverealms_glow_mese.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + light_source = 13, + paramtype = "light", + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, +}) + +--glowing ruby +minetest.register_node("caverealms:glow_ruby", { + description = "Glow Ruby", + tiles = {"caverealms_glow_ruby.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + light_source = 13, + paramtype = "light", + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, +}) + +--glowing amethyst +minetest.register_node("caverealms:glow_amethyst", { + description = "Glow Amethyst", + tiles = {"caverealms_glow_amethyst.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + light_source = 13, + paramtype = "light", + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, +}) + +--embedded crystal +minetest.register_node("caverealms:glow_ore", { + description = "Glow Crystal Ore", + tiles = {"caverealms_glow_ore.png"}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_glass_defaults(), + light_source = 10, + paramtype = "light", +}) + +--embedded emerald +minetest.register_node("caverealms:glow_emerald_ore", { + description = "Glow Emerald Ore", + tiles = {"caverealms_glow_emerald_ore.png"}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_glass_defaults(), + light_source = 10, + paramtype = "light", +}) + +--embedded ruby +minetest.register_node("caverealms:glow_ruby_ore", { + description = "Glow Ruby Ore", + tiles = {"caverealms_glow_ruby_ore.png"}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_glass_defaults(), + light_source = 10, + paramtype = "light", +}) + +--embedded amethyst +minetest.register_node("caverealms:glow_amethyst_ore", { + description = "Glow Amethyst Ore", + tiles = {"caverealms_glow_amethyst_ore.png"}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_glass_defaults(), + light_source = 10, + paramtype = "light", +}) + +--thin (transparent) ice +minetest.register_node("caverealms:thin_ice", { + description = "Thin Ice", + tiles = {"caverealms_thin_ice.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, + freezemelt = "default:water_source", + paramtype = "light", +}) + +--salt crystal +minetest.register_node("caverealms:salt_crystal", { + description = "Salt Crystal", + tiles = {"caverealms_salt_crystal.png"}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_glass_defaults(), + light_source = 11, + paramtype = "light", + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, +}) + +--glowing crystal gem +minetest.register_node("caverealms:glow_gem", { + description = "Glow Gem", + tiles = {"caverealms_glow_gem.png"}, + inventory_image = "caverealms_glow_gem.png", + wield_image = "caverealms_glow_gem.png", + is_ground_content = true, + groups = {cracky = 3, oddly_breakable_by_hand = 1, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), + light_source = 11, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 0.75, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + } +}) + +--glowing salt gem +minetest.register_node("caverealms:salt_gem", { + description = "Salt Gem", + tiles = {"caverealms_salt_gem.png"}, + inventory_image = "caverealms_salt_gem.png", + wield_image = "caverealms_salt_gem.png", + is_ground_content = true, + groups = {cracky = 3, oddly_breakable_by_hand = 1, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), + light_source = 11, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 0.75, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + } +}) + +--stone spike +minetest.register_node("caverealms:spike", { + description = "Stone Spike", + tiles = {"caverealms_spike.png"}, + inventory_image = "caverealms_spike.png", + wield_image = "caverealms_spike.png", + is_ground_content = true, + groups = {cracky = 3, oddly_breakable_by_hand = 1, attached_node = 1}, + sounds = default.node_sound_stone_defaults(), + light_source = 3, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 0.75, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + } +}) + + +--upward pointing icicle +minetest.register_node("caverealms:icicle_up", { + description = "Icicle", + tiles = {"caverealms_icicle_up.png"}, + inventory_image = "caverealms_icicle_up.png", + wield_image = "caverealms_icicle_up.png", + is_ground_content = true, + groups = {cracky=3, oddly_breakable_by_hand=1}, + sounds = default.node_sound_glass_defaults(), + light_source = 8, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -7/16, 0.5}, + }, +}) + +--downward pointing icicle +minetest.register_node("caverealms:icicle_down", { + description = "Icicle", + tiles = {"caverealms_icicle_down.png"}, + inventory_image = "caverealms_icicle_down.png", + wield_image = "caverealms_icicle_down.png", + is_ground_content = true, + groups = {cracky=3, oddly_breakable_by_hand=1}, + sounds = default.node_sound_glass_defaults(), + light_source = 8, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-0.5, 7/16, -0.5, 0.5, 0.5, 0.5}, + }, +}) + +--cave mossy cobble - bluish? +minetest.register_node("caverealms:stone_with_moss", { + description = "Cave Stone with Moss", + tiles = {"default_cobble.png^caverealms_moss.png", "default_cobble.png", "default_cobble.png^caverealms_moss_side.png"}, + is_ground_content = true, + groups = {crumbly=1, cracky=3}, + drop = 'default:cobble', + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +--cave lichen-covered cobble - purple-ish +minetest.register_node("caverealms:stone_with_lichen", { + description = "Cave Stone with Lichen", + tiles = {"default_cobble.png^caverealms_lichen.png", "default_cobble.png", "default_cobble.png^caverealms_lichen_side.png"}, + is_ground_content = true, + groups = {crumbly=1, cracky=3}, + drop = 'default:cobble', + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +--cave algae-covered cobble - yellow-ish +minetest.register_node("caverealms:stone_with_algae", { + description = "Cave Stone with Algae", + tiles = {"default_cobble.png^caverealms_algae.png", "default_cobble.png", "default_cobble.png^caverealms_algae_side.png"}, + is_ground_content = true, + groups = {crumbly=1, cracky=3}, + drop = 'default:cobble', + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +--tiny-salt-crystal-covered cobble - pink-ish +minetest.register_node("caverealms:stone_with_salt", { + description = "Salt Crystal", + tiles = {"caverealms_salty2.png"}, + light_source = 9, + paramtype = "light", + use_texture_alpha = true, + drawtype = "glasslike", + sunlight_propagates = true, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_glass_defaults(), +}) + +--Hot Cobble - cobble with lava instead of mortar XD +minetest.register_node("caverealms:hot_cobble", { + description = "Hot Cobble", + tiles = {"caverealms_hot_cobble.png"}, + is_ground_content = true, + groups = {cracky=1, hot=1, unbreakable = 1}, + damage_per_second = 1, + light_source = 3, + paramtype = "light", + sounds = default.node_sound_stone_defaults({ + footstep = {name="default_stone_footstep", gain=0.25}, + }), +}) + +--Glow Obsidian +minetest.register_node("caverealms:glow_obsidian", { + description = "Glowing Obsidian", + tiles = {"caverealms_glow_obsidian.png"}, + is_ground_content = true, + groups = {cracky=1, level=2}, + light_source = 7, + paramtype = "light", + sounds = default.node_sound_stone_defaults({ + footstep = {name="default_stone_footstep", gain=0.25}, + }), +}) + +--Glow Obsidian 2 - has traces of lava +minetest.register_node("caverealms:glow_obsidian_2", { + description = "Hot Glowing Obsidian", + tiles = {"caverealms_glow_obsidian2.png"}, + is_ground_content = true, + groups = {cracky=1, hot=1, level=2}, + light_source = 9, + paramtype = "light", + sounds = default.node_sound_stone_defaults({ + footstep = {name="default_stone_footstep", gain=0.25}, + }), +}) + +--Glow Obsidian Bricks +minetest.register_node("caverealms:glow_obsidian_brick", { + description = "Glow Obsidian Brick", + tiles = {"caverealms_glow_obsidian_brick.png"}, + light_source = 7, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("caverealms:glow_obsidian_brick_2", { + description = "Glow Obsidian Brick", + tiles = {"caverealms_glow_obsidian_brick_2.png"}, + light_source = 9, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +--Glow Obsidian Stairs/Slabs +stairs.register_stair_and_slab( + "glow_obsidian_brick", + "caverealms:glow_obsidian_brick", + {cracky = 1, level = 2}, + {"caverealms_glow_obsidian_brick.png"}, + "Glow Obsidian Brick Stair", + "Glow Obsidian Brick Slab", + default.node_sound_stone_defaults()) + +stairs.register_stair_and_slab( + "glow_obsidian_brick_2", + "caverealms:glow_obsidian_brick_2", + {cracky = 1, level = 2}, + {"caverealms_glow_obsidian_brick_2.png"}, + "Glow Obsidian Brick Stair", + "Glow Obsidian Brick Slab", + default.node_sound_stone_defaults()) + +--Glow Obsidian Glass +minetest.register_node("caverealms:glow_obsidian_glass", { + description = "Glow Obsidian Glass", + drawtype = "glasslike_framed_optional", + tiles = {"caverealms_glow_obsidian_glass.png", "default_obsidian_glass_detail.png"}, + paramtype = "light", + light_source = 13, + sunlight_propagates = true, + groups = {cracky = 3}, + sounds = default.node_sound_glass_defaults(), +}) + +--Coal Dust +minetest.register_node("caverealms:coal_dust", { + description = "Coal Dust", + tiles = {"caverealms_coal_dust.png"}, + is_ground_content = true, + groups = {crumbly=3, falling_node=1, sand=1}, + sounds = default.node_sound_sand_defaults(), +}) + +--glow worms +minetest.register_node("caverealms:glow_worm", { + description = "Blue Glow Worms", + tiles = {"caverealms_glow_worm.png"}, + inventory_image = "caverealms_glow_worm.png", + wield_image = "caverealms_glow_worm.png", + is_ground_content = true, + groups = {oddly_breakable_by_hand=3}, + light_source = 9, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-1/6, -1/2, -1/6, 1/6, 1/2, 1/6}, + }, +}) + +minetest.register_node("caverealms:glow_worm_green", { + description = "Green Glow Worms", + tiles = {"caverealms_glow_worm_green.png"}, + inventory_image = "caverealms_glow_worm_green.png", + wield_image = "caverealms_glow_worm_green.png", + is_ground_content = true, + groups = {oddly_breakable_by_hand=3}, + light_source = 9, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-1/6, -1/2, -1/6, 1/6, 1/2, 1/6}, + }, +}) + +minetest.register_node("caverealms:fire_vine", { + description = "Fire Vine", + tiles = {"caverealms_fire_vine.png"}, + inventory_image = "caverealms_fire_vine.png", + wield_image = "caverealms_fire_vine.png", + is_ground_content = true, + damage_per_second = 1, + groups = {oddly_breakable_by_hand=3}, + light_source = 9, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-1/6, -1/2, -1/6, 1/6, 1/2, 1/6}, + }, +}) + + +--define special flame so that it does not expire +minetest.register_node("caverealms:constant_flame", { + description = "Fire", + drawtype = "plantlike", + tiles = {{ + name="fire_basic_flame_animated.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1}, + }}, + inventory_image = "fire_basic_flame.png", + light_source = 14, + groups = {igniter=2, dig_immediate=3, hot=3, not_in_creative_inventory=1}, + paramtype = "light", + drop = '', + walkable = false, + buildable_to = true, + damage_per_second = 4, +}) + +--dungeon master statue (nodebox) +minetest.register_node("caverealms:dm_statue", { + description = "Dungeon Master Statue", + tiles = { + "caverealms_dm_stone.png", + "caverealms_dm_stone.png", + "caverealms_dm_stone.png", + "caverealms_dm_stone.png", + "caverealms_dm_stone.png", + "caverealms_stone_eyes.png" + }, + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + groups = {cracky=2}, + node_box = { + type = "fixed", + fixed = { + {-0.4375, -0.5, -0.4375, 0.4375, -0.3125, 0.4375}, -- NodeBox1 + {-0.25, -0.125, -0.1875, 0.25, 0.5, 0.1875}, -- NodeBox2 + {-0.375, 0, -0.125, -0.25, 0.4375, 0.125}, -- NodeBox3 + {0.25, 0.125, -0.4375, 0.375, 0.375, 0.1875}, -- NodeBox4 + {-0.25, -0.5, -0.125, -0.125, -0.125, 0.125}, -- NodeBox5 + {0.125, -0.3125, -0.125, 0.25, 0, 0.125}, -- NodeBox6 + } + }, + selection_box = { + type = "regular" + } +}) + + +-- Compatibility +minetest.register_alias("caverealms:hanging_thin_ice", "caverealms:thin_ice") + +minetest.register_alias("caverealms:spike_2", "caverealms:spike") +minetest.register_alias("caverealms:spike_3", "caverealms:spike") +minetest.register_alias("caverealms:spike_4", "caverealms:spike") +minetest.register_alias("caverealms:spike_5", "caverealms:spike") + +minetest.register_alias("caverealms:salt_gem_2", "caverealms:salt_gem") +minetest.register_alias("caverealms:salt_gem_3", "caverealms:salt_gem") +minetest.register_alias("caverealms:salt_gem_4", "caverealms:salt_gem") +minetest.register_alias("caverealms:salt_gem_5", "caverealms:salt_gem") + +minetest.register_alias("caverealms:glow_gem_2", "caverealms:glow_gem") +minetest.register_alias("caverealms:glow_gem_3", "caverealms:glow_gem") +minetest.register_alias("caverealms:glow_gem_4", "caverealms:glow_gem") +minetest.register_alias("caverealms:glow_gem_5", "caverealms:glow_gem") diff --git a/mods/caverealms_lite/plants.lua b/mods/caverealms_lite/plants.lua new file mode 100644 index 0000000..1ebeff7 --- /dev/null +++ b/mods/caverealms_lite/plants.lua @@ -0,0 +1,188 @@ +-- Lichen biome + +-- glowing fungi +minetest.register_node("caverealms:fungus", { + description = "Glowing Fungus", + tiles = {"caverealms_fungi.png"}, + inventory_image = "caverealms_fungi.png", + wield_image = "caverealms_fungi.png", + is_ground_content = true, + groups = {oddly_breakable_by_hand = 3, attached_node = 1}, + light_source = 5, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + }, +}) + +-- mycena mushroom +minetest.register_node("caverealms:mycena", { + description = "Mycena Mushroom", + tiles = {"caverealms_mycena.png"}, + inventory_image = "caverealms_mycena.png", + wield_image = "caverealms_mycena.png", + is_ground_content = true, + groups = {oddly_breakable_by_hand = 3, attached_node = 1}, + light_source = 6, + paramtype = "light", + drawtype = "plantlike", + walkable = false, + buildable_to = true, + visual_scale = 1.0, + selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}, + }, +}) + +-- giant mushroom +if minetest.get_modpath("ethereal") then + minetest.register_alias("caverealms:mushroom_cap", "ethereal:mushroom") + minetest.register_alias("caverealms:mushroom_stem", "ethereal:mushroom_trunk") +else + -- stem + minetest.register_node("caverealms:mushroom_stem", { + description = "Giant Mushroom Stem", + tiles = {"caverealms_mushroom_stem.png"}, + is_ground_content = true, + groups = {choppy=2, oddly_breakable_by_hand=1}, + }) + + -- cap + minetest.register_node("caverealms:mushroom_cap", { + description = "Giant Mushroom Cap", + tiles = {"caverealms_mushroom_cap.png"}, + is_ground_content = true, + groups = {choppy=2, oddly_breakable_by_hand=1,}, + drop = { + max_items = 1, + items = { + {items = {"caverealms:mushroom_sapling"}, rarity = 20}, + {items = {"caverealms:mushroom_cap"}} + } + }, + }) + + -- sapling + minetest.register_node("caverealms:mushroom_sapling", { + description = "Mushroom Tree Sapling", + drawtype = "plantlike", + tiles = {"caverealms_mushroom_sapling.png"}, + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2}, + sounds = default.node_sound_leaves_defaults(), + }) +end + +-- gills +minetest.register_node("caverealms:mushroom_gills", { + description = "Giant Mushroom Gills", + tiles = {"caverealms_mushroom_gills.png"}, + is_ground_content = true, + light_source = 10, + groups = {choppy=2, oddly_breakable_by_hand=1}, + drawtype = "plantlike", + paramtype = "light", +}) + + +-- Saplings + +-- grow trees +local add_tree = function (pos, ofx, ofy, ofz, schem) + if not schem then + print ("Schematic not found") + return + end + minetest.swap_node(pos, {name = "air"}) + minetest.place_schematic( + {x = pos.x - ofx, y = pos.y - ofy, z = pos.z - ofz}, + schem, 0, nil, false) +end + +local path = minetest.get_modpath("caverealms").."/schematics/" + +-- giant mushrooms +function grow_caverealms_mushroom(pos) + add_tree(pos, 5, 0, 5, path .. "shroom.mts") +end + +-- height check +local function enough_height(pos, height) + local nod = minetest.line_of_sight( + {x = pos.x, y = pos.y + 1, z = pos.z}, + {x = pos.x, y = pos.y + height, z = pos.z}) + if not nod then + return false + else + return true + end +end + +minetest.register_abm({ + label = "Caverealms grow sapling", + nodenames = {"ethereal:mushroom_sapling", "caverealms:mushroom_sapling"}, + interval = 10, + chance = 50, + catch_up = false, + action = function(pos, node) + local light_level = minetest.get_node_light(pos) + -- check light level + if not light_level or light_level > 10 then + return + end + -- get node under sapling + local under = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}).name + -- check if registered + if not minetest.registered_nodes[node.name] then + return + end + -- ethereal sapling on lichen stone + if node.name == "ethereal:mushroom_sapling" + and under == "caverealms:stone_with_lichen" + and enough_height(pos, 10) then + grow_caverealms_mushroom(pos) + -- caverealms sapling on lichen stone + elseif node.name == "caverealms:mushroom_sapling" + and under == "caverealms:stone_with_lichen" + and enough_height(pos, 10) then + grow_caverealms_mushroom(pos) + end + end, +}) + + +-- spread moss/lichen/algae to nearby cobblestone +minetest.register_abm({ + label = "Caverealms stone spread", + nodenames = { + "caverealms:stone_with_moss", + "caverealms:stone_with_lichen", + "caverealms:stone_with_algae", + }, + neighbors = {"air"}, + interval = 16, + chance = 50, + catch_up = false, + action = function(pos, node) + local num = minetest.find_nodes_in_area_under_air( + {x = pos.x - 1, y = pos.y - 2, z = pos.z - 1}, + {x = pos.x + 1, y = pos.y + 1, z = pos.z + 1}, + "default:cobble") + if #num > 0 then + minetest.set_node(num[math.random(#num)], {name = node.name}) + end + end, +}) diff --git a/mods/caverealms_lite/schematics/shroom.mts b/mods/caverealms_lite/schematics/shroom.mts new file mode 100644 index 0000000..07e4966 Binary files /dev/null and b/mods/caverealms_lite/schematics/shroom.mts differ diff --git a/mods/caverealms_lite/textures/Thumbs.db b/mods/caverealms_lite/textures/Thumbs.db new file mode 100644 index 0000000..277f856 Binary files /dev/null and b/mods/caverealms_lite/textures/Thumbs.db differ diff --git a/mods/caverealms_lite/textures/caverealms_algae.png b/mods/caverealms_lite/textures/caverealms_algae.png new file mode 100644 index 0000000..1331bb0 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_algae.png differ diff --git a/mods/caverealms_lite/textures/caverealms_algae_side.png b/mods/caverealms_lite/textures/caverealms_algae_side.png new file mode 100644 index 0000000..b9bd4ed Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_algae_side.png differ diff --git a/mods/caverealms_lite/textures/caverealms_angler_rod.png b/mods/caverealms_lite/textures/caverealms_angler_rod.png new file mode 100644 index 0000000..799abec Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_angler_rod.png differ diff --git a/mods/caverealms_lite/textures/caverealms_angler_rod_baited.png b/mods/caverealms_lite/textures/caverealms_angler_rod_baited.png new file mode 100644 index 0000000..98c9f3b Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_angler_rod_baited.png differ diff --git a/mods/caverealms_lite/textures/caverealms_angler_rod_weild.png b/mods/caverealms_lite/textures/caverealms_angler_rod_weild.png new file mode 100644 index 0000000..160a5ff Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_angler_rod_weild.png differ diff --git a/mods/caverealms_lite/textures/caverealms_coal_dust.png b/mods/caverealms_lite/textures/caverealms_coal_dust.png new file mode 100644 index 0000000..be6cbbb Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_coal_dust.png differ diff --git a/mods/caverealms_lite/textures/caverealms_dm_stone.png b/mods/caverealms_lite/textures/caverealms_dm_stone.png new file mode 100644 index 0000000..73e9266 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_dm_stone.png differ diff --git a/mods/caverealms_lite/textures/caverealms_fire_vine.png b/mods/caverealms_lite/textures/caverealms_fire_vine.png new file mode 100644 index 0000000..6f2c2a3 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_fire_vine.png differ diff --git a/mods/caverealms_lite/textures/caverealms_fungi.png b/mods/caverealms_lite/textures/caverealms_fungi.png new file mode 100644 index 0000000..fde8cbf Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_fungi.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_amethyst.png b/mods/caverealms_lite/textures/caverealms_glow_amethyst.png new file mode 100644 index 0000000..7daa61b Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_amethyst.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_amethyst_ore.png b/mods/caverealms_lite/textures/caverealms_glow_amethyst_ore.png new file mode 100644 index 0000000..403d907 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_amethyst_ore.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_bait.png b/mods/caverealms_lite/textures/caverealms_glow_bait.png new file mode 100644 index 0000000..56a084b Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_bait.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_crystal.png b/mods/caverealms_lite/textures/caverealms_glow_crystal.png new file mode 100644 index 0000000..b9be395 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_crystal.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_emerald.png b/mods/caverealms_lite/textures/caverealms_glow_emerald.png new file mode 100644 index 0000000..025a48b Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_emerald.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_emerald_ore.png b/mods/caverealms_lite/textures/caverealms_glow_emerald_ore.png new file mode 100644 index 0000000..9f601aa Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_emerald_ore.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_gem.png b/mods/caverealms_lite/textures/caverealms_glow_gem.png new file mode 100644 index 0000000..9bf3426 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_gem.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_mese.png b/mods/caverealms_lite/textures/caverealms_glow_mese.png new file mode 100644 index 0000000..ed433fe Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_mese.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_obsidian.png b/mods/caverealms_lite/textures/caverealms_glow_obsidian.png new file mode 100644 index 0000000..a157738 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_obsidian.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_obsidian2.png b/mods/caverealms_lite/textures/caverealms_glow_obsidian2.png new file mode 100644 index 0000000..7d1dcf3 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_obsidian2.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_obsidian_brick.png b/mods/caverealms_lite/textures/caverealms_glow_obsidian_brick.png new file mode 100644 index 0000000..a5c6db8 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_obsidian_brick.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_obsidian_brick_2.png b/mods/caverealms_lite/textures/caverealms_glow_obsidian_brick_2.png new file mode 100644 index 0000000..da2b2e3 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_obsidian_brick_2.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_obsidian_glass.png b/mods/caverealms_lite/textures/caverealms_glow_obsidian_glass.png new file mode 100644 index 0000000..afd0fa7 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_obsidian_glass.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_ore.png b/mods/caverealms_lite/textures/caverealms_glow_ore.png new file mode 100644 index 0000000..19179a9 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_ore.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_ruby.png b/mods/caverealms_lite/textures/caverealms_glow_ruby.png new file mode 100644 index 0000000..59fd46b Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_ruby.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_ruby_ore.png b/mods/caverealms_lite/textures/caverealms_glow_ruby_ore.png new file mode 100644 index 0000000..31ecb63 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_ruby_ore.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_worm.png b/mods/caverealms_lite/textures/caverealms_glow_worm.png new file mode 100644 index 0000000..e324fbd Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_worm.png differ diff --git a/mods/caverealms_lite/textures/caverealms_glow_worm_green.png b/mods/caverealms_lite/textures/caverealms_glow_worm_green.png new file mode 100644 index 0000000..686c277 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_glow_worm_green.png differ diff --git a/mods/caverealms_lite/textures/caverealms_hot_cobble.png b/mods/caverealms_lite/textures/caverealms_hot_cobble.png new file mode 100644 index 0000000..2e873e8 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_hot_cobble.png differ diff --git a/mods/caverealms_lite/textures/caverealms_icicle_down.png b/mods/caverealms_lite/textures/caverealms_icicle_down.png new file mode 100644 index 0000000..adcc340 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_icicle_down.png differ diff --git a/mods/caverealms_lite/textures/caverealms_icicle_up.png b/mods/caverealms_lite/textures/caverealms_icicle_up.png new file mode 100644 index 0000000..fcd5e2a Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_icicle_up.png differ diff --git a/mods/caverealms_lite/textures/caverealms_lichen.png b/mods/caverealms_lite/textures/caverealms_lichen.png new file mode 100644 index 0000000..f38fe76 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_lichen.png differ diff --git a/mods/caverealms_lite/textures/caverealms_lichen_side.png b/mods/caverealms_lite/textures/caverealms_lichen_side.png new file mode 100644 index 0000000..b036dc3 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_lichen_side.png differ diff --git a/mods/caverealms_lite/textures/caverealms_moss.png b/mods/caverealms_lite/textures/caverealms_moss.png new file mode 100644 index 0000000..fd23ec3 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_moss.png differ diff --git a/mods/caverealms_lite/textures/caverealms_moss_side.png b/mods/caverealms_lite/textures/caverealms_moss_side.png new file mode 100644 index 0000000..a16d64a Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_moss_side.png differ diff --git a/mods/caverealms_lite/textures/caverealms_mushroom_cap.png b/mods/caverealms_lite/textures/caverealms_mushroom_cap.png new file mode 100644 index 0000000..e5a1a35 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_mushroom_cap.png differ diff --git a/mods/caverealms_lite/textures/caverealms_mushroom_gills.png b/mods/caverealms_lite/textures/caverealms_mushroom_gills.png new file mode 100644 index 0000000..596de9e Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_mushroom_gills.png differ diff --git a/mods/caverealms_lite/textures/caverealms_mushroom_sapling.png b/mods/caverealms_lite/textures/caverealms_mushroom_sapling.png new file mode 100644 index 0000000..262c690 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_mushroom_sapling.png differ diff --git a/mods/caverealms_lite/textures/caverealms_mushroom_stem.png b/mods/caverealms_lite/textures/caverealms_mushroom_stem.png new file mode 100644 index 0000000..d329ef1 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_mushroom_stem.png differ diff --git a/mods/caverealms_lite/textures/caverealms_mycena.png b/mods/caverealms_lite/textures/caverealms_mycena.png new file mode 100644 index 0000000..50ea65b Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_mycena.png differ diff --git a/mods/caverealms_lite/textures/caverealms_salt_crystal.png b/mods/caverealms_lite/textures/caverealms_salt_crystal.png new file mode 100644 index 0000000..dde96fc Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_salt_crystal.png differ diff --git a/mods/caverealms_lite/textures/caverealms_salt_gem.png b/mods/caverealms_lite/textures/caverealms_salt_gem.png new file mode 100644 index 0000000..0419e2e Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_salt_gem.png differ diff --git a/mods/caverealms_lite/textures/caverealms_salty2.png b/mods/caverealms_lite/textures/caverealms_salty2.png new file mode 100644 index 0000000..7f8b521 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_salty2.png differ diff --git a/mods/caverealms_lite/textures/caverealms_spike.png b/mods/caverealms_lite/textures/caverealms_spike.png new file mode 100644 index 0000000..253c9e6 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_spike.png differ diff --git a/mods/caverealms_lite/textures/caverealms_stone_eyes.png b/mods/caverealms_lite/textures/caverealms_stone_eyes.png new file mode 100644 index 0000000..288db06 Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_stone_eyes.png differ diff --git a/mods/caverealms_lite/textures/caverealms_thin_ice.png b/mods/caverealms_lite/textures/caverealms_thin_ice.png new file mode 100644 index 0000000..b16036d Binary files /dev/null and b/mods/caverealms_lite/textures/caverealms_thin_ice.png differ diff --git a/mods/caverealms_lite/textures/fire_basic_flame.png b/mods/caverealms_lite/textures/fire_basic_flame.png new file mode 100644 index 0000000..7a126e3 Binary files /dev/null and b/mods/caverealms_lite/textures/fire_basic_flame.png differ diff --git a/mods/caverealms_lite/textures/fire_basic_flame_animated.png b/mods/caverealms_lite/textures/fire_basic_flame_animated.png new file mode 100644 index 0000000..3b312e5 Binary files /dev/null and b/mods/caverealms_lite/textures/fire_basic_flame_animated.png differ diff --git a/mods/charcoal/init.lua b/mods/charcoal/init.lua new file mode 100644 index 0000000..492ec30 --- /dev/null +++ b/mods/charcoal/init.lua @@ -0,0 +1,62 @@ +minetest.register_craftitem('charcoal:charcoal', { + description = 'Charcoal', + inventory_image = 'charcoal_charcoal.png', + groups = {coal=1}, +}) + +minetest.register_craftitem('charcoal:charcoal_block', { + description = 'Charcoal Block', + inventory_image = 'charcoal_charcoal_block_icon.png', + groups = {coal=1}, +}) + + +minetest.register_craft({ + type = 'cooking', + output = 'charcoal:charcoal', + recipe = 'group:tree', + cooktime = 9, +}) + +minetest.register_craft({ + output = 'charcoal:charcoal_block', + recipe = { + {'charcoal:charcoal', 'charcoal:charcoal', 'charcoal:charcoal'}, + {'charcoal:charcoal', 'charcoal:charcoal', 'charcoal:charcoal'}, + {'charcoal:charcoal', 'charcoal:charcoal', 'charcoal:charcoal'}, + } +}) + + +minetest.register_node('charcoal:charcoal_block', { + description = 'Charcoal Block', + tiles = {'charcoal_charcoal_block.png'}, + groups = {cracky=1}, +}) + +minetest.register_craft({ + type = 'fuel', + recipe = 'charcoal:charcoal', + burntime = 40, +}) + +minetest.register_craft({ + type = 'fuel', + recipe = 'charcoal:charcoal_block', + burntime = 370, +}) + +minetest.register_craft({ + output = 'default:torch 4', + recipe = { + {'charcoal:charcoal'}, + {'default:stick'}, + } +}) + +minetest.register_craft({ + output = 'charcoal:charcoal 9', + recipe = { + {'charcoal:charcoal_block'}, + } +}) diff --git a/mods/charcoal/license.txt b/mods/charcoal/license.txt new file mode 100644 index 0000000..a33bb65 --- /dev/null +++ b/mods/charcoal/license.txt @@ -0,0 +1,6 @@ +Code is licensed MIT, Media CC by SA 4.0 +Copyright 2020 Nathan Salapat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/charcoal/mod.conf b/mods/charcoal/mod.conf new file mode 100644 index 0000000..e47ba23 --- /dev/null +++ b/mods/charcoal/mod.conf @@ -0,0 +1,3 @@ +name = charcoal +depends = default +description = Adds charcoal to the game. diff --git a/mods/charcoal/textures/charcoal_charcoal.png b/mods/charcoal/textures/charcoal_charcoal.png new file mode 100644 index 0000000..63c5ef5 Binary files /dev/null and b/mods/charcoal/textures/charcoal_charcoal.png differ diff --git a/mods/charcoal/textures/charcoal_charcoal_block.png b/mods/charcoal/textures/charcoal_charcoal_block.png new file mode 100644 index 0000000..1303d8e Binary files /dev/null and b/mods/charcoal/textures/charcoal_charcoal_block.png differ diff --git a/mods/chat3/API.md b/mods/chat3/API.md new file mode 100644 index 0000000..21f3e68 --- /dev/null +++ b/mods/chat3/API.md @@ -0,0 +1,132 @@ +Chat3 API +========= + +Main API +-------- + +`chat3.colorize(name, color, msg)` + +* Checks protocol of `name` and if recent enough returns the colourized `msg` +* This does not send the message to the player, but just returns the message. +* `name`: Name of player to whom the colorized message is to be sent +* `color`: Hex-code or color name (string) +* `msg`: Message to colorize + +`chat3.send(name, msg, prefix, source)` + +* Simulate a message being sent to all players +* `name`: Sender player name +* `msg`: Message to send +* `prefix`: An optional string to prefix the colourized message and username +* `source`: Used by ranks to allow compatibility between ranks and chat3 + +Ignore API +---------- + +`chat3.ignore.get(name)` + +* Returns table of ignored players (e.g. +* `{ignoring = {name1 = true, ...}, ignored_by = {name2 = true, ...}}`) +* `name`: Player username + +`chat3.ignore.set(name, list)` + +* Set a player's ignore list +* `name`: Player username +* `list`: Table of names (e.g. (e.g. +* `{ignoring = {name1 = true, ...}, ignored_by = {name2 = true, ...}}`) + +`chat3.ignore.add_name(name, ignore)` + +* Returns `success` if `ignore` was added to `name`'s `ignoring` list and `name` +* to `ignore`'s `ignored_by` list +* `name`: Name of player to whose ignore list `ignore` should be added +* `ignore`: Player username to ignore + +`chat3.ignore.remove_name(name, unignore)` + +* Returns `success` if `ignore` was removed from `name`'s `ignoring` list and +* `name` from `ignore`'s `ignored_by` list + +`chat3.ignore.clear(name)` + +* Returns `success` if `name`'s ignore list was cleared +* This should be used over `chat3.ignore.set(name, nil)` as it also clears +* `ignored_by` lists and notifies no longer ignored players. +`name`: Name of player whose ignore list should be cleared + +`chat3.ignore.can(name, check)` + +* Returns `true` if the player can be ignored +* If the player cannot be ignored they will be removed from the ignore list of +* the player ignoring them. +* `name`: Name of player whose ignore list is to be checked +* `check`: Player username to check if ignored + +`chat3.ignore.is(name, check)` + +* Returns `true` if the player is being ignored +* `name`: Name of player whose ignore list is to be checked +* `target`: Player Object of player to check the ignore list of + +`chat3.ignore.add(name, ignore)` + +* Returns `success, message` after attempting to ignore a player +* Verbose, chat-friendly version of `chat3.ignore.add_name` +* `name`: Name of player to whose ignore list `ignore` should be added +* `ignore`: Player username to attempt to ignore + +`chat3.ignore.remove(name, unignore)` + +* Returns `success, message` after attempting to remove a player from another's +* ignore list. +* Verbose, chat-friendly version of `chat3.ignore.remove_name` +* `name`: Name of player from whose ignore list `unignore` should be removed +* `player`: Player username to attempt to unignore + +`chat3.ignore.check(name, check)` + +* Returns `result, message` after attempting to find out if `check` is being +* ignored by `name`. +* `name`: Name of player whose ignore list should be checked +* `check`: Player username to check if being ignored + +`chat3.ignore.list(name, subtable)` + +* Returns a table containing a list of players being ignored by `name`, or `nil` +* if none, in a format suitable for use with `table.concat` (e.g. `{name1, name2, ...}`). +* `name`: Name of player whose ignore list should be listed +* `subtable`: Table to return (`ignoring` or `ignored_by`) + +Alternate Username API +---------------------- + +`chat3.alt.get(name)` + +* Returns table of alternate usernames (e.g. `{name1 = true, name2 = true, ...}`) +* `name`: Player username + +`chat3.alt.set(name, list)` + +* Set a player's alternate username list +* `name`: Player username +* `list`: Table of alternate usernames (e.g. `{name1 = true, name2 = true, ...}`) + +`chat3.alt.add(name, alt)` + +* Add an alternate username (returns `nil` if max has been reached or if the + alternate username already exists) +* `name`: Base player username +* `alt`: New alternate username + +`chat3.alt.remove(name, alt)` + +* Remove an alternate username (returns `nil` if the username already does not + exist) +* `name`: Base player username +* `alt`: Alternate username to remove + +`chat3.alt.list(name)` + +* Returns a table with a list of alternate usernames (suitable for `table.concat`) +* `name`: Player username diff --git a/mods/chat3/README.md b/mods/chat3/README.md new file mode 100644 index 0000000..ceab9bb --- /dev/null +++ b/mods/chat3/README.md @@ -0,0 +1,40 @@ +![Screenshot](.gh-screenshot.png) + +Enhanced Chat [chat3] +======================= +- GitHub: https://github.com/octacian/chat3 +- Download: https://github.com/octacian/chat3/archive/master.zip +- Forum: https://forum.minetest.net/viewtopic.php?t=17163 + +**Notice:** chat3 requires that the server be running Minetest 0.4.16, as it is required for several features of chat3's core functionality. More specifically, you need a version of Minetest that includes [this commit](https://github.com/minetest/minetest/commit/43d1f375d18a2fbc547a9b4f23d1354d645856ca) (May 6th, 2017). + +Yes, chat3 seems a whole lot like a spinoff of chat2, however, it (mostly) isn't. It isn't that much unlike chat3, except for one thing: rather than cluttering the screen with a second chat window, chat3 just uses the default Minetest chat. Then it's entirely up to the player to configure the chat placement, size, and anything else on their client. + +Messages are highlighted in a light blue to players who are within 12 blocks of the sender (configurable with `chat3.near`, if set to `0` positional highlighting is ignored). Messages in which the receiving player's name or a previously configured alternate username is mentioned are highlighted in a light green, as are PMs. Messages in which the first character is a `!` are highlighted in red to all players (also known as a shout). Important messages (mentions or shouts) also cause a bell to be played to players if `chat3.bell` is `true` and the player hasn't disabled the chatbell using the `/chatbell` command. Everything mentioned here can also be configured, and is documented below in the Configuration section. + +If the server is using Minetest 0.4.16, which has the ability to properly retreive the protocol version of the client without requiring a debug build, chat3 will automatically adjust its message handling to work with older clients as well. This means that clients before 0.4.16 will not see chat duplication on their side, and colour codes will not be sent to clients that do not support them. + +Chat3 is also compatible with some of my other chat-related mods, including [ranks](https://forum.minetest.net/viewtopic.php?f=9&t=17640). + +Configuration +------------- + +All of the features provided by chat3 can be configured directly from the advanced settings menu in the chat3 subsection of the top-level Mods section. You can also configure chat3 directly from `minetest.conf` with the settings listed below. + +| Name | Type | Default | Description | +| ------------------ | ------ | ------- | ------------------------- | +| chat3.near | float | 12 | Near highlight range | +| chat3.bell | bool | true | Enable chatbell | +| chat3.shout | bool | true | Allow shout messages | +| chat3.shout_prefix | string | ! | Shout prefix | +| chat3.ignore | bool | true | Allow ignoring players | +| chat3.alt_support | bool | true | Allow alternate usernames | +| chat3.alt_max | int | 3 | Maximum # of alts | + +The chatbell can also be enabled or disabled using the `/chatbell` command per-player. The ignore feature can be further configured by adding players that cannot be ignored with `ignore_override` privilege. Furthermore, the server owner (as defined by the `name` setting) cannot be ignored no matter what. + +Media License +------------- + +Brandon75689 - https://opengameart.org/content/point-bell (CC-BY-SA 3.0) + chat3_bell.ogg diff --git a/mods/chat3/alt.lua b/mods/chat3/alt.lua new file mode 100644 index 0000000..17b05d3 --- /dev/null +++ b/mods/chat3/alt.lua @@ -0,0 +1,114 @@ +-- chat3/alt.lua + +chat3.alt = {} + +local storage = chat3.storage +local MAX = chat3.settings.get_int("chat3.alt_max") or 3 + +--- +--- Functions (exposed API) +--- + +-- [function] Get alt list +function chat3.alt.get(name) + local list = storage:get_string("alt_list_"..name) + + if list then + list = minetest.deserialize(list) + end + + return list or {} +end + +-- [function] Set alt list +function chat3.alt.set(name, list) + storage:set_string("alt_list_"..name, minetest.serialize(list)) +end + +-- [function] Add alt +function chat3.alt.add(name, alt) + local list = chat3.alt.get(name) + + local count = 0 + for _, i in pairs(list) do + count = count + 1 + end + + if count < MAX and not list[alt] then + list[alt] = true + chat3.alt.set(name, list) + else + return + end + + return true +end + +-- [function] Remove alt +function chat3.alt.remove(name, alt) + local list = chat3.alt.get(name) + + if list[alt] then + list[alt] = nil + else + return + end + + chat3.alt.set(name, list) + return true +end + +-- [function] List Alt Usernames (returns a table suitable for use with table.concat) +function chat3.alt.list(name) + local list, result = chat3.alt.get(name), {} + if list then + for alt, i in pairs(list) do + table.insert(result, alt) + end + + if #result > 0 then + return result + end + end +end + +--- +--- Registrations +--- + +-- [chatcommand] Alt +minetest.register_chatcommand("alt", { + description = "Manage your chat3 alternate usernames", + params = "[list | add | del | rst] []", + func = function(name, params) + params = params:split(" ") + local operation, alt = params[1], params[2] + + if operation == "list" then + local list = chat3.alt.list(name) + if list then + return true, "Your Alternate Usernames: "..table.concat(list, ", ") + else + return false, "You have not yet configured any alternate usernames." + end + elseif operation == "add" and alt and alt ~= "" then + if chat3.alt.add(name, alt) then + return true, "Added alternate username \""..alt.."\"." + else + return false, "You have either reached the max number ("..tostring(MAX) + ..") of alternate usernames, or the alternate username already exists." + end + elseif operation == "del" and alt and alt ~= "" then + if chat3.alt.remove(name, alt) then + return true, "Removed alternate username \""..alt.."\"." + else + return false, "Alternate username already does not exist." + end + elseif operation == "rst" then + chat3.alt.set(name, {}) + return true, "Reset your alternate username list." + else + return false, "Invalid parameters (see /help alt)" + end + end, +}) diff --git a/mods/chat3/ignore.lua b/mods/chat3/ignore.lua new file mode 100644 index 0000000..82d559c --- /dev/null +++ b/mods/chat3/ignore.lua @@ -0,0 +1,230 @@ +-- chat3/ignore.lua + +chat3.ignore = {} + +local storage = chat3.storage + +--- +--- Functions (API) +--- + +-- [function] Get ignore list +function chat3.ignore.get(name) + local list = storage:get_string("ignore_list_"..name) + + if list then + list = minetest.deserialize(list) + end + + if not list or not list.ignoring or not list.ignored_by then + list = {ignoring = {}, ignored_by = {}} + end + + return list +end + +-- [function] Set ignore list +function chat3.ignore.set(name, list) + storage:set_string("ignore_list_"..name, minetest.serialize(list)) +end + +-- [function] Add name to list +function chat3.ignore.add_name(name, ignore) + -- Update ignoring + local list = chat3.ignore.get(name) + list.ignoring[ignore] = true + chat3.ignore.set(name, list) + + -- Update ignored_by + list = chat3.ignore.get(ignore) + list.ignored_by[name] = true + chat3.ignore.set(ignore, list) + + return true +end + +-- [function] Remove name from list +function chat3.ignore.remove_name(name, unignore) + -- Update ignoring + local list = chat3.ignore.get(name) + list.ignoring[unignore] = nil + chat3.ignore.set(name, list) + + -- Update ignored_by + list = chat3.ignore.get(unignore) + list.ignored_by[name] = nil + chat3.ignore.set(unignore, list) + + return true +end + +-- [function] Clear ignore list +function chat3.ignore.clear(name) + local list = chat3.ignore.get(name) + + -- Clear resulting ignored_by entries and notify + for t, i in pairs(list.ignoring) do + local tlist = chat3.ignore.get(t) + tlist.ignored_by[name] = nil + chat3.ignore.set(t, tlist) + minetest.chat_send_player(t, chat3.colorize(t, "#00ff00", name.. + " is no longer ignoring you.")) + list.ignoring[t] = nil + end + + chat3.ignore.set(name, list) + + return true +end + +-- [function] Can ignore +function chat3.ignore.can(name, check) + local priv = minetest.check_player_privs(check, "ignore_override") + if not priv and minetest.settings:get("name") ~= check and name ~= check then + return true + else + chat3.ignore.remove_name(name, check) + end +end + +-- [function] Is Ignoring +function chat3.ignore.is(name, check) + if name == check then + return false + else + local list = chat3.ignore.get(check).ignored_by + return list[name] and chat3.ignore.can(name, check) + end +end + +-- [function] Ignore +function chat3.ignore.add(name, ignore) + if chat3.ignore.can(name, ignore) then + if chat3.ignore.get(name).ignoring[ignore] then + return false, "You are already ignoring "..ignore.."." + else + chat3.ignore.add_name(name, ignore) + + -- Notify ignored player + --[[if minetest.get_player_by_name(ignore) then + minetest.chat_send_player(ignore, chat3.colorize(ignore, "red", name.. + " is now ignoring you.")) + end +--]] + return true, "Added "..ignore.." to your ignore list." + end + else + return false, "You cannot ignore "..ignore.."." + end +end + +-- [function] Unignore +function chat3.ignore.remove(name, unignore) + if chat3.ignore.get(name).ignoring[unignore] then + chat3.ignore.remove_name(name, unignore) + + -- Notify unignored player + if minetest.get_player_by_name(unignore) then + minetest.chat_send_player(unignore, chat3.colorize(unignore, "#00ff00", + name.." is no longer ignoring you.")) + end + + return true, "Removed "..unignore.." from your ignore list." + else + return false, unignore.." is already not on your ignore list." + end +end + +-- [function] Check Ignore (verbose [chat] version if Is Ignoring) +function chat3.ignore.check(name, check) + minetest.log("chat3.ignore.check: "..name..", "..check) + if chat3.ignore.is(name, check) then + return true, "You are being ignored by "..name.."." + else + return false, name.." is not ignoring you." + end +end + +-- [function] List Ignored Players (returns a table suitable for use with table.concat) +function chat3.ignore.list(name, subtable) + local list, result = chat3.ignore.get(name)[subtable], {} + if list then + for ignored, i in pairs(list) do + table.insert(result, ignored) + end + + if #result > 0 then + return result + end + end +end + +--- +--- Registrations +--- + +-- [event] Show list of people ignoring you on join +--[[ +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + local list = chat3.ignore.list(name, "ignored_by") + if list then + local p = "players" + if #list == 1 then + p = "player" + end + + minetest.chat_send_player(name, string.format( + "You are being ignored by %i %s: %s.", #list, p, + table.concat(list, ", "))) + end +end) +--]] + +-- [privilege] Ignore Override +minetest.register_privilege("ignore_override", { + description = "Prevent players from ignoring anyone with this privilege.", + give_to_singleplayer = false, +}) + +-- [chatcommand] Ignore +minetest.register_chatcommand("ignore", { + description = "Ignore players", + params = "[list | by | add | del | rst | check] []", + func = function(name, params) + params = params:split(" ") + local operation, target = params[1], params[2] + local invalid = "Invalid parameters (see /help ignore)" + + if operation and operation ~= "" then + if operation == "list" then + local list = chat3.ignore.list(name, "ignoring") + if list then + return true, "Ignored Players: "..table.concat(list, ", ").."." + else + return false, "You are not ignoring any players." + end + elseif operation == "by" then + local list = chat3.ignore.list(name, "ignored_by") + if list then + return true, "You are being ignored by: "..table.concat(list, ", ").."." + else + return false, "You are not being ignored by any players." + end + elseif operation == "add" and target and target ~= "" then + return chat3.ignore.add(name, target) + elseif operation == "del" and target and target ~= "" then + return chat3.ignore.remove(name, target) + elseif operation == "check" and target and target ~= "" then + return chat3.ignore.check(target, name) + elseif operation == "rst" then + chat3.ignore.clear(name) + return true, "Cleared your ignore list." + else + return false, invalid + end + else + return false, invalid + end + end, +}) diff --git a/mods/chat3/init.lua b/mods/chat3/init.lua new file mode 100644 index 0000000..2ae980b --- /dev/null +++ b/mods/chat3/init.lua @@ -0,0 +1,285 @@ +-- chat3/init.lua + +chat3 = {} + +chat3.settings = {} +chat3.storage = minetest.get_mod_storage() + +local modpath = minetest.get_modpath("chat3") + +local prot = {} -- Table of protocol versions - to be used later + +--- +--- Handle Settings +--- + +-- [function] Get float setting +function chat3.settings.get_int(key) + local res = minetest.settings:get(key) + if res then + return tonumber(res) + end +end + +-- [function] Get boolean setting +function chat3.settings.get_bool(key, default) + local retval = minetest.settings:get_bool(key) + + if default and retval == nil then + retval = default + end + + return retval +end + +local bell = chat3.settings.get_bool("chat3.bell") +local shout = chat3.settings.get_bool("chat3.shout") +local prefix = minetest.settings:get("chat3.shout_prefix") or "!" +local near = chat3.settings.get_int("chat3.near") or 12 +local ignore = chat3.settings.get_bool("chat3.ignore", true) +local alt = chat3.settings.get_bool("chat3.alt_support", true) + +if prefix:len() > 1 then + prefix = "!" +end + +--- +--- Load Features +--- + +if ignore then dofile(modpath.."/ignore.lua") end -- Load ignore +if alt then dofile(modpath.."/alt.lua") end -- Load alt + +--- +--- Helpers +--- + +local function cache_protocal_version(name) + local info = minetest.get_player_information(name) + -- if info is not nil, cache the player's protocol version + if info ~= nil then + prot[name] = info.protocol_version + -- else, if info is nil, the player doesn't exist yet for some reason and + -- caching will occur the first time the information is requested. + end +end + +local function get_protocal_version(name) + -- if version is cached, return it + if prot[name] then + return prot[name] + end + + -- otherwise, retrive and cache it + cache_protocal_version(name) +end + +--- +--- Exposed Functions (API) +--- + +-- [function] Colorize +function chat3.colorize(name, colour, msg) + local vers = get_protocal_version(name) + if vers and vers >= 27 then + return minetest.colorize(colour, msg) + else + return msg + end +end + +-- [function] Check if mentioned (should highlight or not) +function chat3.is_mentioned(name, msg) + name, msg = name:lower(), msg:lower() + + -- Direct mentions + local direct_mention = msg:find(name, 1, true) + + -- Alt mentions + local alt_mention + if alt then + local list = chat3.alt.get(name) + for alt, i in pairs(list) do + alt_mention = msg:find(alt, 1, true) or alt_mention + end + end + + return direct_mention or alt_mention +end + +-- [function] Process +function chat3.send(name, msg, prefix, source) + if not minetest.check_player_privs(name, "shout") + or minetest.get_modpath("ranks") and source ~= "ranks" then + return + end + + local sender = minetest.get_player_by_name(name) + + for _, player in pairs(minetest.get_connected_players()) do + local rname = player:get_player_name() + local colour = "#ffffff" + + local vers = prot[rname] + if (not vers or (vers and (vers >= 29 or (vers < 29 and name ~= rname)))) + and (not ignore or not chat3.ignore.is(rname, name) and not chat3.ignore.is(name, rname)) then + -- Check for near + if near ~= 0 then -- and name ~= rname then + if vector.distance(sender:getpos(), player:getpos()) <= near then + colour = "#88ffff" + end + end + + -- Check for mentions + if chat3.is_mentioned(rname, msg) then + colour = "#00ff00" + + -- Chat bell + if bell and name ~= rname then + local pbell = player:get_attribute("chat3:bell") + if pbell ~= "false" then + minetest.sound_play("chat3_bell", { + gain = 4, + to_player = rname, + }) + end + end + end + + -- Check for shout + if shout and msg:sub(1, 1) == prefix then + colour = "#ff0000" + + -- Chat bell + if bell and name ~= rname then + local pbell = player:get_attribute("chat3:bell") + if pbell ~= "false" then + minetest.sound_play("chat3_bell", { + gain = 4, + to_player = rname, + }) + end + end + end + + -- if same player, set to white + if name == rname then + colour = "#ffffff" + end + + -- Send message + local send = chat3.colorize(rname, colour, "<"..name.."> "..msg) + if prefix then + send = prefix..send + end + + minetest.chat_send_player(rname, send) + end + end + + -- Log message + minetest.log("action", "CHAT: ".."<"..name.."> "..msg) + + -- Prevent from sending normally + return true +end + +--- +--- Events/Definitions +--- + +-- [event] On join player +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + cache_protocal_version(name) +end) + +-- [event] On chat message +minetest.register_on_chat_message(function(name, msg) + return chat3.send(name, msg) +end) + +-- [redefine] /msg +if minetest.chatcommands["msg"] then + local old_command = minetest.chatcommands["msg"].func + minetest.override_chatcommand("msg", { + func = function(name, param) + local sendto, message = param:match("^(%S+)%s(.+)$") + if not sendto then + return false, "Invalid usage, see /help msg." + end + if not minetest.get_player_by_name(sendto) then + return false, "The player " .. sendto + .. " is not online." + end + + if ignore and chat3.ignore.is(sendto, name) then + return false, chat3.colorize(name, "red", + "Could not send message, you are on "..sendto.."'s ignore list.") + else + + minetest.log("action", "PM from " .. name .. " to " .. sendto + .. ": " .. message) + minetest.chat_send_player(sendto, chat3.colorize(sendto, '#00ff00', + "PM from " .. name .. ": ".. message)) + + if bell then + local player = minetest.get_player_by_name(sendto) + local pbell = player:get_attribute("chat3:bell") + if pbell ~= "false" then + minetest.sound_play("chat3_bell", { + gain = 4, + to_player = sendto, + }) + end + end + + if ignore and chat3.ignore.is(name, sendto) then + return true, "Message sent.\n"..chat3.colorize(name, "red", + "Warning: "..sendto.." will not be able to respond to this" + .." message unless you remove them from your ignore list.") + else + return true, "Message sent." + end + end + end, + }) +end + +-- [redefine] /me +if minetest.chatcommands["me"] then + local old_command = minetest.chatcommands["me"] + minetest.override_chatcommand("me", { + func = function(name, param) + minetest.chat_send_player(name, '* '..name..' '..param) + --[[for _, player in pairs(minetest.get_connected_players()) do + local rname = player:get_player_name() + + if not ignore or not chat3.ignore.is(rname, name) then + minetest.chat_send_player(rname, "* "..name.." "..param) + end + end + --]] + end, + }) +end + +-- [chatcommand] Chatbell +if bell then + minetest.register_chatcommand("chatbell", { + description = "Enable/disable chatbell when you are mentioned in the chat", + func = function(name) + local player = minetest.get_player_by_name(name) + if player then + local bell = player:get_attribute("chat3:bell") + if not bell or bell == "" or bell == "true" then + player:set_attribute("chat3:bell", "false") + return true, "Disabled Chatbell" + else + player:set_attribute("chat3:bell", "true") + return true, "Enabled Chatbell" + end + end + end, + }) +end diff --git a/mods/chat3/license.txt b/mods/chat3/license.txt new file mode 100644 index 0000000..0b3ce07 --- /dev/null +++ b/mods/chat3/license.txt @@ -0,0 +1,16 @@ +MIT License +Copyright (c) 2017 Elijah Duffy +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT +NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/chat3/mod.conf b/mods/chat3/mod.conf new file mode 100644 index 0000000..ff46ee1 --- /dev/null +++ b/mods/chat3/mod.conf @@ -0,0 +1,2 @@ +name = chat3 +description = chat3 is a simplistic Minetest mod that makes chat on a populated server much easier to understand and keep up with. diff --git a/mods/chat3/settingtypes.txt b/mods/chat3/settingtypes.txt new file mode 100644 index 0000000..bf258be --- /dev/null +++ b/mods/chat3/settingtypes.txt @@ -0,0 +1,36 @@ +# If this is enabled, players will have the option to hear a bell play +# whenever their name is mentioned in chat in addition to the message being +# highlighted in green. +chat3.bell (Chatbell) bool true + +# If this is not set to 0, players within this range of each other will see +# messages highlighted in blue to indicate that they are close. +chat3.near (Near Highlight Range) float 12 + +# If this is true, players can cause messages to be highlighted in red for +# all players and the chatbell to be played (if enabled) by prefixing their +# message, by default, with "!" (configurable with chat3.shout_prefix). +chat3.shout (Enable Shout Messages) bool true + +# The single-character prefix to cause messages to be highlighted in red for +# all players and the chatbell to be played (if enabled). This setting only +# applies if chat3.shout is set to true. +chat3.shout_prefix (Shout Prefix) string ! + +# When enabled, a /ignore chatcommand is added which allows players to ignore +# chat messages and PMs from players which they have added (see /help ignore). +# Non-ignorable players can be added with by granting the `ignore_override`. +# This will prevent these players from being added to ignore lists and will +# automatically remove them should they already exist. The server owner (as +# defined by the `name` setting) cannot be ignored no matter what. +chat3.ignore (Enable Ignore Feature) bool true + +# When enabled, players can add a limitted number of alternate usernames +# which chat3 will check incoming messages for in order to expand +# highlighting. The max number of allowed alternate usernames can be +# configured with chat3.alt_max (defaults to 3). +chat3.alt_support (Allow players to add alts) bool true + +# If chat3.alt_support is enabled, this will control the maximum number of +# alternate usernames that each player is allowed to configure. +chat3.alt_max (Configure maximum alts) int 3 1 1000 diff --git a/mods/chat3/sounds/chat3_bell.ogg b/mods/chat3/sounds/chat3_bell.ogg new file mode 100644 index 0000000..1f981bf Binary files /dev/null and b/mods/chat3/sounds/chat3_bell.ogg differ diff --git a/mods/cloudlands/README.md b/mods/cloudlands/README.md new file mode 100644 index 0000000..52ba2d8 --- /dev/null +++ b/mods/cloudlands/README.md @@ -0,0 +1,51 @@ +

+ +

+ +# Hallelujah Mountains for Minetest + + + +[![License](https://img.shields.io/badge/license-LGPLv2.1%2B-blue.svg)](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html) + +AKA Cloudlands — giant rocks floating suspended in magnetic eddies. Now with giant trees + +This can be run with or without a normal terrain mapgen, allowing pure skylands or an exotic addition to the landscape. + +Many Configurable settings, including the altitude islands appear, and the ability to restrict the areas they spawn. + +It's a single file with no hard dependencies for easy integration into modpacks or games, e.g. as an exotic biome. + +Hallelujah Mountains [maps](https://i.imgur.com/2SkoAyB.png) can be generated by [Amidstest](https://forum.minetest.net/viewtopic.php?t=19869), provided you know the seed of the world. The islands are not homogenous — there will be areas without any, while smaller islands tend to follow eddy fields, often emanating out from much larger and rarer islands. + +**Mod dependencies:** None. + +**Minetest version:** v5.0+ + +**Recommended mods:** +* [Vines](https://forum.minetest.net/viewtopic.php?t=2344), or something that contains vines, such as plantlife_modpack or MineClone2. These will grow off the sides of the islands, climate permitting, allowing you to climb, and looking picturesque! +* [Nether](https://forum.minetest.net/viewtopic.php?t=5790) enables players to build portals to Hallelujah Mountains, allowing secret entrances into floating kingdoms, or the island altitude to be configured way up high while still having a means to get there. Stones to build these portals can only be found in the Nether (but not until [PR13](https://github.com/minetest-mods/nether/pull/13) is merged). +* Extra ways to explore + * [Bridger](https://forum.minetest.net/viewtopic.php?t=18243) or [Bridges](https://forum.minetest.net/viewtopic.php?t=3488) if you want to build nice wooden bridges between islands + * [Airboat](https://github.com/paramat/airboat) to sail the high clouds on a small airship + * [Flying carpet](https://forum.minetest.net/viewtopic.php?t=12263) + * [Jetpack, wings, etc.](https://forum.minetest.net/viewtopic.php?t=11257) + * [Hang-glider / Elytra](https://forum.minetest.net/viewtopic.php?t=21425) + * Teleporter mods, balloon mods, etc. + +**Ores tip:** If you decide ores like iron and diamond should be obtainable from island stone, and are playing Minetest Game, you can go into Settings->Advanced Settings->Mods->cloudlands, set the "Altitude of Islands" to be 1300 (or higher), and Enable "Generate ores inside islands". This works because Minetest Game also generates the deep-underground ores in stone above 1025 to ensure they can be found in mgV7 Floatlands. Ores can be added in other games or at other altitudes by adding adjusted copies of the game's calls to minetest.register_ore(). + +**Video:** [Minetest Mod Review: Cloudlands](http://www.nathansalapat.com/minetest/cloudlands) + +**Forum:** [link](https://forum.minetest.net/viewtopic.php?t=20257) + +**Screenshots:** +![default](https://i.imgur.com/PUjjaIK.jpg) + +![default](https://i.imgur.com/xn9UING.jpg) + +![default](https://i.imgur.com/SeYMfZv.jpg) + +![default](https://i.imgur.com/wBLEFWn.jpg) + +![default](https://i.imgur.com/A6vDDGc.jpg) diff --git a/mods/cloudlands/cloudlands.lua b/mods/cloudlands/cloudlands.lua new file mode 100644 index 0000000..0009ed9 --- /dev/null +++ b/mods/cloudlands/cloudlands.lua @@ -0,0 +1,2799 @@ +local ALTITUDE = 200 -- average altitude of islands +local ALTITUDE_AMPLITUDE = 40 -- rough island altitude variance (plus or minus) +local GENERATE_ORES = false -- set to true for island core stone to contain patches of dirt and sand etc. +local LOWLAND_BIOMES = false or -- If true then determine an island's biome using the biome at altitude "LOWLAND_BIOME_ALTITUDE" + minetest.get_modpath("ethereal") ~= nil -- Ethereal has an alpine biome above altitude 40, so default to lowland biomes +local LOWLAND_BIOME_ALTITUDE = 10 -- Higher than beaches, lower than mountains (See LOWLAND_BIOMES) +local VINE_COVERAGE = 0.3 -- set to 0 to turn off vines +local REEF_RARITY = 0.015 -- Chance of a viable island having a reef or atoll +local TREE_RARITY = 0.06 -- Chance of a viable island having a giant tree growing out of it +local PORTAL_RARITY = 0.04 -- Chance of a viable island having some ancient portalstone on it (If portals API available and ENABLE_PORTALS is true) +local BIOLUMINESCENCE = false or -- Allow giant trees variants which have glowing parts + minetest.get_modpath("glowtest") ~= nil or + minetest.get_modpath("ethereal") ~= nil or + minetest.get_modpath("glow") ~= nil or + minetest.get_modpath("nsspf") ~= nil or + minetest.get_modpath("moonflower") ~= nil -- a world using any of these mods is OK with bioluminescence +local ENABLE_PORTALS = true -- Whether to allow players to build portals to islands. Portals require the Nether mod. +local EDDYFIELD_SIZE = 1 -- size of the "eddy field-lines" that smaller islands follow +local ISLANDS_SEED = 1000 -- You only need to change this if you want to try different island layouts without changing the map seed + +-- Some lists of known node aliases (any nodes which can't be found won't be used). +local NODENAMES_STONE = {"epic:stone", "mcl_core:stone", "default:stone"} +local NODENAMES_WATER = {"mapgen_water_source", "mcl_core:water_source", "default:water_source"} +local NODENAMES_ICE = {"mapgen_ice", "mcl_core:ice", "pedology:ice_white", "default:ice"} +local NODENAMES_GRAVEL = {"mapgen_gravel", "mcl_core:gravel", "default:gravel"} +local NODENAMES_GRASS = {"mapgen_dirt_with_grass", "mcl_core:dirt_with_grass", "default:dirt_with_grass"} -- currently only used with games that don't register biomes, e.g. Hades Revisted +local NODENAMES_DIRT = {"mapgen_dirt", "mcl_core:dirt", "default:dirt"} -- currently only used with games that don't register biomes, e.g. Hades Revisted +local NODENAMES_SILT = {"mapgen_silt", "default:silt", "aotearoa:silt", "darkage:silt", "mapgen_sand", "mcl_core:sand", "default:sand"} -- silt isn't a thing yet, but perhaps one day it will be. Use sand for the bottom of ponds in the meantime. +local NODENAMES_VINES = {"mcl_core:vine", "vines:side_end", "ethereal:vine"} -- ethereal vines don't grow, so only select that if there's nothing else. +local NODENAMES_HANGINGVINE = {"vines:vine_end"} +local NODENAMES_HANGINGROOT = {"vines:root_end"} +local NODENAMES_TREEWOOD = {"mcl_core:tree", "default:tree", "mapgen_tree"} +local NODENAMES_TREELEAVES = {"mcl_core:leaves", "default:leaves", "mapgen_leaves"} + +local MODNAME = minetest.get_current_modname() +local VINES_REQUIRED_HUMIDITY = 49 +local VINES_REQUIRED_TEMPERATURE = 40 +local ICE_REQUIRED_TEMPERATURE = 8 + +local DEBUG = false -- dev logging +local DEBUG_GEOMETRIC = false -- turn off noise from island shapes +local DEBUG_SKYTREES = false -- dev logging + +-- OVERDRAW can be set to 1 to cause a y overdraw of one node above the chunk, to avoid creating a dirt "surface" +-- at the top of the chunk that trees mistakenly grow on when the chunk is decorated. +-- However, it looks like that tree problem has been solved by either engine or biome updates, and overdraw causes +-- it's own issues (e.g. nodeId_top not getting set correctly), so I'm leaving overdraw off (i.e. zero) until I +-- notice problems requiring it. +local OVERDRAW = 0 + +local S = minetest.get_translator(minetest.get_current_modname()) + +cloudlands = {} -- API functions can be accessed via this global: + -- cloudlands.get_island_details(minp, maxp) -- returns an array of island-information-tables, y is ignored. + -- cloudlands.find_nearest_island(x, z, search_radius) -- returns a single island-information-table, or nil + -- cloudlands.get_height_at(x, z, [island-information-tables]) -- returns (y, isWater), or nil if no island here + +cloudlands.coreTypes = { + { + territorySize = 200, + coresPerTerritory = 3, + radiusMax = 96, + depthMax = 50, + thicknessMax = 8, + frequency = 0.1, + pondWallBuffer = 0.03, + requiresNexus = true, + exclusive = false + }, + { + territorySize = 60, + coresPerTerritory = 1, + radiusMax = 40, + depthMax = 40, + thicknessMax = 4, + frequency = 0.1, + pondWallBuffer = 0.06, + requiresNexus = false, + exclusive = true + }, + { + territorySize = 30, + coresPerTerritory = 3, + radiusMax = 16, -- I feel this and depthMax should be bigger, say 18, and territorySize increased to 34 to match, but I can't change it any more or existing worlds will mismatch along previously emerged chunk boundaries + depthMax = 16, + thicknessMax = 2, + frequency = 0.1, + pondWallBuffer = 0.11, -- larger values will make ponds smaller and further from island edges, so it should be as low as you can get it without the ponds leaking over the edge. A small leak-prone island is at (3160, -2360) on seed 1 + requiresNexus = false, + exclusive = true + } +} + +if minetest.get_biome_data == nil then error(MODNAME .. " requires Minetest v5.0 or greater", 0) end + +local function fromSettings(settings_name, default_value) + local result + if type(default_value) == "number" then + result = tonumber(minetest.settings:get(settings_name) or default_value) + elseif type(default_value) == "boolean" then + result = minetest.settings:get_bool(settings_name, default_value) + end + return result +end +-- override any settings with user-specified values before these values are needed +ALTITUDE = fromSettings(MODNAME .. "_altitude", ALTITUDE) +ALTITUDE_AMPLITUDE = fromSettings(MODNAME .. "_altitude_amplitude", ALTITUDE_AMPLITUDE) +GENERATE_ORES = fromSettings(MODNAME .. "_generate_ores", GENERATE_ORES) +VINE_COVERAGE = fromSettings(MODNAME .. "_vine_coverage", VINE_COVERAGE * 100) / 100 +LOWLAND_BIOMES = fromSettings(MODNAME .. "_use_lowland_biomes", LOWLAND_BIOMES) +TREE_RARITY = fromSettings(MODNAME .. "_giant_tree_rarety", TREE_RARITY * 100) / 100 +BIOLUMINESCENCE = fromSettings(MODNAME .. "_bioluminescence", BIOLUMINESCENCE) +ENABLE_PORTALS = fromSettings(MODNAME .. "_enable_portals", ENABLE_PORTALS) + +local noiseparams_eddyField = { + offset = -1, + scale = 2, + spread = {x = 350 * EDDYFIELD_SIZE, y = 350 * EDDYFIELD_SIZE, z= 350 * EDDYFIELD_SIZE}, + seed = ISLANDS_SEED, --WARNING! minetest.get_perlin() will add the server map's seed to this value + octaves = 2, + persistence = 0.7, + lacunarity = 2.0, +} +local noiseparams_heightMap = { + offset = 0, + scale = ALTITUDE_AMPLITUDE, + spread = {x = 160, y = 160, z= 160}, + seed = ISLANDS_SEED, --WARNING! minetest.get_perlin() will add the server map's seed to this value + octaves = 3, + persistence = 0.5, + lacunarity = 2.0, +} +local DENSITY_OFFSET = 0.7 +local noiseparams_density = { + offset = DENSITY_OFFSET, + scale = .3, + spread = {x = 25, y = 25, z= 25}, + seed = 1000, --WARNING! minetest.get_perlin() will add the server map's seed to this value + octaves = 4, + persistence = 0.5, + lacunarity = 2.0, +} +local SURFACEMAP_OFFSET = 0.5 +local noiseparams_surfaceMap = { + offset = SURFACEMAP_OFFSET, + scale = .5, + spread = {x = 40, y = 40, z= 40}, + seed = ISLANDS_SEED, --WARNING! minetest.get_perlin() will add the server map's seed to this value + octaves = 4, + persistence = 0.5, + lacunarity = 2.0, +} +local noiseparams_skyReef = { + offset = .3, + scale = .9, + spread = {x = 3, y = 3, z= 3}, + seed = 1000, + octaves = 2, + persistence = 0.5, + lacunarity = 2.0, +} + +local noiseAngle = -15 --degrees to rotate eddyField noise, so that the vertical and horizontal tendencies are off-axis +local ROTATE_COS = math.cos(math.rad(noiseAngle)) +local ROTATE_SIN = math.sin(math.rad(noiseAngle)) + +local noise_eddyField +local noise_heightMap +local noise_density +local noise_surfaceMap +local noise_skyReef + +local worldSeed +local nodeId_ignore = minetest.CONTENT_IGNORE +local nodeId_air +local nodeId_stone +local nodeId_grass +local nodeId_dirt +local nodeId_water +local nodeId_ice +local nodeId_silt +local nodeId_gravel +local nodeId_vine +local nodeName_vine + +local REQUIRED_DENSITY = 0.4 + +local randomNumbers = {} -- array of 0-255 random numbers with values between 0 and 1 (inclusive) +local data = {} -- reuse the massive VoxelManip memory buffers instead of creating on every on_generate() +local biomes = {} + +-- optional region specified in settings to restrict islands too +local region_restrictions = false +local region_min_x, region_min_z, region_max_x, region_max_z = -32000, -32000, 32000, 32000 + +-- optional biomes specified in settings to restrict islands too +local limit_to_biomes = nil +local limit_to_biomes_altitude = nil + +--[[============================== + Math functions + ==============================]]-- + +-- avoid having to perform table lookups each time a common math function is invoked +local math_min, math_max, math_floor, math_sqrt, math_cos, math_sin, math_abs, math_pow, PI = math.min, math.max, math.floor, math.sqrt, math.cos, math.sin, math.abs, math.pow, math.pi + +local function clip(value, minValue, maxValue) + if value <= minValue then + return minValue + elseif value >= maxValue then + return maxValue + else + return value + end +end + +local function round(value) + return math_floor(0.5 + value) +end + +--[[============================== + Interop functions + ==============================]]-- + +local get_heat, get_humidity = minetest.get_heat, minetest.get_humidity + +local biomeinfoAvailable = minetest.get_modpath("biomeinfo") ~= nil and minetest.global_exists("biomeinfo") +local isMapgenV6 = minetest.get_mapgen_setting("mg_name") == "v6" +if isMapgenV6 then + if not biomeinfoAvailable then + -- The biomeinfo mod by Wuzzy can be found at https://repo.or.cz/minetest_biomeinfo.git + minetest.log("warning", MODNAME .. " detected mapgen v6: Full mapgen v6 support requires adding the biomeinfo mod.") + else + get_heat = function(pos) + return biomeinfo.get_v6_heat(pos) * 100 + end + get_humidity = function(pos) + return biomeinfo.get_v6_humidity(pos) * 100 + end + end +end + +local interop = {} +-- returns the id of the first name in the list that resolves to a node id, or nodeId_ignore if not found +interop.find_node_id = function (node_contender_names) + local result = nodeId_ignore + for _,contenderName in ipairs(node_contender_names) do + + local nonAliasName = minetest.registered_aliases[contenderName] or contenderName + if minetest.registered_nodes[nonAliasName] ~= nil then + result = minetest.get_content_id(nonAliasName) + end + + --if DEBUG then minetest.log("info", contenderName .. " returned " .. result) end + if result ~= nodeId_ignore then return result end + end + return result +end + +-- returns the name of the first name in the list that resolves to a node id, or 'ignore' if not found +interop.find_node_name = function (node_contender_names) + return minetest.get_name_from_content_id(interop.find_node_id(node_contender_names)) +end + +-- returns the node name of the clone node. +interop.register_clone = function(node_name, clone_name) + local node = minetest.registered_nodes[node_name] + if node == nil then + minetest.log("error", "cannot clone " .. node_name) + return nil + else + if clone_name == nil then clone_name = MODNAME .. ":" .. string.gsub(node.name, ":", "_") end + if minetest.registered_nodes[clone_name] == nil then + if DEBUG then minetest.log("info", "attempting to register: " .. clone_name) end + local clone = {} + for key, value in pairs(node) do clone[key] = value end + clone.name = clone_name + minetest.register_node(clone_name, clone) + --minetest.log("info", clone_name .. " id: " .. minetest.get_content_id(clone_name)) + --minetest.log("info", clone_name .. ": " .. dump(minetest.registered_nodes[clone_name])) + end + return clone_name + end +end + +-- converts "modname:nodename" into (modname, nodename), if no colon is found then modname is nil +interop.split_nodename = function(nodeName) + local result_modname = nil + local result_nodename = nodeName + + local pos = nodeName:find(':') + if pos ~= nil then + result_modname = nodeName:sub(0, pos - 1) + result_nodename = nodeName:sub(pos + 1) + end + return result_modname, result_nodename +end; + +-- returns a unique id for the biome, normally this is numeric but with mapgen v6 it can be a string name. +interop.get_biome_key = function(pos) + if isMapgenV6 and biomeinfoAvailable then + return biomeinfo.get_v6_biome(pos) + else + return minetest.get_biome_data(pos).biome + end +end + +-- returns true if filename is a file that exists. +interop.file_exists = function(filename) + local f = io.open(filename, "r") + if f == nil then + return false + else + f:close() + return true + end +end + +--[[============================== + Portals + ==============================]]-- + +local addDetail_ancientPortal = nil; + +if ENABLE_PORTALS and minetest.get_modpath("nether") ~= nil and minetest.global_exists("nether") and nether.register_portal ~= nil then + -- The Portals API is available + -- Register a player-buildable portal to Hallelujah Mountains. + + + -- returns a position on the island which is suitable for a portal to be placed, or nil if none can be found + local function find_potential_portal_location_on_island(island_info) + + local result = nil + + if island_info ~= nil then + local searchRadius = island_info.radius * 0.6 -- islands normally don't reach their full radius, and lets not put portals too near the edge + local coreList = cloudlands.get_island_details( + {x = island_info.x - searchRadius, z = island_info.z - searchRadius}, + {x = island_info.x + searchRadius, z = island_info.z + searchRadius} + ); + + -- Deterministically sample the island for a low location that isn't water. + -- Seed the prng so this function always returns the same coords for the island + local prng = PcgRandom(island_info.x * 65732 + island_info.z * 729 + minetest.get_mapgen_setting("seed") * 3) + local positions = {} + + for attempt = 1, 15 do -- how many attempts we'll make at finding a good location + local angle = (prng:next(0, 10000) / 10000) * 2 * PI + local distance = math_sqrt(prng:next(0, 10000) / 10000) * searchRadius + if attempt == 1 then distance = 0 end -- Always sample the middle of the island, as it's the safest fallback location + local x = round(island_info.x + math_cos(angle) * distance) + local z = round(island_info.z + math_sin(angle) * distance) + local y, isWater = cloudlands.get_height_at(x, z, coreList) + if y ~= nil then + local weight = 0 + if not isWater then weight = weight + 1 end -- avoid putting portals in ponds + if y >= island_info.y + ALTITUDE then weight = weight + 2 end -- avoid putting portals down the sides of eroded cliffs + positions[#positions + 1] = {x = x, y = y + 1, z = z, weight = weight} + end + end + + -- Order the locations by how good they are + local compareFn = function(pos_a, pos_b) + if pos_a.weight > pos_b.weight then return true end + if pos_a.weight == pos_b.weight and pos_a.y < pos_b.y then return true end -- I can't justify why I think lower positions are better. I'm imagining portals nested in valleys rather than on ridges. + return false + end + table.sort(positions, compareFn) + + -- Now the locations are sorted by how good they are, find the first/best that doesn't + -- grief a player build. + -- Ancient Portalstone has is_ground_content set to true, so we won't have to worry about + -- old/broken portal frames interfering with the results of nether.volume_is_natural() + for _, position in ipairs(positions) do + -- Unfortunately, at this point we don't know the orientation of the portal, so use worst case + local minp = {x = position.x - 2, y = position.y, z = position.z - 2} + local maxp = {x = position.x + 3, y = position.y + 4, z = position.z + 3} + if nether.volume_is_natural(minp, maxp) then + result = position + break + end + end + end + + return result + end + + + -- returns nil if no suitable location could be found, otherwise returns (portal_pos, island_info) + local function find_nearest_island_location_for_portal(surface_x, surface_z) + + local result = nil + + local island = cloudlands.find_nearest_island(surface_x, surface_z, 75) + if island == nil then island = cloudlands.find_nearest_island(surface_x, surface_z, 150) end + if island == nil then island = cloudlands.find_nearest_island(surface_x, surface_z, 400) end + + if island ~= nil then + result = find_potential_portal_location_on_island(island) + end + + return result, island + end + + -- Ideally the Nether mod will provide a block obtainable by exploring the Nether which is + -- earmarked for mods like this one to use for portals, but until this happens I'll create + -- our own tempory placeholder "portalstone". + local portalstone_end = "default_furnace_top.png^(default_ice.png^[opacity:120)^[multiply:#668" -- this gonna look bad with non-default texturepacks, hopefully Nether mod will provide a real block + local portalstone_side = "[combine:16x16:0,0=default_furnace_top.png:4,0=default_furnace_top.png:8,0=default_furnace_top.png:12,0=default_furnace_top.png:^(default_ice.png^[opacity:120)^[multiply:#668" + minetest.register_node("cloudlands:ancient_portalstone", { + description = S("Ancient Portalstone"), + tiles = {portalstone_end, portalstone_end, portalstone_side, portalstone_side, portalstone_side, portalstone_side}, + paramtype2 = "facedir", + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 1, level = 2}, + on_blast = function() --[[blast proof]] end + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "cloudlands:ancient_portalstone", + wherein = "nether:rack", + clust_scarcity = 28 * 28 * 28, + clust_num_ores = 6, + clust_size = 3, + y_max = nether.DEPTH, + y_min = nether.DEPTH_FLOOR or -32000, + }) + + local _ = {name = "air", prob = 0} + local A = {name = "air", prob = 255, force_place = true} + local PU = {name = "cloudlands:ancient_portalstone", param2 = 0, prob = 255, force_place = true} + local PW = {name = "cloudlands:ancient_portalstone", param2 = 12, prob = 255, force_place = true} + local PN = {name = "cloudlands:ancient_portalstone", param2 = 4, prob = 255, force_place = true} + minetest.register_decoration({ + name = "Ancient broken portal", + deco_type = "schematic", + place_on = "nether:rack", + sidelen = 80, + fill_ratio = 0.0003, + biomes = {"nether_caverns"}, + y_max = nether.DEPTH, + y_min = nether.DEPTH_FLOOR or -32000, + schematic = { + size = {x = 4, y = 4, z = 1}, + data = { + PN, A, PW, PN, + PU, A, A, PU, + A, _, _, PU, + _, _, _, PU + }, + yslice_prob = { + {ypos = 3, prob = 92}, + {ypos = 1, prob = 30}, + } + }, + place_offset_y = 1, + flags = "force_placement,all_floors", + rotation = "random" + }) + + addDetail_ancientPortal = function(core) + + if (core.radius < 8 or PORTAL_RARITY == 0) then return false end -- avoid portals hanging off the side of small islands + + local fastHash = 3 + fastHash = (37 * fastHash) + core.x + fastHash = (37 * fastHash) + core.z + fastHash = (37 * fastHash) + math_floor(core.radius) + fastHash = (37 * fastHash) + math_floor(core.depth) + fastHash = (37 * fastHash) + ISLANDS_SEED + fastHash = (37 * fastHash) + 9354 -- to keep this probability distinct from reefs and atols + if (PORTAL_RARITY * 10000) < math_floor((math_abs(fastHash)) % 10000) then return false end + + local portalPos = find_potential_portal_location_on_island(core) + + if portalPos ~= nil then + local orientation = (fastHash % 2) * 90 + portalPos.y = portalPos.y - ((core.x + core.z) % 3) -- partially bury some ancient portals + + minetest.place_schematic( + portalPos, + { + size = {x = 4, y = 5, z = 1}, + data = { + PN, PW, PW, PN, + PU, _, _, PU, + PU, _, _, PU, + PU, _, _, PU, + PN, PW, PW, PN + }, + }, + orientation, + { -- node replacements + ["default:obsidian"] = "cloudlands:ancient_portalstone", + }, + true + ) + end + end + + + nether.register_portal("cloudlands_portal", { + shape = nether.PortalShape_Traditional, + frame_node_name = "cloudlands:ancient_portalstone", + wormhole_node_color = 2, -- 2 is blue + particle_color = "#77F", + particle_texture = { + name = "nether_particle_anim1.png", + animation = { + type = "vertical_frames", + aspect_w = 7, + aspect_h = 7, + length = 1, + }, + scale = 1.5 + }, + title = S("Hallelujah Mountains Portal"), + book_of_portals_pagetext = + S("Construction requires 14 blocks of ancient portalstone. We have no knowledge of how portalstones were created, the means to craft them are likely lost to time, so our only source has been to scavenge the Nether for the remnants of ancient broken portals. A finished frame is four blocks wide, five blocks high, and stands vertically, like a doorway.") .. "\n\n" .. + S("The only portal we managed to scavenge enough portalstone to build took us to a land of floating islands. There were hills and forests and even water up there, but the edges are a perilous drop — a depth of which we cannot even begin to plumb."), + + is_within_realm = function(pos) + -- return true if pos is in the cloudlands + -- I'm doing this based off height for speed, so it sometimes gets it wrong when the + -- Hallelujah mountains start reaching the ground. + local largestCoreType = cloudlands.coreTypes[1] -- the first island type is the biggest/thickest + local island_bottom = ALTITUDE - (largestCoreType.depthMax * 0.66) + round(noise_heightMap:get2d({x = pos.x, y = pos.z})) + return pos.y > math_max(40, island_bottom) + end, + + find_realm_anchorPos = function(surface_anchorPos) + -- Find the nearest island and obtain a suitable surface position on it + local destination_pos, island = find_nearest_island_location_for_portal(surface_anchorPos.x, surface_anchorPos.z) + + if island ~= nil then + -- Allow any existing or player-positioned portal on the island to be linked to + -- first before resorting to the island's default portal position + local existing_portal_location, existing_portal_orientation = nether.find_nearest_working_portal( + "cloudlands_portal", + {x = island.x, y = 100000, z = island.z}, -- Using 100000 for y to ensure the position is in the cloudlands realm and so find_nearest_working_portal() will only returns island portals. + island.radius * 0.9, -- Islands normally don't reach their full radius. Ensure this distance limit encompasses any location find_nearest_island_location_for_portal() can return. + 0 -- a y_factor of 0 makes the search ignore the altitude of the portals (as long as they are in the Cloudlands realm) + ) + if existing_portal_location ~= nil then + return existing_portal_location, existing_portal_orientation + end + end + + return destination_pos + end, + + find_surface_anchorPos = function(realm_anchorPos) + -- This function isn't needed since find_surface_target_y() will be used by default, + -- but by implementing it I can look for any existing nearby portals before falling + -- back to find_surface_target_y. + + -- Using -100000 for y to ensure the position is outside the cloudlands realm and so + -- find_nearest_working_portal() will only returns surface portals. + -- a y_factor of 0 makes the search ignore the -100000 altitude of the portals (as + -- long as they are outside the cloudlands realm) + local existing_portal_location, existing_portal_orientation = + nether.find_nearest_working_portal("cloudlands_portal", {x = realm_anchorPos.x, y = -100000, z = realm_anchorPos.z}, 150, 0) + + if existing_portal_location ~= nil then + return existing_portal_location, existing_portal_orientation + else + local y = nether.find_surface_target_y(realm_anchorPos.x, realm_anchorPos.z, "cloudlands_portal") + return {x = realm_anchorPos.x, y = y, z = realm_anchorPos.z} + end + end, + + on_ignite = function(portalDef, anchorPos, orientation) + -- make some sparks fly on ignition + local p1, p2 = portalDef.shape:get_p1_and_p2_from_anchorPos(anchorPos, orientation) + local pos = vector.divide(vector.add(p1, p2), 2) + + local textureName = portalDef.particle_texture + if type(textureName) == "table" then textureName = textureName.name end + + local velocity + if orientation == 0 then + velocity = {x = 0, y = 0, z = 7} + else + velocity = {x = 7, y = 0, z = 0} + end + + local particleSpawnerDef = { + amount = 180, + time = 0.15, + minpos = {x = pos.x - 1, y = pos.y - 1.5, z = pos.z - 1}, + maxpos = {x = pos.x + 1, y = pos.y + 1.5, z = pos.z + 1}, + minvel = velocity, + maxvel = velocity, + minacc = {x = 0, y = 0, z = 0}, + maxacc = {x = 0, y = 0, z = 0}, + minexptime = 0.1, + maxexptime = 0.5, + minsize = 0.3 * portalDef.particle_texture_scale, + maxsize = 0.8 * portalDef.particle_texture_scale, + collisiondetection = false, + texture = textureName .. "^[colorize:#99F:alpha", + animation = portalDef.particle_texture_animation, + glow = 8 + } + + minetest.add_particlespawner(particleSpawnerDef) + + velocity = vector.multiply(velocity, -1); + particleSpawnerDef.minvel, particleSpawnerDef.maxvel = velocity, velocity + minetest.add_particlespawner(particleSpawnerDef) + end + + }) +end + +--[[============================== + SkyTrees + ==============================]]-- + +-- If splitting SkyTrees into a seperate mod, perhaps schemlib would be of help - https://forum.minetest.net/viewtopic.php?t=18084 + + +if not minetest.global_exists("SkyTrees") then -- If SkyTrees added into other mods, this may have already been defined + + local TREE1_FILE = 'cloudlands_tree1.mts' + local TREE2_FILE = 'cloudlands_tree2.mts' + local BARK_SUFFIX = '_bark' + local GLOW_SUFFIX = '_glow' + + SkyTrees = { + -- Order the trees in this schematicInfo array from the largest island requirements to smallest + -- The data in each schematicInfo must exactly match what's in the .mts file or things will break + schematicInfo = { + { + filename = TREE1_FILE, + size = {x = 81, y = 106, z = 111}, + center = {x = 37, y = 11, z = 73}, + requiredIslandDepth = 20, + requiredIslandRadius = 40, + nodesWithConstructor = { + {x=35, y=69, z=1}, {x=61, y=51, z=2}, {x=36, y=68, z=2}, {x=68, y=48, z=3}, {x=61, y=50, z=4}, {x=71, y=50, z=5}, {x=58, y=52, z=5}, {x=65, y=50, z=9}, {x=72, y=53, z=11}, {x=41, y=67, z=12}, {x=63, y=48, z=13}, {x=69, y=52, z=13}, {x=33, y=66, z=14}, {x=39, y=68, z=15}, {x=72, y=68, z=15}, {x=40, y=67, z=16}, {x=39, y=66, z=17}, {x=68, y=45, z=19}, {x=69, y=44, z=20}, {x=72, y=55, z=20}, {x=66, y=56, z=20}, {x=58, y=66, z=20}, {x=71, y=58, z=21}, {x=68, y=45, z=22}, {x=70, y=51, z=22}, {x=73, y=55, z=22}, {x=36, y=62, z=22}, {x=70, y=67, z=22}, {x=21, y=65, z=23}, {x=22, y=66, z=23}, {x=53, y=66, z=23}, {x=70, y=68, z=23}, {x=73, y=54, z=24}, {x=75, y=57, z=24}, {x=37, y=63, z=24}, {x=7, y=68, z=24}, {x=69, y=56, z=25}, {x=34, y=58, z=25}, {x=66, y=62, z=25}, {x=64, y=66, z=25}, {x=6, y=67, z=25}, {x=3, y=68, z=25}, {x=68, y=56, z=26}, {x=65, y=57, z=26}, {x=61, y=63, z=26}, {x=31, y=59, z=27}, {x=48, y=62, z=27}, {x=50, y=63, z=27}, {x=78, y=65, z=27}, {x=78, y=52, z=28}, {x=68, y=57, z=28}, {x=76, y=57, z=28}, {x=31, y=60, z=28}, {x=15, y=63, z=28}, {x=16, y=63, z=28}, {x=66, y=64, z=28}, {x=60, y=65, z=28}, {x=61, y=76, z=28}, {x=63, y=76, z=28}, {x=69, y=59, z=29}, {x=51, y=65, z=29}, {x=72, y=57, z=30}, {x=20, y=60, z=30}, {x=21, y=61, z=30}, {x=49, y=65, z=30}, {x=52, y=53, z=31}, {x=72, y=57, z=31}, {x=36, y=58, z=31}, {x=63, y=60, z=31}, {x=54, y=63, z=31}, {x=45, y=65, z=31}, {x=79, y=66, z=31}, {x=62, y=70, z=31}, {x=55, y=103, z=31}, {x=52, y=53, z=32}, {x=68, y=60, z=32}, {x=19, y=61, z=32}, {x=53, y=63, z=32}, {x=37, y=64, z=32}, {x=21, y=65, z=32}, {x=56, y=65, z=32}, {x=59, y=71, z=32}, {x=35, y=74, z=32}, {x=23, y=75, z=32}, {x=35, y=58, z=33}, {x=62, y=60, z=33}, {x=18, y=63, z=33}, {x=73, y=67, z=33}, {x=37, y=74, z=33}, {x=65, y=75, z=33}, {x=38, y=2, z=34}, {x=67, y=52, z=34}, {x=71, y=60, z=34}, {x=25, y=63, z=34}, {x=19, y=64, z=34}, {x=32, y=66, z=34}, {x=66, y=72, z=34}, {x=41, y=81, z=34}, {x=45, y=93, z=34}, {x=54, y=99, z=34}, {x=38, y=5, z=35}, {x=68, y=48, z=35}, {x=69, y=51, z=35}, {x=48, y=53, z=35}, {x=37, y=57, z=35}, {x=77, y=58, z=35}, {x=32, y=60, z=35}, {x=20, y=61, z=35}, {x=27, y=61, z=35}, {x=33, y=65, z=35}, {x=58, y=65, z=35}, {x=58, y=72, z=35}, {x=60, y=73, z=35}, {x=30, y=74, z=35}, {x=41, y=74, z=35}, {x=41, y=87, z=35}, {x=22, y=58, z=36}, {x=64, y=58, z=36}, {x=39, y=70, z=36}, {x=36, y=77, z=36}, {x=44, y=83, z=36}, {x=40, y=86, z=36}, {x=35, y=56, z=37}, {x=65, y=59, z=37}, {x=66, y=62, z=37}, {x=62, y=67, z=37}, {x=39, y=68, z=37}, {x=40, y=86, z=37}, {x=53, y=88, z=37}, {x=43, y=97, z=37}, {x=52, y=99, z=37}, {x=37, y=3, z=38}, {x=35, y=55, z=38}, {x=38, y=56, z=38}, {x=25, y=57, z=38}, {x=65, y=57, z=38}, {x=71, y=61, z=38}, {x=33, y=65, z=38}, {x=61, y=65, z=38}, {x=50, y=66, z=38}, {x=38, y=68, z=38}, {x=46, y=97, z=38}, {x=44, y=100, z=38}, {x=51, y=102, z=38}, {x=29, y=42, z=39}, {x=27, y=43, z=39}, {x=70, y=48, z=39}, {x=72, y=52, z=39}, {x=23, y=57, z=39}, {x=26, y=57, z=39}, {x=28, y=58, z=39}, {x=55, y=58, z=39}, {x=73, y=59, z=39}, {x=65, y=65, z=39}, {x=41, y=68, z=39}, {x=42, y=81, z=39}, {x=55, y=88, z=39}, {x=43, y=91, z=39}, {x=45, y=100, z=39}, {x=23, y=57, z=40}, {x=29, y=57, z=40}, {x=76, y=58, z=40}, {x=73, y=59, z=40}, {x=78, y=59, z=40}, {x=31, y=60, z=40}, {x=64, y=64, z=40}, {x=41, y=67, z=40}, {x=42, y=75, z=40}, {x=37, y=78, z=40}, {x=42, y=92, z=40}, {x=51, y=101, z=40}, {x=48, y=105, z=40}, {x=75, y=59, z=41}, {x=55, y=63, z=41}, {x=35, y=68, z=41}, {x=35, y=69, z=41}, {x=35, y=71, z=41}, {x=34, y=42, z=42}, {x=29, y=55, z=42}, {x=50, y=61, z=42}, {x=34, y=65, z=42}, {x=57, y=88, z=42}, {x=48, y=89, z=42}, {x=49, y=89, z=42}, {x=27, y=22, z=43}, {x=26, y=28, z=43}, {x=31, y=46, z=43}, {x=66, y=52, z=43}, {x=49, y=57, z=43}, {x=56, y=57, z=43}, {x=41, y=69, z=43}, {x=36, y=52, z=44}, {x=63, y=54, z=44}, {x=51, y=55, z=44}, {x=57, y=56, z=44}, {x=69, y=57, z=44}, {x=64, y=65, z=44}, {x=55, y=90, z=44}, {x=30, y=42, z=45}, {x=31, y=52, z=45}, {x=51, y=54, z=45}, {x=24, y=57, z=45}, {x=70, y=62, z=45}, {x=39, y=69, z=45}, {x=35, y=80, z=45}, {x=29, y=81, z=45}, {x=44, y=85, z=45}, {x=41, y=86, z=45}, {x=33, y=9, z=46}, {x=28, y=44, z=46}, {x=50, y=54, z=46}, {x=47, y=55, z=46}, {x=45, y=56, z=46}, {x=45, y=58, z=46}, {x=47, y=58, z=46}, {x=30, y=63, z=46}, {x=27, y=81, z=46}, {x=28, y=81, z=46}, {x=40, y=86, z=46}, {x=29, y=16, z=47}, {x=32, y=10, z=48}, {x=66, y=49, z=48}, {x=29, y=52, z=48}, {x=53, y=54, z=48}, {x=55, y=54, z=48}, {x=61, y=58, z=48}, {x=59, y=61, z=48}, {x=50, y=63, z=48}, {x=26, y=82, z=48}, {x=43, y=85, z=48}, {x=48, y=86, z=48}, {x=31, y=19, z=49}, {x=30, y=46, z=49}, {x=63, y=51, z=49}, {x=41, y=53, z=49}, {x=31, y=60, z=49}, {x=67, y=1, z=50}, {x=37, y=8, z=50}, {x=40, y=30, z=50}, {x=43, y=57, z=50}, {x=59, y=57, z=50}, {x=60, y=57, z=50}, {x=29, y=61, z=50}, {x=34, y=63, z=50}, {x=49, y=65, z=50}, {x=65, y=3, z=51}, {x=45, y=29, z=51}, {x=41, y=58, z=51}, {x=42, y=60, z=51}, {x=46, y=64, z=51}, {x=47, y=67, z=51}, {x=52, y=68, z=51}, {x=69, y=51, z=52}, {x=53, y=55, z=52}, {x=45, y=62, z=52}, {x=64, y=2, z=53}, {x=3, y=3, z=53}, {x=10, y=6, z=53}, {x=31, y=14, z=53}, {x=37, y=35, z=53}, {x=43, y=48, z=53}, {x=71, y=50, z=53}, {x=52, y=54, z=53}, {x=43, y=57, z=53}, {x=55, y=57, z=53}, {x=52, y=67, z=53}, {x=48, y=72, z=53}, {x=5, y=1, z=54}, {x=9, y=4, z=54}, {x=62, y=4, z=54}, {x=33, y=8, z=54}, {x=42, y=29, z=54}, {x=42, y=32, z=54}, {x=43, y=34, z=54}, {x=41, y=39, z=54}, {x=41, y=57, z=54}, {x=34, y=61, z=54}, {x=58, y=2, z=55}, {x=59, y=3, z=55}, {x=38, y=7, z=55}, {x=40, y=12, z=55}, {x=38, y=39, z=55}, {x=33, y=46, z=55}, {x=28, y=54, z=55}, {x=29, y=55, z=55}, {x=30, y=57, z=55}, {x=54, y=58, z=55}, {x=52, y=63, z=55}, {x=37, y=7, z=56}, {x=55, y=8, z=56}, {x=33, y=45, z=56}, {x=58, y=0, z=57}, {x=9, y=5, z=57}, {x=34, y=7, z=57}, {x=54, y=8, z=57}, {x=17, y=9, z=57}, {x=32, y=12, z=57}, {x=37, y=39, z=57}, {x=41, y=45, z=57}, {x=31, y=46, z=57}, {x=49, y=50, z=57}, {x=50, y=56, z=57}, {x=46, y=59, z=57}, {x=48, y=66, z=57}, {x=51, y=67, z=57}, {x=15, y=3, z=58}, {x=8, y=10, z=58}, {x=41, y=11, z=58}, {x=40, y=13, z=58}, {x=42, y=45, z=58}, {x=50, y=51, z=58}, {x=20, y=5, z=59}, {x=19, y=7, z=59}, {x=22, y=8, z=59}, {x=23, y=9, z=59}, {x=40, y=13, z=59}, {x=33, y=14, z=59}, {x=42, y=41, z=59}, {x=20, y=6, z=60}, {x=9, y=8, z=60}, {x=46, y=8, z=60}, {x=34, y=39, z=60}, {x=30, y=52, z=60}, {x=43, y=57, z=60}, {x=18, y=5, z=61}, {x=11, y=10, z=61}, {x=36, y=36, z=61}, {x=47, y=55, z=61}, {x=38, y=56, z=61}, {x=61, y=59, z=61}, {x=56, y=60, z=61}, {x=36, y=6, z=62}, {x=55, y=7, z=62}, {x=26, y=10, z=62}, {x=29, y=13, z=62}, {x=46, y=13, z=62}, {x=57, y=60, z=62}, {x=18, y=7, z=63}, {x=30, y=11, z=63}, {x=53, y=13, z=63}, {x=45, y=14, z=63}, {x=36, y=32, z=63}, {x=46, y=41, z=63}, {x=29, y=43, z=63}, {x=29, y=44, z=63}, {x=29, y=46, z=63}, {x=29, y=50, z=63}, {x=30, y=52, z=63}, {x=46, y=54, z=63}, {x=19, y=6, z=64}, {x=54, y=8, z=64}, {x=16, y=11, z=64}, {x=42, y=16, z=64}, {x=36, y=25, z=64}, {x=37, y=27, z=64}, {x=36, y=28, z=64}, {x=37, y=29, z=64}, {x=40, y=33, z=64}, {x=30, y=36, z=64}, {x=43, y=39, z=64}, {x=62, y=61, z=64}, {x=21, y=6, z=65}, {x=24, y=6, z=65}, {x=53, y=10, z=65}, {x=52, y=12, z=65}, {x=27, y=17, z=65}, {x=39, y=17, z=65}, {x=29, y=19, z=65}, {x=32, y=22, z=65}, {x=28, y=42, z=65}, {x=60, y=61, z=65}, {x=24, y=6, z=66}, {x=26, y=6, z=66}, {x=19, y=12, z=66}, {x=28, y=20, z=66}, {x=31, y=26, z=66}, {x=39, y=55, z=66}, {x=42, y=6, z=67}, {x=24, y=7, z=67}, {x=20, y=14, z=67}, {x=41, y=21, z=67}, {x=28, y=22, z=67}, {x=29, y=46, z=67}, + {x=34, y=52, z=67}, {x=45, y=17, z=68}, {x=42, y=25, z=68}, {x=28, y=43, z=68}, {x=46, y=44, z=68}, {x=29, y=7, z=69}, {x=49, y=12, z=69}, {x=29, y=43, z=69}, {x=48, y=9, z=70}, {x=45, y=17, z=70}, {x=36, y=9, z=71}, {x=47, y=10, z=71}, {x=25, y=11, z=71}, {x=45, y=17, z=71}, {x=42, y=46, z=71}, {x=34, y=47, z=71}, {x=35, y=48, z=71}, {x=45, y=10, z=72}, {x=25, y=12, z=72}, {x=45, y=35, z=72}, {x=45, y=43, z=72}, {x=36, y=52, z=72}, {x=39, y=55, z=72}, {x=26, y=19, z=73}, {x=27, y=21, z=73}, {x=26, y=27, z=73}, {x=26, y=29, z=73}, {x=43, y=31, z=73}, {x=28, y=36, z=73}, {x=42, y=41, z=73}, {x=34, y=46, z=73}, {x=39, y=59, z=73}, {x=24, y=9, z=74}, {x=48, y=9, z=74}, {x=35, y=48, z=74}, {x=35, y=51, z=74}, {x=42, y=53, z=74}, {x=33, y=57, z=74}, {x=30, y=60, z=74}, {x=47, y=8, z=75}, {x=22, y=12, z=75}, {x=45, y=18, z=75}, {x=27, y=30, z=75}, {x=45, y=33, z=75}, {x=36, y=49, z=75}, {x=36, y=1, z=76}, {x=45, y=7, z=76}, {x=21, y=14, z=76}, {x=44, y=23, z=76}, {x=29, y=35, z=76}, {x=38, y=40, z=76}, {x=39, y=42, z=76}, {x=33, y=58, z=76}, {x=34, y=1, z=77}, {x=21, y=7, z=77}, {x=18, y=11, z=77}, {x=26, y=23, z=77}, {x=43, y=25, z=77}, {x=41, y=32, z=77}, {x=36, y=41, z=77}, {x=39, y=47, z=77}, {x=35, y=56, z=77}, {x=35, y=1, z=78}, {x=26, y=3, z=78}, {x=34, y=3, z=78}, {x=18, y=9, z=78}, {x=27, y=23, z=78}, {x=51, y=33, z=78}, {x=41, y=37, z=78}, {x=36, y=1, z=79}, {x=25, y=2, z=79}, {x=18, y=8, z=79}, {x=15, y=10, z=79}, {x=14, y=11, z=79}, {x=27, y=23, z=79}, {x=28, y=25, z=79}, {x=45, y=32, z=79}, {x=33, y=34, z=79}, {x=34, y=34, z=79}, {x=37, y=55, z=79}, {x=40, y=62, z=79}, {x=27, y=0, z=80}, {x=31, y=18, z=80}, {x=30, y=26, z=80}, {x=34, y=61, z=80}, {x=20, y=7, z=81}, {x=51, y=7, z=81}, {x=25, y=8, z=81}, {x=53, y=8, z=81}, {x=42, y=10, z=81}, {x=56, y=12, z=81}, {x=21, y=15, z=81}, {x=37, y=28, z=81}, {x=36, y=29, z=81}, {x=37, y=29, z=81}, {x=44, y=35, z=81}, {x=22, y=7, z=82}, {x=26, y=8, z=82}, {x=29, y=8, z=82}, {x=44, y=9, z=82}, {x=42, y=10, z=82}, {x=32, y=13, z=82}, {x=13, y=14, z=82}, {x=29, y=22, z=82}, {x=31, y=25, z=82}, {x=35, y=27, z=82}, {x=27, y=60, z=82}, {x=41, y=64, z=82}, {x=20, y=8, z=83}, {x=57, y=8, z=83}, {x=24, y=9, z=83}, {x=58, y=9, z=83}, {x=36, y=22, z=83}, {x=32, y=24, z=83}, {x=47, y=8, z=84}, {x=56, y=8, z=84}, {x=59, y=11, z=84}, {x=45, y=13, z=84}, {x=58, y=13, z=84}, {x=17, y=14, z=84}, {x=23, y=14, z=84}, {x=56, y=14, z=84}, {x=29, y=19, z=84}, {x=36, y=19, z=84}, {x=27, y=59, z=84}, {x=35, y=6, z=85}, {x=9, y=8, z=85}, {x=41, y=11, z=85}, {x=50, y=13, z=85}, {x=33, y=58, z=85}, {x=34, y=58, z=85}, {x=33, y=7, z=86}, {x=18, y=10, z=86}, {x=9, y=12, z=86}, {x=41, y=12, z=87}, {x=41, y=60, z=87}, {x=9, y=2, z=88}, {x=7, y=5, z=88}, {x=5, y=10, z=88}, {x=41, y=11, z=88}, {x=62, y=11, z=88}, {x=42, y=68, z=88}, {x=37, y=6, z=89}, {x=66, y=8, z=89}, {x=9, y=10, z=89}, {x=19, y=10, z=89}, {x=58, y=12, z=89}, {x=45, y=62, z=89}, {x=7, y=5, z=90}, {x=67, y=5, z=90}, {x=7, y=9, z=90}, {x=31, y=11, z=90}, {x=62, y=11, z=90}, {x=1, y=2, z=91}, {x=5, y=5, z=91}, {x=69, y=5, z=91}, {x=62, y=8, z=91}, {x=58, y=9, z=91}, {x=63, y=10, z=91}, {x=35, y=7, z=92}, {x=62, y=9, z=92}, {x=33, y=13, z=92}, {x=36, y=62, z=92}, {x=37, y=3, z=93}, {x=37, y=6, z=93}, {x=64, y=6, z=93}, {x=32, y=10, z=93}, {x=34, y=14, z=93}, {x=39, y=57, z=93}, {x=41, y=67, z=93}, {x=33, y=9, z=94}, {x=38, y=57, z=94}, {x=41, y=69, z=94}, {x=40, y=1, z=95}, {x=34, y=7, z=97}, {x=33, y=9, z=97}, {x=33, y=10, z=102}, {x=33, y=7, z=105}, {x=35, y=9, z=107} + } + }, + { + filename = TREE2_FILE, + size = {x = 62, y = 65, z = 65}, + center = {x = 30, y = 12, z = 36}, + requiredIslandDepth = 16, + requiredIslandRadius = 24, + nodesWithConstructor = { {x=35, y=53, z=1}, {x=33, y=59, z=1}, {x=32, y=58, z=3}, {x=31, y=57, z=5}, {x=40, y=58, z=6}, {x=29, y=57, z=7}, {x=39, y=51, z=8}, {x=52, y=53, z=8}, {x=32, y=53, z=9}, {x=25, y=58, z=9}, {x=51, y=51, z=10}, {x=47, y=50, z=11}, {x=50, y=55, z=11}, {x=28, y=57, z=11}, {x=26, y=39, z=12}, {x=30, y=39, z=12}, {x=24, y=40, z=12}, {x=53, y=52, z=12}, {x=29, y=57, z=12}, {x=43, y=59, z=12}, {x=26, y=39, z=13}, {x=36, y=48, z=13}, {x=27, y=39, z=14}, {x=39, y=48, z=14}, {x=33, y=50, z=14}, {x=43, y=50, z=14}, {x=24, y=59, z=14}, {x=41, y=49, z=15}, {x=33, y=12, z=16}, {x=36, y=46, z=16}, {x=50, y=51, z=16}, {x=46, y=57, z=16}, {x=36, y=45, z=17}, {x=27, y=46, z=17}, {x=22, y=48, z=17}, {x=45, y=50, z=17}, {x=31, y=38, z=18}, {x=32, y=38, z=18}, {x=39, y=46, z=18}, {x=51, y=51, z=18}, {x=31, y=11, z=19}, {x=32, y=38, z=19}, {x=39, y=41, z=19}, {x=45, y=57, z=19}, {x=29, y=58, z=19}, {x=28, y=60, z=20}, {x=38, y=40, z=21}, {x=30, y=58, z=21}, {x=31, y=13, z=22}, {x=20, y=41, z=22}, {x=22, y=43, z=22}, {x=20, y=48, z=22}, {x=22, y=39, z=23}, {x=49, y=50, z=23}, {x=52, y=52, z=23}, {x=53, y=53, z=23}, {x=32, y=55, z=23}, {x=36, y=59, z=23}, {x=31, y=60, z=23}, {x=25, y=46, z=24}, {x=40, y=56, z=24}, {x=34, y=58, z=24}, {x=38, y=58, z=24}, {x=32, y=39, z=25}, {x=40, y=46, z=25}, {x=39, y=55, z=25}, {x=36, y=45, z=26}, {x=12, y=7, z=28}, {x=34, y=33, z=28}, {x=31, y=36, z=28}, {x=37, y=41, z=28}, {x=14, y=60, z=28}, {x=19, y=13, z=29}, {x=12, y=43, z=29}, {x=8, y=45, z=29}, {x=31, y=46, z=29}, {x=39, y=47, z=29}, {x=13, y=60, z=29}, {x=22, y=63, z=29}, {x=51, y=9, z=30}, {x=32, y=39, z=30}, {x=33, y=40, z=30}, {x=34, y=44, z=30}, {x=22, y=1, z=31}, {x=24, y=2, z=31}, {x=20, y=7, z=31}, {x=51, y=9, z=31}, {x=16, y=12, z=31}, {x=34, y=27, z=31}, {x=22, y=43, z=31}, {x=27, y=44, z=31}, {x=23, y=51, z=31}, {x=42, y=58, z=31}, {x=9, y=60, z=31}, {x=22, y=5, z=32}, {x=22, y=6, z=32}, {x=50, y=10, z=32}, {x=53, y=11, z=32}, {x=41, y=15, z=32}, {x=43, y=15, z=32}, {x=31, y=21, z=32}, {x=31, y=28, z=32}, {x=12, y=42, z=32}, {x=15, y=42, z=32}, {x=13, y=48, z=32}, {x=37, y=49, z=32}, {x=18, y=59, z=32}, {x=52, y=9, z=33}, {x=40, y=10, z=33}, {x=43, y=10, z=33}, {x=22, y=11, z=33}, {x=27, y=11, z=33}, {x=50, y=11, z=33}, {x=22, y=15, z=33}, {x=36, y=29, z=33}, {x=33, y=37, z=33}, {x=9, y=42, z=33}, {x=14, y=42, z=33}, {x=18, y=43, z=33}, {x=23, y=43, z=33}, {x=33, y=49, z=33}, {x=43, y=53, z=33}, {x=54, y=53, z=33}, {x=31, y=55, z=33}, {x=23, y=58, z=33}, {x=43, y=10, z=34}, {x=44, y=10, z=34}, {x=32, y=12, z=34}, {x=46, y=13, z=34}, {x=28, y=29, z=34}, {x=20, y=42, z=34}, {x=39, y=50, z=34}, {x=51, y=52, z=34}, {x=54, y=52, z=34}, {x=35, y=55, z=34}, {x=51, y=56, z=34}, {x=35, y=5, z=35}, {x=34, y=8, z=35}, {x=33, y=10, z=35}, {x=49, y=10, z=35}, {x=43, y=14, z=35}, {x=36, y=35, z=35}, {x=30, y=47, z=35}, {x=9, y=48, z=35}, {x=39, y=51, z=35}, {x=56, y=52, z=35}, {x=40, y=56, z=35}, {x=13, y=59, z=35}, {x=26, y=62, z=35}, {x=28, y=13, z=36}, {x=38, y=17, z=36}, {x=38, y=20, z=36}, {x=27, y=26, z=36}, {x=38, y=35, z=36}, {x=24, y=39, z=36}, {x=6, y=43, z=36}, {x=13, y=57, z=36}, {x=48, y=7, z=37}, {x=33, y=8, z=37}, {x=50, y=9, z=37}, {x=36, y=11, z=37}, {x=27, y=20, z=37}, {x=27, y=22, z=37}, {x=38, y=24, z=37}, {x=33, y=34, z=37}, {x=9, y=42, z=37}, {x=14, y=42, z=37}, {x=25, y=42, z=37}, {x=53, y=50, z=37}, {x=33, y=53, z=37}, {x=54, y=59, z=37}, {x=28, y=21, z=38}, {x=39, y=34, z=38}, {x=24, y=35, z=38}, {x=8, y=43, z=38}, {x=6, y=47, z=38}, {x=48, y=51, z=38}, {x=61, y=53, z=38}, {x=26, y=57, z=38}, {x=27, y=57, z=38}, {x=32, y=59, z=38}, {x=29, y=62, z=38}, {x=38, y=62, z=38}, {x=33, y=7, z=39}, {x=34, y=9, z=39}, {x=28, y=23, z=39}, {x=34, y=37, z=39}, {x=19, y=42, z=39}, {x=55, y=50, z=39}, {x=47, y=51, z=39}, {x=11, y=54, z=39}, {x=9, y=60, z=39}, {x=33, y=61, z=39}, {x=33, y=4, z=40}, {x=30, y=11, z=40}, {x=39, y=13, z=40}, {x=36, y=23, z=40}, {x=22, y=38, z=40}, {x=54, y=49, z=40}, {x=53, y=50, z=40}, {x=23, y=54, z=40}, {x=28, y=57, z=40}, {x=29, y=57, z=40}, {x=31, y=29, z=41}, {x=27, y=34, z=41}, {x=30, y=37, z=41}, {x=42, y=38, z=41}, {x=12, y=42, z=41}, {x=15, y=42, z=41}, {x=44, y=44, z=41}, {x=28, y=57, z=41}, {x=55, y=57, z=41}, {x=9, y=59, z=41}, {x=30, y=10, z=42}, {x=26, y=15, z=42}, {x=31, y=15, z=42}, {x=34, y=17, z=42}, {x=28, y=36, z=42}, {x=38, y=44, z=42}, {x=42, y=44, z=42}, {x=46, y=44, z=42}, {x=32, y=47, z=42}, {x=52, y=47, z=42}, {x=39, y=55, z=42}, {x=54, y=56, z=42}, {x=34, y=59, z=42}, {x=40, y=11, z=43}, {x=30, y=14, z=43}, {x=28, y=16, z=43}, {x=34, y=31, z=43}, {x=11, y=43, z=43}, {x=14, y=43, z=43}, {x=28, y=47, z=43}, {x=57, y=50, z=43}, {x=61, y=54, z=43}, {x=30, y=58, z=43}, {x=34, y=59, z=43}, {x=7, y=61, z=43}, {x=41, y=10, z=44}, {x=29, y=15, z=44}, {x=36, y=39, z=44}, {x=6, y=43, z=44}, {x=30, y=47, z=44}, {x=57, y=50, z=44}, {x=38, y=10, z=45}, {x=42, y=10, z=45}, {x=11, y=43, z=45}, {x=14, y=43, z=45}, {x=46, y=44, z=45}, {x=32, y=45, z=45}, {x=55, y=45, z=45}, {x=3, y=48, z=45}, {x=31, y=57, z=45}, {x=41, y=3, z=46}, {x=40, y=7, z=46}, {x=28, y=11, z=46}, {x=23, y=13, z=46}, {x=19, y=43, z=46}, {x=24, y=9, z=47}, {x=39, y=9, z=47}, {x=43, y=12, z=47}, {x=5, y=43, z=47}, {x=42, y=43, z=47}, {x=46, y=43, z=47}, {x=24, y=47, z=47}, {x=60, y=52, z=47}, {x=24, y=54, z=47}, {x=37, y=57, z=47}, {x=11, y=60, z=47}, {x=27, y=9, z=48}, {x=27, y=11, z=48}, {x=22, y=14, z=48}, {x=15, y=44, z=48}, {x=51, y=45, z=48}, {x=23, y=49, z=48}, {x=59, y=53, z=48}, {x=9, y=56, z=48}, {x=33, y=59, z=48}, {x=41, y=14, z=49}, {x=8, y=43, z=49}, {x=10, y=43, z=49}, {x=39, y=43, z=49}, {x=34, y=44, z=49}, {x=47, y=44, z=49}, {x=48, y=44, z=49}, {x=24, y=51, z=49}, {x=10, y=55, z=49}, {x=32, y=59, z=49}, {x=20, y=61, z=49}, {x=11, y=63, z=49}, {x=25, y=8, z=50}, {x=22, y=10, z=50}, {x=42, y=14, z=50}, {x=10, y=43, z=50}, {x=43, y=43, z=50}, {x=61, y=46, z=50}, {x=39, y=54, z=50}, {x=24, y=12, z=51}, {x=50, y=44, z=51}, {x=52, y=45, z=51}, {x=54, y=45, z=51}, {x=2, y=46, z=51}, {x=8, y=51, z=51}, {x=7, y=52, z=51}, {x=37, y=58, z=51}, {x=22, y=50, z=52}, {x=25, y=55, z=52}, {x=39, y=58, z=52}, {x=20, y=7, z=53}, {x=40, y=43, z=53}, {x=58, y=45, z=53}, {x=60, y=50, z=53}, {x=22, y=55, z=53}, {x=28, y=56, z=53}, {x=50, y=62, z=53}, {x=54, y=45, z=54}, {x=61, y=46, z=54}, {x=30, y=47, z=54}, {x=30, y=49, z=54}, {x=53, y=53, z=54}, {x=18, y=55, z=54}, {x=51, y=56, z=54}, {x=46, y=62, z=54}, {x=21, y=56, z=55}, {x=24, y=56, z=55}, {x=38, y=61, z=55}, {x=19, y=49, z=56}, {x=46, y=52, z=56}, {x=47, y=53, z=56}, {x=59, y=47, z=57}, {x=26, y=57, z=57}, {x=45, y=43, z=58}, {x=15, y=50, z=58}, {x=11, y=51, z=58}, {x=50, y=44, z=59}, {x=53, y=47, z=59}, {x=43, y=49, z=59}, {x=18, y=50, z=59}, {x=18, y=51, z=60}, {x=38, y=45, z=61}, {x=50, y=47, z=61}, {x=41, y=48, z=61} }, + } + }, + MODNAME = minetest.get_current_modname() -- don't hardcode incase it's copied into other mods + } + + -- Must be called during mod load time, as it uses minetest.register_node() + -- (add an optional dependency for any mod where the tree & leaf textures might be + -- sourced from, to ensure they are loaded before this is called) + SkyTrees.init = function() + + SkyTrees.minimumIslandRadius = 100000 + SkyTrees.minimumIslandDepth = 100000 + SkyTrees.maximumYOffset = 0 + SkyTrees.maximumHeight = 0 + + SkyTrees.nodeName_sideVines = interop.find_node_name(NODENAMES_VINES) + SkyTrees.nodeName_hangingVine = interop.find_node_name(NODENAMES_HANGINGVINE) + SkyTrees.nodeName_hangingRoot = interop.find_node_name(NODENAMES_HANGINGROOT) + + for i,tree in pairs(SkyTrees.schematicInfo) do + local fullFilename = minetest.get_modpath(SkyTrees.MODNAME) .. DIR_DELIM .. tree.filename + + if not interop.file_exists(fullFilename) then + -- remove the schematic from the list + SkyTrees.schematicInfo[i] = nil + else + SkyTrees.minimumIslandRadius = math_min(SkyTrees.minimumIslandRadius, tree.requiredIslandRadius) + SkyTrees.minimumIslandDepth = math_min(SkyTrees.minimumIslandDepth, tree.requiredIslandDepth) + SkyTrees.maximumYOffset = math_max(SkyTrees.maximumYOffset, tree.center.y) + SkyTrees.maximumHeight = math_max(SkyTrees.maximumHeight, tree.size.y) + + tree.theme = {} + SkyTrees.schematicInfo[tree.filename] = tree -- so schematicInfo of trees can be indexed by name + end + end + + local function generate_woodTypes(nodeName_templateWood, overlay, barkoverlay, nodesuffix, description, dropsTemplateWood) + + local trunkNode = minetest.registered_nodes[nodeName_templateWood] + local newTrunkNode = {} + for key, value in pairs(trunkNode) do newTrunkNode[key] = value end + newTrunkNode.name = SkyTrees.MODNAME .. ":" .. nodesuffix + newTrunkNode.description = description + if dropsTemplateWood then + newTrunkNode.drop = nodeName_templateWood + if newTrunkNode.groups == nil then newTrunkNode.groups = {} end + newTrunkNode.groups.not_in_creative_inventory = 1 + else + newTrunkNode.drop = nil + end + + local tiles = trunkNode.tiles + if type(tiles) == "table" then + newTrunkNode.tiles = {} + for key, value in pairs(tiles) do newTrunkNode.tiles[key] = value .. overlay end + else + newTrunkNode.tiles = tiles .. overlay + end + + local newBarkNode = {} + for key, value in pairs(newTrunkNode) do newBarkNode[key] = value end + newBarkNode.name = newBarkNode.name .. BARK_SUFFIX + newBarkNode.description = S("Bark of @1", newBarkNode.description) + -- .drop: leave the bark nodes dropping the trunk wood + + tiles = trunkNode.tiles + if type(tiles) == "table" then + newBarkNode.tiles = { tiles[#tiles] .. barkoverlay } + end + + --minetest.log("info", newTrunkNode.name .. ": " .. dump(newTrunkNode)) + minetest.register_node(newTrunkNode.name, newTrunkNode) + minetest.register_node(newBarkNode.name, newBarkNode) + return newTrunkNode.name + end + + local function generate_leafTypes(nodeName_templateLeaf, overlay, nodesuffix, description, dropsTemplateLeaf, glowVariantBrightness) + + local leafNode = minetest.registered_nodes[nodeName_templateLeaf] + local newLeafNode = {} + for key, value in pairs(leafNode) do newLeafNode[key] = value end + newLeafNode.name = SkyTrees.MODNAME .. ":" .. nodesuffix + newLeafNode.description = description + newLeafNode.sunlight_propagates = true -- soo many leaves they otherwise blot out the sun. + if dropsTemplateLeaf then + newLeafNode.drop = nodeName_templateLeaf + if newLeafNode.groups == nil then newLeafNode.groups = {} end + newLeafNode.groups.not_in_creative_inventory = 1 + else + newLeafNode.drop = nil + end + + local tiles = leafNode.tiles + if type(tiles) == "table" then + newLeafNode.tiles = {} + for key, value in pairs(tiles) do newLeafNode.tiles[key] = value .. overlay end + else + newLeafNode.tiles = tiles .. overlay + end + + minetest.register_node(newLeafNode.name, newLeafNode) + + if glowVariantBrightness ~= nil and glowVariantBrightness > 0 and BIOLUMINESCENCE then + local glowingLeafNode = {} + for key, value in pairs(newLeafNode) do glowingLeafNode[key] = value end + glowingLeafNode.name = newLeafNode.name .. GLOW_SUFFIX + glowingLeafNode.description = S("Glowing @1", description) + glowingLeafNode.light_source = glowVariantBrightness + minetest.register_node(glowingLeafNode.name, glowingLeafNode) + end + + return newLeafNode.name + end + + local templateWood = interop.find_node_name(NODENAMES_TREEWOOD) + if templateWood == 'ignore' then + SkyTrees.disabled = "Could not find any tree nodes" + return + end + local normalwood = generate_woodTypes(templateWood, "", "", "tree", S("Giant tree"), true) + local darkwood = generate_woodTypes(templateWood, "^[colorize:black:205", "^[colorize:black:205", "darkwood", S("Giant Ziricote"), false) + local deadwood = generate_woodTypes(templateWood, "^[colorize:#EFE6B9:110", "^[colorize:#E8D0A0:110", "deadbleachedwood", S("Dead bleached wood"), false) -- make use of the bark blocks to introduce some color variance in the tree + + + local templateLeaf = interop.find_node_name(NODENAMES_TREELEAVES) + if templateLeaf == 'ignore' then + SkyTrees.disabled = "Could not find any treeleaf nodes" + return + end + local greenleaf1 = generate_leafTypes(templateLeaf, "", "leaves", S("Leaves of a giant tree"), true) -- drops templateLeaf because these look close enough to the original leaves that we won't clutter the game & creative-menu with tiny visual variants that other recipes/parts of the game won't know about + local greenleaf2 = generate_leafTypes(templateLeaf, "^[colorize:#00FF00:16", "leaves2", S("Leaves of a giant tree"), false) + local greenleaf3 = generate_leafTypes(templateLeaf, "^[colorize:#90FF60:28", "leaves3", S("Leaves of a giant tree"), false) + + local whiteblossom1 = generate_leafTypes(templateLeaf, "^[colorize:#fffdfd:alpha", "blossom_white1", S("Blossom"), false) + local whiteblossom2 = generate_leafTypes(templateLeaf, "^[colorize:#fff0f0:alpha", "blossom_white2", S("Blossom"), false) + local pinkblossom = generate_leafTypes(templateLeaf, "^[colorize:#FFE3E8:alpha", "blossom_whitepink", S("Blossom"), false, 5) + + local sakurablossom1 = generate_leafTypes(templateLeaf, "^[colorize:#ea327c:alpha", "blossom_red", S("Sakura blossom"), false, 5) + local sakurablossom2 = generate_leafTypes(templateLeaf, "^[colorize:#ffc3dd:alpha", "blossom_pink", S("Sakura blossom"), false) + + local wisteriaBlossom1 = generate_leafTypes(templateLeaf, "^[colorize:#8087ec:alpha", "blossom_wisteria1", S("Wisteria blossom"), false) + local wisteriaBlossom2 = generate_leafTypes(templateLeaf, "^[colorize:#ccc9ff:alpha", "blossom_wisteria2", S("Wisteria blossom"), false, 7) + + + local tree = SkyTrees.schematicInfo[TREE1_FILE] + if tree ~= nil then + + tree.defaultThemeName = "Green foliage" + tree.theme[tree.defaultThemeName] = { + relativeProbability = 5, + trunk = normalwood, + leaves1 = greenleaf1, + leaves2 = greenleaf2, + leaves_special = greenleaf3, + vineflags = { leaves = true, hanging_leaves = true }, + + init = function(self, position) + -- if it's hot and humid then add vines + local viney = get_heat(position) >= VINES_REQUIRED_TEMPERATURE and get_humidity(position) >= VINES_REQUIRED_HUMIDITY + + if viney then + local flagSeed = position.x * 3 + position.z + ISLANDS_SEED + self.vineflags.hanging_leaves = (flagSeed % 10) <= 3 or (flagSeed % 10) >= 8 + self.vineflags.leaves = (flagSeed % 10) <= 5 + self.vineflags.bark = (flagSeed % 10) <= 2 + self.vineflags.hanging_bark = (flagSeed % 10) <= 1 + end + end + } + + tree.theme["Haunted"] = { + relativeProbability = 2, + trunk = darkwood, + vineflags = { hanging_roots = true }, + hasHeart = false, + hasSoil = false, + + init = function(self, position) + -- 60% of these trees are a hanging roots variant + self.vineflags.hanging_roots = (position.x * 3 + position.y + position.z + ISLANDS_SEED) % 10 < 60 + end + } + + tree.theme["Dead"] = { + relativeProbability = 0, -- 0 because this theme will be chosen based on location, rather than chance. + trunk = deadwood, + hasHeart = false + } + + tree.theme["Sakura"] = { + relativeProbability = 2, + trunk = darkwood, + leaves1 = sakurablossom2, + leaves2 = whiteblossom2, + leaves_special = sakurablossom1, + + init = function(self, position) + -- 40% of these trees are a glowing variant + self.glowing = (position.x * 3 + position.z + ISLANDS_SEED) % 10 <= 3 and BIOLUMINESCENCE + self.leaves_special = sakurablossom1 + if self.glowing then self.leaves_special = sakurablossom1 .. GLOW_SUFFIX end + end + } + + end + + tree = SkyTrees.schematicInfo[TREE2_FILE] + if tree ~= nil then + + -- copy the green leaves theme from tree1 + tree.defaultThemeName = "Green foliage" + tree.theme[tree.defaultThemeName] = SkyTrees.schematicInfo[TREE1_FILE].theme["Green foliage"] + + tree.theme["Wisteria"] = { + relativeProbability = 2.5, + trunk = normalwood, + leaves1 = greenleaf1, + leaves2 = wisteriaBlossom1, + leaves_special = wisteriaBlossom2, + vineflags = { leaves = true, hanging_leaves = true, hanging_bark = true }, + + init = function(self, position) + -- 40% of these trees are a glowing variant + self.glowing = (position.x * 3 + position.z + ISLANDS_SEED) % 10 <= 3 and BIOLUMINESCENCE + self.leaves_special = wisteriaBlossom2 + if self.glowing then self.leaves_special = wisteriaBlossom2 .. GLOW_SUFFIX end + + -- if it's hot and humid then allow vines on the trunk as well + self.vineflags.bark = get_heat(position) >= VINES_REQUIRED_TEMPERATURE and get_humidity(position) >= VINES_REQUIRED_HUMIDITY + end + } + + tree.theme["Blossom"] = { + relativeProbability = 1.5, + trunk = normalwood, + leaves1 = whiteblossom1, + leaves2 = whiteblossom2, + leaves_special = normalwood..BARK_SUFFIX, + + init = function(self, position) + -- 30% of these trees are a glowing variant + self.glowing = (position.x * 3 + position.z + ISLANDS_SEED) % 10 <= 2 and BIOLUMINESCENCE + self.leaves_special = normalwood..BARK_SUFFIX + if self.glowing then self.leaves_special = pinkblossom .. GLOW_SUFFIX end + end + } + + end + + -- fill in any omitted fields in the themes with default values + for _,treeInfo in pairs(SkyTrees.schematicInfo) do + for _,theme in pairs(treeInfo.theme) do + if theme.bark == nil then theme.bark = theme.trunk .. BARK_SUFFIX end + if theme.leaves1 == nil then theme.leaves1 = 'ignore' end + if theme.leaves2 == nil then theme.leaves2 = 'ignore' end + if theme.leaves_special == nil then theme.leaves_special = theme.leaves1 end + + if theme.vineflags == nil then theme.vineflags = {} end + if theme.relativeProbability == nil then theme.relativeProbability = 1.0 end + if theme.glowing == nil then theme.glowing = false end + if theme.hasSoil == nil then theme.hasSoil = true end + if theme.hasHeart == nil then theme.hasHeart = true end + end + end + + -- The heart of the Tree + -- The difference between a living tree and and a haunted/darkened husk + -- + -- Ideally trees would slowly fizzlefade to/from the Haunted theme depending on + -- whether a player steals or restores the heart, meaning a house hollowed out inside + -- a living tree would need the heart to still be kept inside it, perhaps on its + -- own pedestal (unless wanting an Addam's Family treehouse). + local heartwoodTexture = minetest.registered_nodes[templateWood].tiles + if type(heartwoodTexture) == "table" then heartwoodTexture = heartwoodTexture[1] end + local heartwoodGlow = minetest.LIGHT_MAX -- plants can grow under the heart of the Tree + if not BIOLUMINESCENCE then heartwoodGlow = 0 end -- :( + minetest.register_node( + SkyTrees.MODNAME .. ":HeartWood", + { + tiles = { heartwoodTexture }, + description = S("Heart of the Tree"), + groups = {oddly_breakable_by_hand = 3}, + drawtype = "nodebox", + paramtype = "light", + light_source = heartwoodGlow, -- plants can grow under the heart of the Tree + node_box = { + type = "fixed", + fixed = { + --[[ Original heart + {-0.38, -0.38, -0.38, 0.38, 0.38, 0.38}, + {0.15, 0.15, 0.15, 0.5, 0.5, 0.5}, + {-0.5, 0.15, 0.15, -0.15, 0.5, 0.5}, + {-0.5, 0.15, -0.5, -0.15, 0.5, -0.15}, + {0.15, 0.15, -0.5, 0.5, 0.5, -0.15}, + {0.15, -0.5, -0.5, 0.5, -0.15, -0.15}, + {-0.5, -0.5, -0.5, -0.15, -0.15, -0.15}, + {-0.5, -0.5, 0.15, -0.15, -0.15, 0.5}, + {0.15, -0.5, 0.15, 0.5, -0.15, 0.5} + ]] + + {-0.38, -0.38, -0.38, 0.38, 0.38, 0.38}, + {-0.5, -0.2, -0.2, 0.5, 0.2, 0.2}, + {-0.2, -0.5, -0.2, 0.2, 0.5, 0.2}, + {-0.2, -0.2, -0.5, 0.2, 0.2, 0.5} + } + } + } + ) + end + + -- this is hack to work around how place_schematic() never invalidates its cache + -- a unique schematic filename is generated for each unique theme + SkyTrees.getMalleatedFilename = function(schematicInfo, themeName) + + -- create a unique id for the theme + local theme = schematicInfo.theme[themeName] + local flags = 0 + if theme.glowing then flags = flags + 1 end + if theme.vineflags.leaves then flags = flags + 2 end + if theme.vineflags.hanging_leaves then flags = flags + 4 end + if theme.vineflags.bark then flags = flags + 8 end + if theme.vineflags.hanging_bark then flags = flags + 16 end + if theme.vineflags.hanging_roots then flags = flags + 32 end + if theme.hasSoil then flags = flags + 64 end + if theme.hasHeart then flags = flags + 128 end + + local uniqueId = themeName .. flags + + if schematicInfo.malleatedFilenames == nil then schematicInfo.malleatedFilenames = {} end + + if schematicInfo.malleatedFilenames[uniqueId] == nil then + + local malleationCount = 0 + for _ in pairs(schematicInfo.malleatedFilenames) do malleationCount = malleationCount + 1 end + + local malleatedFilename = minetest.get_modpath(SkyTrees.MODNAME) .. DIR_DELIM + for i = 1, malleationCount do + malleatedFilename = malleatedFilename .. '.' .. DIR_DELIM -- should work on both Linux and Windows + end + malleatedFilename = malleatedFilename .. schematicInfo.filename + schematicInfo.malleatedFilenames[uniqueId] = malleatedFilename + end + + --minetest.log("info", "Malleated file name for " .. uniqueId .. " is " .. schematicInfo.malleatedFilenames[uniqueId]) + return schematicInfo.malleatedFilenames[uniqueId] + end + + + -- Returns true if a tree in this location would be dead + -- (checks for desert) + SkyTrees.isDead = function(position) + local heat = get_heat(position) + local humidity = get_humidity(position) + + if humidity <= 10 or (humidity <= 20 and heat >= 80) then + return true + end + + local biomeId = interop.get_biome_key(position) + local biome = biomes[biomeId] + if biome ~= nil and biome.node_top ~= nil then + local modname, nodename = interop.split_nodename(biome.node_top) + if string.find(nodename, "sand") or string.find(nodename, "desert") then + return true + end + end + end + + + -- Returns the name of a suitable theme + -- Picks a theme from the schematicInfo automatically, based on the themes' relativeProbability, and location. + SkyTrees.selectTheme = function(position, schematicInfo, choiceSeed) + + local deadThemeName = "Dead" + + if schematicInfo.theme[deadThemeName] ~= nil then + -- Tree is dead and bleached in desert biomes + if SkyTrees.isDead(position) then + return deadThemeName + end + end + + if choiceSeed == nil then choiceSeed = 0 end + -- Use a known PRNG implementation + local prng = PcgRandom( + position.x * 65732 + + position.z * 729 + + schematicInfo.size.x * 3 + + choiceSeed + ) + + local sumProbabilities = 0 + for _,theme in pairs(schematicInfo.theme) do + sumProbabilities = sumProbabilities + theme.relativeProbability + end + + local selection = prng:next(0, sumProbabilities * 1000) / 1000 + if DEBUG_SKYTREES then minetest.log("info", "Skytrees x: "..position.x.." y: ".. position.y .. " sumProbabilities: " .. sumProbabilities .. ", selection: " .. selection) end + + sumProbabilities = 0 + for themeName,theme in pairs(schematicInfo.theme) do + if selection <= sumProbabilities + theme.relativeProbability then + return themeName + else + sumProbabilities = sumProbabilities + theme.relativeProbability + end + end + + error(SkyTrees.MODNAME .. " - SkyTrees.selectTheme failed to find a theme", 0) + return schematicInfo.defaultThemeName + end + + + -- position is a vector {x, y, z} + -- rotation must be either 0, 90, 180, or 270 + -- schematicInfo must be one of the items in SkyTrees.schematicInfo[] + -- topsoil [optional] is the biome's "node_top" - the ground node of the region. + SkyTrees.placeTree = function(position, rotation, schematicInfo, themeName, topsoil) + + if SkyTrees.disabled ~= nil then + error(SkyTrees.MODNAME .. " - SkyTrees are disabled: " .. SkyTrees.disabled, 0) + return + end + + -- returns a new position vector, rotated around (0, 0) to match the schematic rotation (provided the schematic_size is correct!) + local function rotatePositon(position, schematic_size, rotation) + local result = vector.new(position); + if rotation == 90 then + result.x = position.z + result.z = schematic_size.x - position.x - 1 + elseif rotation == 180 then + result.x = schematic_size.x - position.x - 1 + result.z = schematic_size.z - position.z - 1 + elseif rotation == 270 then + result.x = schematic_size.z - position.z - 1 + result.z = position.x + end + return result + end + + local rotatedCenter = rotatePositon(schematicInfo.center, schematicInfo.size, rotation); + local treePos = vector.subtract(position, rotatedCenter) + + if themeName == nil then themeName = SkyTrees.selectTheme(position, schematicInfo) end + local theme = schematicInfo.theme[themeName] + if theme == nil then error(MODNAME .. ' called SkyTrees.placeTree("' .. schematicInfo.filename .. '") with invalid theme: ' .. themeName, 0) end + if theme.init ~= nil then theme.init(theme, position) end + + if theme.hasSoil then + if topsoil == nil then + topsoil = 'ignore' + if minetest.get_biome_data == nil then error(SkyTrees.MODNAME .. " requires Minetest v5.0 or greater, or to have minor modifications to support v0.4.x", 0) end + local treeBiome = biomes[interop.get_biome_key(position)] + if treeBiome ~= nil and treeBiome.node_top ~= nil then topsoil = treeBiome.node_top end + end + else + topsoil = 'ignore' + end + + local nodeName_heart = SkyTrees.MODNAME .. ":HeartWood" + if not theme.hasHeart then nodeName_heart = 'ignore' end + + -- theme.init() may have changed the vineflags, so update the replacement node names + if theme.vineflags.hanging_leaves == true and SkyTrees.nodeName_hangingVine == 'ignore' then theme.vineflags.leaves = true end -- if there are no hanging vines then substitute side_vines + if theme.vineflags.leaves == true then theme.leaf_vines = SkyTrees.nodeName_sideVines else theme.leaf_vines = 'ignore' end + if theme.vineflags.bark == true then theme.bark_vines = SkyTrees.nodeName_sideVines else theme.bark_vines = 'ignore' end + if theme.vineflags.hanging_leaves == true then theme.hanging_leaf_vines = SkyTrees.nodeName_hangingVine else theme.hanging_leaf_vines = 'ignore' end + if theme.vineflags.hanging_bark == true then theme.hanging_bark_vines = SkyTrees.nodeName_hangingVine else theme.hanging_bark_vines = 'ignore' end + if theme.vineflags.hanging_roots == true and SkyTrees.nodeName_hangingRoot ~= 'ignore' then theme.hanging_bark_vines = SkyTrees.nodeName_hangingRoot end + + local replacements = { + ['treebark\r\n\r\n~~~ Cloudlands_tree mts by Dr.Frankenstone: Amateur Arborist ~~~\r\n\r\n'] = theme.bark, -- because this node name is always replaced, it can double as space for a text header in the file. + ['default:tree'] = theme.trunk, + ['default:leaves'] = theme.leaves1, + ['leaves_alt'] = theme.leaves2, + ['leaves_special'] = theme.leaves_special, + ['leaf_vines'] = theme.leaf_vines, + ['bark_vines'] = theme.bark_vines, + ['hanging_leaf_vines'] = theme.hanging_leaf_vines, + ['hanging_bark_vines'] = theme.hanging_bark_vines, + ['default:dirt'] = topsoil, + ['heart'] = nodeName_heart + } + + if minetest.global_exists("schemlib") then + -- Use schemlib instead minetest.place_schematic(), to avoid bugs in place_schematic() + + local filename = minetest.get_modpath(SkyTrees.MODNAME) .. DIR_DELIM .. schematicInfo.filename + local plan_obj = schemlib.plan.new() + plan_obj:read_from_schem_file(filename, replacements) + plan_obj.data.ground_y = -1 -- prevent read_from_schem_file() from automatically adjusting the height when it encounters dirt in the schematic (SkyTrees sometimes have dirt up in their nooks) + plan_obj.data.facedir = round(rotation / 90) + rotatedCenter = plan_obj:get_world_pos(vector.add(vector.multiply(schematicInfo.center, -1), -1), position); -- this function performs the rotation I require, even if it's named/intended for something else. + plan_obj.data.anchor_pos = rotatedCenter + + if DEBUG_SKYTREES then minetest.log("info", "building tree at " .. dump(position) .. "rotated to " .. dump(treePos) .. "rotatedCenter " .. dump(rotatedCenter) .. ", " .. schematicInfo.filename) end + plan_obj:set_status("build") + + else -- fall back on minetest.place_schematic() + + local malleatedFilename = SkyTrees.getMalleatedFilename(schematicInfo, themeName) + + if DEBUG_SKYTREES then minetest.log("info", "placing tree at " .. dump(position) .. "rotated to " .. dump(treePos) .. "rotatedCenter " .. dump(rotatedCenter) .. ", " .. schematicInfo.filename) end + + -- Defering minetest.place_schematic() until after the lua emerge seems to reduce the likelyhood of + -- having it draw the tree with pieces missing. + minetest.after( + 0.1, + function(treePos, malleatedFilename, rotation, replacements, schematicInfo) + + minetest.place_schematic(treePos, malleatedFilename, rotation, replacements, true) + + -- minetest.place_schematic() doesn't invoke node constructors, so use set_node() for any nodes requiring construction + for i, schematicCoords in pairs(schematicInfo.nodesWithConstructor) do + if rotation ~= 0 then schematicCoords = rotatePositon(schematicCoords, schematicInfo.size, rotation) end + local nodePos = vector.add(treePos, schematicCoords) + local nodeToConstruct = minetest.get_node(nodePos) + if nodeToConstruct.name == "air" or nodeToConstruct.name == "ignore" then + --this is now normal - e.g. if vines are set to 'ignore' then the nodeToConstruct won't be there. + --minetest.log("error", "nodesWithConstructor["..i.."] does not match schematic " .. schematicInfo.filename .. " at " .. nodePos.x..","..nodePos.y..","..nodePos.z.." rotation "..rotation) + else + minetest.set_node(nodePos, nodeToConstruct) + end + end + + end, + treePos, malleatedFilename, rotation, replacements, schematicInfo + ) + + end + end + +end + +SkyTrees.init(); + + +--[[============================== + Initialization and Mapgen + ==============================]]-- + +local function init_mapgen() + -- invoke get_perlin() here, since it can't be invoked before the environment + -- is created because it uses the world's seed value. + noise_eddyField = minetest.get_perlin(noiseparams_eddyField) + noise_heightMap = minetest.get_perlin(noiseparams_heightMap) + noise_density = minetest.get_perlin(noiseparams_density) + noise_surfaceMap = minetest.get_perlin(noiseparams_surfaceMap) + noise_skyReef = minetest.get_perlin(noiseparams_skyReef) + + local prng = PcgRandom(122456 + ISLANDS_SEED) + for i = 0,255 do randomNumbers[i] = prng:next(0, 0x10000) / 0x10000 end + + if isMapgenV6 then + biomes["Normal"] = {node_top="mapgen_dirt_with_grass", node_filler="mapgen_dirt", node_stone="mapgen_stone"} + biomes["Desert"] = {node_top="mapgen_desert_sand", node_filler="mapgen_desert_sand", node_stone="mapgen_desert_stone"} + biomes["Jungle"] = {node_top="mapgen_dirt_with_grass", node_filler="mapgen_dirt", node_stone="mapgen_stone"} + biomes["Tundra"] = {node_top="mapgen_dirt_with_snow", node_filler="mapgen_dirt", node_stone="mapgen_stone"} + biomes["Taiga"] = {node_top="mapgen_dirt_with_snow", node_filler="mapgen_dirt", node_stone="mapgen_stone"} + else + for k,v in pairs(minetest.registered_biomes) do + biomes[minetest.get_biome_id(k)] = v; + end + end + if DEBUG then minetest.log("info", "registered biomes: " .. dump(biomes)) end + + nodeId_air = minetest.get_content_id("air") + + nodeId_stone = interop.find_node_id(NODENAMES_STONE) + nodeId_grass = interop.find_node_id(NODENAMES_GRASS) + nodeId_dirt = interop.find_node_id(NODENAMES_DIRT) + nodeId_water = interop.find_node_id(NODENAMES_WATER) + nodeId_ice = interop.find_node_id(NODENAMES_ICE) + nodeId_silt = interop.find_node_id(NODENAMES_SILT) + nodeId_gravel = interop.find_node_id(NODENAMES_GRAVEL) + nodeId_vine = interop.find_node_id(NODENAMES_VINES) + nodeName_vine = minetest.get_name_from_content_id(nodeId_vine) + + local regionRectStr = minetest.settings:get(MODNAME .. "_limit_rect") + if type(regionRectStr) == "string" then + local minXStr, minZStr, maxXStr, maxZStr = string.match(regionRectStr, '(-?[%d%.]+)[,%s]+(-?[%d%.]+)[,%s]+(-?[%d%.]+)[,%s]+(-?[%d%.]+)') + if minXStr ~= nil then + local minX, minZ, maxX, maxZ = tonumber(minXStr), tonumber(minZStr), tonumber(maxXStr), tonumber(maxZStr) + if minX ~= nil and maxX ~= nil and minX < maxX then + region_min_x, region_max_x = minX, maxX + end + if minZ ~= nil and maxZ ~= nil and minZ < maxZ then + region_min_z, region_max_z = minZ, maxZ + end + end + end + + local limitToBiomesStr = minetest.settings:get(MODNAME .. "_limit_biome") + if type(limitToBiomesStr) == "string" and string.len(limitToBiomesStr) > 0 then + limit_to_biomes = limitToBiomesStr:lower() + end + limit_to_biomes_altitude = tonumber(minetest.settings:get(MODNAME .. "_limit_biome_altitude")) + + region_restrictions = + region_min_x > -32000 or region_min_z > -32000 + or region_max_x < 32000 or region_max_z < 32000 + or limit_to_biomes ~= nil +end + +-- Updates coreList to include all cores of type coreType within the given bounds +local function addCores(coreList, coreType, x1, z1, x2, z2) + + -- this function is used by the API functions, so may be invoked without our on_generated + -- being called + cloudlands.init(); + + for z = math_floor(z1 / coreType.territorySize), math_floor(z2 / coreType.territorySize) do + for x = math_floor(x1 / coreType.territorySize), math_floor(x2 / coreType.territorySize) do + + -- Use a known PRNG implementation, to make life easier for Amidstest + local prng = PcgRandom( + x * 8973896 + + z * 7467838 + + worldSeed + 8438 + ISLANDS_SEED + ) + + local coresInTerritory = {} + + for i = 1, coreType.coresPerTerritory do + local coreX = x * coreType.territorySize + prng:next(0, coreType.territorySize - 1) + local coreZ = z * coreType.territorySize + prng:next(0, coreType.territorySize - 1) + + -- there's strong vertical and horizontal tendency in 2-octave noise, + -- so rotate it a little to avoid it lining up with the world axis. + local noiseX = ROTATE_COS * coreX - ROTATE_SIN * coreZ + local noiseZ = ROTATE_SIN * coreX + ROTATE_COS * coreZ + local eddyField = noise_eddyField:get2d({x = noiseX, y = noiseZ}) + + if (math_abs(eddyField) < coreType.frequency) then + + local nexusConditionMet = not coreType.requiresNexus + if not nexusConditionMet then + -- A 'nexus' is a made up name for a place where the eddyField is flat. + -- There are often many 'field lines' leading out from a nexus. + -- Like a saddle in the perlin noise the height "coreType.frequency" + local eddyField_orthA = noise_eddyField:get2d({x = noiseX + 2, y = noiseZ}) + local eddyField_orthB = noise_eddyField:get2d({x = noiseX, y = noiseZ + 2}) + if math_abs(eddyField - eddyField_orthA) + math_abs(eddyField - eddyField_orthB) < 0.02 then + nexusConditionMet = true + end + end + + if nexusConditionMet then + local radius = (coreType.radiusMax + prng:next(0, coreType.radiusMax) * 2) / 3 -- give a 33%/66% weighting split between max-radius and random + local depth = (coreType.depthMax + prng:next(0, coreType.depthMax) * 2) / 2 -- ERROR!! fix this bug! should be dividing by 3. But should not change worldgen now, so adjust depthMax of islands so nothing changes when bug is fixed? + local thickness = prng:next(0, coreType.thicknessMax) + + + if coreX >= x1 and coreX < x2 and coreZ >= z1 and coreZ < z2 then + + local spaceConditionMet = not coreType.exclusive + if not spaceConditionMet then + -- see if any other cores occupy this space, and if so then + -- either deny the core, or raise it + spaceConditionMet = true + local minDistSquared = radius * radius * .7 + + for _,core in ipairs(coreList) do + if core.type.radiusMax == coreType.radiusMax then + -- We've reached the cores of the current type. We can't exclude based on all + -- cores of the same type as we can't be sure neighboring territories will have been generated. + break + end + if (core.x - coreX)*(core.x - coreX) + (core.z - coreZ)*(core.z - coreZ) <= minDistSquared + core.radius * core.radius then + spaceConditionMet = false + break + end + end + if spaceConditionMet then + for _,core in ipairs(coresInTerritory) do + -- We can assume all cores of the current type are being generated in this territory, + -- so we can exclude the core if it overlaps one already in this territory. + if (core.x - coreX)*(core.x - coreX) + (core.z - coreZ)*(core.z - coreZ) <= minDistSquared + core.radius * core.radius then + spaceConditionMet = false + break + end + end + end; + end + + if spaceConditionMet then + -- all conditions met, we've located a new island core + --minetest.log("Adding core "..x..","..y..","..z..","..radius); + local y = round(noise_heightMap:get2d({x = coreX, y = coreZ})) + local newCore = { + x = coreX, + y = y, + z = coreZ, + radius = radius, + thickness = thickness, + depth = depth, + type = coreType, + } + coreList[#coreList + 1] = newCore + coresInTerritory[#coreList + 1] = newCore + end + + else + -- We didn't test coreX,coreZ against x1,z1,x2,z2 immediately and save all + -- that extra work, as that would break the determinism of the prng calls. + -- i.e. if the area was approached from a different direction then a + -- territory might end up with a different list of cores. + -- TODO: filter earlier but advance prng? + end + end + end + end + end + end +end + + +-- removes any islands that fall outside region restrictions specified in the options +local function removeUnwantedIslands(coreList) + + local testBiome = limit_to_biomes ~= nil + local get_biome_name = nil + if testBiome then + -- minetest.get_biome_name() was added in March 2018, we'll ignore the + -- limit_to_biomes option on versions of Minetest that predate this + get_biome_name = minetest.get_biome_name + testBiome = get_biome_name ~= nil + if get_biome_name == nil then + minetest.log("warning", MODNAME .. " ignoring " .. MODNAME .. "_limit_biome option as Minetest API version too early to support get_biome_name()") + limit_to_biomes = nil + end + end + + for i = #coreList, 1, -1 do + local core = coreList[i] + local coreX = core.x + local coreZ = core.z + + if coreX < region_min_x or coreX > region_max_x or coreZ < region_min_z or coreZ > region_max_z then + table.remove(coreList, i) + + elseif testBiome then + local biomeAltitude + if (limit_to_biomes_altitude == nil) then biomeAltitude = ALTITUDE + core.y else biomeAltitude = limit_to_biomes_altitude end + + local biomeName = get_biome_name(minetest.get_biome_data({x = coreX, y = biomeAltitude, z = coreZ}).biome) + if not string.match(limit_to_biomes, biomeName:lower()) then + table.remove(coreList, i) + end + end + end +end + + +-- gets an array of all cores which may intersect the (minp, maxp) area +-- y is ignored +cloudlands.get_island_details = function(minp, maxp) + local result = {} + + for _,coreType in pairs(cloudlands.coreTypes) do + addCores( + result, + coreType, + minp.x - coreType.radiusMax, + minp.z - coreType.radiusMax, + maxp.x + coreType.radiusMax, + maxp.z + coreType.radiusMax + ) + end + + -- remove islands only after cores have all generated to avoid the restriction + -- settings from rearranging islands. + if region_restrictions then removeUnwantedIslands(result) end + + return result; +end + + +cloudlands.find_nearest_island = function(x, z, search_radius) + + local coreList = {} + for _,coreType in pairs(cloudlands.coreTypes) do + addCores( + coreList, + coreType, + x - (search_radius + coreType.radiusMax), + z - (search_radius + coreType.radiusMax), + x + (search_radius + coreType.radiusMax), + z + (search_radius + coreType.radiusMax) + ) + end + -- remove islands only after cores have all generated to avoid the restriction + -- settings from rearranging islands. + if region_restrictions then removeUnwantedIslands(coreList) end + + local result = nil + for _,core in ipairs(coreList) do + local distance = math.hypot(core.x - x, core.z - z) + if distance >= core.radius then + core.distance = 1 + distance - core.radius + else + -- distance is fractional + core.distance = distance / (core.radius + 1) + end + + if result == nil or core.distance < result.distance then result = core end + end + + return result; +end + + +-- coreList can be left as null, but if you wish to sample many heights in a small area +-- then use cloudlands.get_island_details() to get the coreList for that area and save +-- having to recalculate it during each call to get_height_at(). +cloudlands.get_height_at = function(x, z, coreList) + + local result, isWater = nil, false; + + if coreList == nil then + local pos = {x = x, z = z} + coreList = cloudlands.get_island_details(pos, pos) + end + + for _,core in ipairs(coreList) do + + -- duplicates the code from renderCores() to find surface height + -- See the renderCores() version for explanatory comments + local horz_easing + local distanceSquared = (x - core.x)*(x - core.x) + (z - core.z)*(z - core.z) + local radiusSquared = core.radius * core.radius + + local noise_weighting = 1 + local shapeType = math_floor(core.depth + core.radius + core.x) % 5 + if shapeType < 2 then -- convex, see renderCores() implementatin for comments + horz_easing = 1 - distanceSquared / radiusSquared + elseif shapeType == 2 then -- conical, see renderCores() implementatin for comments + horz_easing = 1 - math_sqrt(distanceSquared) / core.radius + else -- concave, see renderCores() implementatin for comments + local radiusRoot = math_sqrt(core.radius) + local squared = 1 - distanceSquared / radiusSquared + local distance = math_sqrt(distanceSquared) + local distance_normalized = distance / core.radius + local root = 1 - math_sqrt(distance) / radiusRoot + horz_easing = math_min(1, 0.8*distance_normalized*squared + 1.2*(1-distance_normalized)*root) + noise_weighting = 0.63 + end + if core.radius + core.depth > 80 then noise_weighting = 0.6 end + if core.radius + core.depth > 120 then noise_weighting = 0.35 end + + local surfaceNoise = noise_surfaceMap:get2d({x = x, y = z}) + if DEBUG_GEOMETRIC then surfaceNoise = SURFACEMAP_OFFSET end + local coreTop = ALTITUDE + core.y + local surfaceHeight = coreTop + round(surfaceNoise * 3 * (core.thickness + 1) * horz_easing) + + if result == nil or math_max(coreTop, surfaceHeight) > result then + + local coreBottom = math_floor(coreTop - (core.thickness + core.depth)) + local yBottom = coreBottom + if result ~= nil then yBottom = math_max(yBottom, result + 1) end + + for y = math_max(coreTop, surfaceHeight), yBottom, -1 do + local vert_easing = math_min(1, (y - coreBottom) / core.depth) + + local densityNoise = noise_density:get3d({x = x, y = y - coreTop, z = z}) + densityNoise = noise_weighting * densityNoise + (1 - noise_weighting) * DENSITY_OFFSET + if DEBUG_GEOMETRIC then densityNoise = DENSITY_OFFSET end + + if densityNoise * ((horz_easing + vert_easing) / 2) >= REQUIRED_DENSITY then + result = y + isWater = surfaceNoise < 0 + break + + --[[abandoned because do we need to calc the bottom of ponds? It also needs the outer code refactored to work + if not isWater then + -- we've found the land height + break + else + -- find the pond bottom, since the water level is already given by (ALTITUDE + island.y) + local surfaceDensity = densityNoise * ((horz_easing + 1) / 2) + local onTheEdge = math_sqrt(distanceSquared) + 1 >= core.radius + if onTheEdge or surfaceDensity > (REQUIRED_DENSITY + core.type.pondWallBuffer) then + break + end + end]] + end + end + end + end + + return result, isWater +end + + +local function setCoreBiomeData(core) + local pos = {x = core.x, y = ALTITUDE + core.y, z = core.z} + if LOWLAND_BIOMES then pos.y = LOWLAND_BIOME_ALTITUDE end + core.biomeId = interop.get_biome_key(pos) + core.biome = biomes[core.biomeId] + core.temperature = get_heat(pos) + core.humidity = get_humidity(pos) + + if core.temperature == nil then core.temperature = 50 end + if core.humidity == nil then core.humidity = 50 end + + if core.biome == nil then + -- Some games don't use the biome list, so come up with some fallbacks + core.biome = {} + core.biome.node_top = minetest.get_name_from_content_id(nodeId_grass) + core.biome.node_filler = minetest.get_name_from_content_id(nodeId_dirt) + end + +end + +local function addDetail_vines(decoration_list, core, data, area, minp, maxp) + + if VINE_COVERAGE > 0 and nodeId_vine ~= nodeId_ignore then + + local y = ALTITUDE + core.y + if y >= minp.y and y <= maxp.y then + -- if core.biome is nil then renderCores() never rendered it, which means it + -- doesn't instersect this draw region. + if core.biome ~= nil and core.humidity >= VINES_REQUIRED_HUMIDITY and core.temperature >= VINES_REQUIRED_TEMPERATURE then + + local nodeId_top + local nodeId_filler + local nodeId_stoneBase + local nodeId_dust + if core.biome.node_top == nil then nodeId_top = nodeId_stone else nodeId_top = minetest.get_content_id(core.biome.node_top) end + if core.biome.node_filler == nil then nodeId_filler = nodeId_stone else nodeId_filler = minetest.get_content_id(core.biome.node_filler) end + if core.biome.node_stone == nil then nodeId_stoneBase = nodeId_stone else nodeId_stoneBase = minetest.get_content_id(core.biome.node_stone) end + if core.biome.node_dust == nil then nodeId_dust = nodeId_stone else nodeId_dust = minetest.get_content_id(core.biome.node_dust) end + + local function isIsland(nodeId) + return (nodeId == nodeId_filler or nodeId == nodeId_top + or nodeId == nodeId_stoneBase or nodeId == nodeId_dust + or nodeId == nodeId_silt or nodeId == nodeId_water) + end + + local function findHighestNodeFace(y, solidIndex, emptyIndex) + -- return the highest y value (or maxp.y) where solidIndex is part of an island + -- and emptyIndex is not + local yOffset = 1 + while y + yOffset <= maxp.y and isIsland(data[solidIndex + yOffset * area.ystride]) and not isIsland(data[emptyIndex + yOffset * area.ystride]) do + yOffset = yOffset + 1 + end + return y + yOffset - 1 + end + + local radius = round(core.radius) + local xCropped = math_min(maxp.x, math_max(minp.x, core.x)) + local zStart = math_max(minp.z, core.z - radius) + local vi = area:index(xCropped, y, zStart) + + for z = 0, math_min(maxp.z, core.z + radius) - zStart do + local searchIndex = vi + z * area.zstride + if isIsland(data[searchIndex]) then + + -- add vines to east face + if randomNumbers[(zStart + z + y) % 256] <= VINE_COVERAGE then + for x = xCropped + 1, maxp.x do + if not isIsland(data[searchIndex + 1]) then + local yhighest = findHighestNodeFace(y, searchIndex, searchIndex + 1) + decoration_list[#decoration_list + 1] = {pos={x=x, y=yhighest, z= zStart + z}, node={name = nodeName_vine, param2 = 3}} + break + end + searchIndex = searchIndex + 1 + end + end + -- add vines to west face + if randomNumbers[(zStart + z + y + 128) % 256] <= VINE_COVERAGE then + searchIndex = vi + z * area.zstride + for x = xCropped - 1, minp.x, -1 do + if not isIsland(data[searchIndex - 1]) then + local yhighest = findHighestNodeFace(y, searchIndex, searchIndex - 1) + decoration_list[#decoration_list + 1] = {pos={x=x, y=yhighest, z= zStart + z}, node={name = nodeName_vine, param2 = 2}} + break + end + searchIndex = searchIndex - 1 + end + end + end + end + + local zCropped = math_min(maxp.z, math_max(minp.z, core.z)) + local xStart = math_max(minp.x, core.x - radius) + local zstride = area.zstride + vi = area:index(xStart, y, zCropped) + + for x = 0, math_min(maxp.x, core.x + radius) - xStart do + local searchIndex = vi + x + if isIsland(data[searchIndex]) then + + -- add vines to north face (make it like moss - grows better on the north side) + if randomNumbers[(xStart + x + y) % 256] <= (VINE_COVERAGE * 1.2) then + for z = zCropped + 1, maxp.z do + if not isIsland(data[searchIndex + zstride]) then + local yhighest = findHighestNodeFace(y, searchIndex, searchIndex + zstride) + decoration_list[#decoration_list + 1] = {pos={x=xStart + x, y=yhighest, z=z}, node={name = nodeName_vine, param2 = 5}} + break + end + searchIndex = searchIndex + zstride + end + end + -- add vines to south face (make it like moss - grows better on the north side) + if randomNumbers[(xStart + x + y + 128) % 256] <= (VINE_COVERAGE * 0.8) then + searchIndex = vi + x + for z = zCropped - 1, minp.z, -1 do + if not isIsland(data[searchIndex - zstride]) then + local yhighest = findHighestNodeFace(y, searchIndex, searchIndex - zstride) + decoration_list[#decoration_list + 1] = {pos={x=xStart + x, y=yhighest, z=z}, node={name = nodeName_vine, param2 = 4}} + break + end + searchIndex = searchIndex - zstride + end + end + end + end + + end + end + end +end + + +-- A rare formation of rocks circling or crowning an island +-- returns true if voxels were changed +local function addDetail_skyReef(decoration_list, core, data, area, minp, maxp) + + local coreTop = ALTITUDE + core.y + local overdrawTop = maxp.y + OVERDRAW + local reefAltitude = math_floor(coreTop - 1 - core.thickness / 2) + local reefMaxHeight = 12 + local reefMaxUnderhang = 4 + + if (maxp.y < reefAltitude - reefMaxUnderhang) or (minp.y > reefAltitude + reefMaxHeight) then + --no reef here + return false + end + + local isReef = core.radius < core.type.radiusMax * 0.4 -- a reef can't extend beyond radiusMax, so needs a small island + local isAtoll = core.radius > core.type.radiusMax * 0.8 + if not (isReef or isAtoll) then return false end + + local fastHash = 3 + fastHash = (37 * fastHash) + core.x + fastHash = (37 * fastHash) + core.z + fastHash = (37 * fastHash) + math_floor(core.radius) + fastHash = (37 * fastHash) + math_floor(core.depth) + if ISLANDS_SEED ~= 1000 then fastHash = (37 * fastHash) + ISLANDS_SEED end + local rarityAdj = 1 + if core.type.requiresNexus and isAtoll then rarityAdj = 4 end -- humongous islands are very rare, and look good as a atoll + if (REEF_RARITY * rarityAdj * 1000) < math_floor((math_abs(fastHash)) % 1000) then return false end + + local coreX = core.x --save doing a table lookup in the loop + local coreZ = core.z --save doing a table lookup in the loop + + -- Use a known PRNG implementation + local prng = PcgRandom( + coreX * 8973896 + + coreZ * 7467838 + + worldSeed + 32564 + ) + + local reefUnderhang + local reefOuterRadius = math_floor(core.type.radiusMax) + local reefInnerRadius = prng:next(core.type.radiusMax * 0.5, core.type.radiusMax * 0.7) + local reefWidth = reefOuterRadius - reefInnerRadius + local noiseOffset = 0 + + if isReef then + reefMaxHeight = round((core.thickness + 4) / 2) + reefUnderhang = round(reefMaxHeight / 2) + noiseOffset = -0.1 + end + if isAtoll then + -- a crown attached to the island + reefOuterRadius = math_floor(core.radius * 0.8) + reefWidth = math_max(4, math_floor(core.radius * 0.15)) + reefInnerRadius = reefOuterRadius - reefWidth + reefUnderhang = 0 + if maxp.y < reefAltitude - reefUnderhang then return end -- no atoll here + end + + local reefHalfWidth = reefWidth / 2 + local reefMiddleRadius = (reefInnerRadius + reefOuterRadius) / 2 + local reefOuterRadiusSquared = reefOuterRadius * reefOuterRadius + local reefInnerRadiusSquared = reefInnerRadius * reefInnerRadius + local reefMiddleRadiusSquared = reefMiddleRadius * reefMiddleRadius + local reefHalfWidthSquared = reefHalfWidth * reefHalfWidth + + -- get the biome details for this core + local nodeId_first + local nodeId_second + local nodeId_top + local nodeId_filler + if core.biome == nil then setCoreBiomeData(core) end -- We can't assume the core biome has already been resolved, core might not have been big enough to enter the draw region + if core.biome.node_top == nil then nodeId_top = nodeId_stone else nodeId_top = minetest.get_content_id(core.biome.node_top) end + if core.biome.node_filler == nil then nodeId_filler = nodeId_stone else nodeId_filler = minetest.get_content_id(core.biome.node_filler) end + if core.biome.node_dust ~= nil then + nodeId_first = minetest.get_content_id(core.biome.node_dust) + nodeId_second = nodeId_top + else + nodeId_first = nodeId_top + nodeId_second = nodeId_filler + end + + local zStart = round(math_max(core.z - reefOuterRadius, minp.z)) + local zStop = round(math_min(core.z + reefOuterRadius, maxp.z)) + local xStart = round(math_max(core.x - reefOuterRadius, minp.x)) + local xStop = round(math_min(core.x + reefOuterRadius, maxp.x)) + local yCenter = math_min(math_max(reefAltitude, minp.y), maxp.y) + local pos = {} + + local dataBufferIndex = area:index(xStart, yCenter, zStart) + local vi = -1 + for z = zStart, zStop do + local zDistSquared = (z - coreZ) * (z - coreZ) + pos.y = z + for x = xStart, xStop do + local distanceSquared = (x - coreX) * (x - coreX) + zDistSquared + if distanceSquared < reefOuterRadiusSquared and distanceSquared > reefInnerRadiusSquared then + pos.x = x + local offsetEase = math_abs(distanceSquared - reefMiddleRadiusSquared) / reefHalfWidthSquared + local fineNoise = noise_skyReef:get2d(pos) + local reefNoise = (noiseOffset* offsetEase) + fineNoise + 0.2 * noise_surfaceMap:get2d(pos) + + if (reefNoise > 0) then + local distance = math_sqrt(distanceSquared) + local ease = 1 - math_abs(distance - reefMiddleRadius) / reefHalfWidth + local yStart = math_max(math_floor(reefAltitude - ease * fineNoise * reefUnderhang), minp.y) + local yStop = math_min(math_floor(reefAltitude + ease * reefNoise * reefMaxHeight), overdrawTop) + + for y = yStart, yStop do + vi = dataBufferIndex + (y - yCenter) * area.ystride + if data[vi] == nodeId_air then + if y == yStop then + data[vi] = nodeId_first + elseif y == yStop - 1 then + data[vi] = nodeId_second + else + data[vi] = nodeId_filler + end + end + end + end + end + dataBufferIndex = dataBufferIndex + 1 + end + dataBufferIndex = dataBufferIndex + area.zstride - (xStop - xStart + 1) + end + + return vi >= 0 +end + +-- A rarely occuring giant tree growing from the center of the island +-- returns true if tree was added +local function addDetail_skyTree(decoration_list, core, minp, maxp) + + if (core.radius < SkyTrees.minimumIslandRadius) or (core.depth < SkyTrees.minimumIslandDepth) then + --no tree here + return false + end + + local coreTop = ALTITUDE + core.y + local treeAltitude = math_floor(coreTop + core.thickness) + + if (maxp.y < treeAltitude - SkyTrees.maximumYOffset) or (minp.y > treeAltitude + SkyTrees.maximumHeight) then + --no tree here + return false + elseif SkyTrees.disabled ~= nil then + -- can't find nodes/textures in this game that are needed to build trees + return false + end + + local coreX = core.x --save doing a table lookups + local coreZ = core.z --save doing a table lookups + + local fastHash = 3 + fastHash = (37 * fastHash) + coreX + fastHash = (37 * fastHash) + coreZ + fastHash = (37 * fastHash) + math_floor(core.radius) + fastHash = (37 * fastHash) + math_floor(core.depth) + fastHash = (37 * fastHash) + ISLANDS_SEED + fastHash = (37 * fastHash) + 76276 -- to keep this probability distinct from reefs and atols + if (TREE_RARITY * 1000) < math_floor((math_abs(fastHash)) % 1000) then return false end + + -- choose a tree that will fit on the island + local tree + + local skipLargeTree = (fastHash % 10) < 3 -- to allow small trees a chance to spawn on large islands + if skipLargeTree then + if SkyTrees.isDead({x = coreX, y = treeAltitude, z = coreZ}) then + -- small tree currently doesn't have a dead theme, so don't skip the large tree + skipLargeTree = false + end + end + + + for i, treeType in pairs(SkyTrees.schematicInfo) do + if i == 1 and skipLargeTree then + -- 'continue', to allow small trees a chance to spawn on large islands + elseif (core.radius >= treeType.requiredIslandRadius) and (core.depth >= treeType.requiredIslandDepth) then + tree = treeType + break + end + end + + local maxOffsetFromCenter = core.radius - (tree.requiredIslandRadius - 4); -- 4 is an arbitrary number, to allow trees to get closer to the edge + + -- Use a known PRNG implementation + local prng = PcgRandom( + coreX * 8973896 + + coreZ * 7467838 + + worldSeed + 43786 + ) + + local treeAngle = 90 * prng:next(0, 3) + local treePos = { + x = coreX + math_floor((prng:next(-maxOffsetFromCenter, maxOffsetFromCenter) + prng:next(-maxOffsetFromCenter, maxOffsetFromCenter)) / 2), + y = treeAltitude, + z = coreZ + math_floor((prng:next(-maxOffsetFromCenter, maxOffsetFromCenter) + prng:next(-maxOffsetFromCenter, maxOffsetFromCenter)) / 2) + } + + if minetest.global_exists("schemlib") then + -- This check is skipped when not using schemlib, because while redrawing the tree multiple times - every time a chunk it + -- touches gets emitted - might be slower, it helps work around the bugs in minetest.place_schematic() where large schematics + -- are spawned incompletely. + -- The bug in question: https://forum.minetest.net/viewtopic.php?f=6&t=22136 + -- (it isn't an issue if schemlib is used) + if (maxp.y < treePos.y) or (minp.y > treePos.y) or (maxp.x < treePos.x) or (minp.x > treePos.x) or (maxp.z < treePos.z) or (minp.z > treePos.z) then + -- Now that we know the exact position of the tree, we know it's spawn point is not in this chunk. + -- In the interests of only drawing trees once, we only invoke placeTree when the chunk containing treePos is emitted. + return false + end + end + + if tree.theme["Dead"] == nil then + if SkyTrees.isDead(treePos) then + -- Trees in this location should be dead, but this tree doesn't have a dead theme, so don't put a tree here + return false + end + end + + if core.biome == nil then setCoreBiomeData(core) end -- We shouldn't assume the core biome has already been resolved, it might be below the emerged chunk and unrendered + + if core.biome.node_top == nil then + -- solid stone isn't fertile enough for giant trees, and there's a solid stone biome in MT-Game: tundra_highland + return false + end + + if DEBUG_SKYTREES then minetest.log("info", "core x: "..coreX.." y: ".. coreZ .. " treePos: " .. treePos.x .. ", y: " .. treePos.y) end + + SkyTrees.placeTree(treePos, treeAngle, tree, nil, core.biome.node_top) + return true; +end + + +------------------------------------------------------------------------------ +-- Secrets section +------------------------------------------------------------------------------ + +-- We might not need this stand-in cobweb, but unless we go overboard on listing many +-- optional dependencies we won't know whether there's a proper cobweb available to +-- use until after it's too late to register this one. +if minetest.get_modpath("default") then + -- the crack texture is probably available + local nodeName_standinCobweb = MODNAME .. ":cobweb" + minetest.register_node( + nodeName_standinCobweb, + { + tiles = { + -- [Ab]Use the crack texture to avoid needing to include a cobweb texture + "crack_anylength.png^[verticalframe:5:4^[brighten" + }, + description = S("Cobweb"), + groups = {snappy = 3, liquid = 3, flammable = 3, not_in_creative_inventory = 1}, + drawtype = "plantlike", + walkable = false, + liquid_viscosity = 8, + liquidtype = "source", + liquid_alternative_flowing = nodeName_standinCobweb, + liquid_alternative_source = nodeName_standinCobweb, + liquid_renewable = false, + liquid_range = 0, + sunlight_propagates = true, + paramtype = "light" + } + ) +end + + +local nodeName_egg = "secret:fossilized_egg" +local eggTextureName = "default_jungleleaves.png" -- called this in default/Voxelgarden/MineClone2 +if minetest.get_modpath("ethereal") ~= nil then eggTextureName = "ethereal_frost_leaves.png" end -- called "ethereal_frost_leaves.png" in ethereal +-- Since "secret:fossilized_egg" doesn't use this mod's name for the prefix, we can't assume +-- another mod isn't also using/providing it +if minetest.registered_nodes[nodeName_egg] == nil then + minetest.register_node( + ":"..nodeName_egg, + { + tiles = { + -- [Ab]Use a leaf texture to avoid needing to include an egg texture and exposing that the mod contains secrets + eggTextureName.."^[colorize:#280040E0^[noalpha" + }, + description = S("Fossilized Egg"), + groups = {oddly_breakable_by_hand = 3, not_in_creative_inventory = 1}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.066666, -0.5, -0.066666, 0.066666, 0.5, 0.066666}, -- column1 + {-0.133333, -0.476667, -0.133333, 0.133333, 0.42, 0.133333}, -- column2 + {-0.2, -0.435, -0.2, 0.2, 0.31, 0.2 }, -- column3 + {-0.2, -0.36, -0.28, 0.2, 0.16667, 0.28 }, -- side1 + {-0.28, -0.36, -0.2, 0.28, 0.16667, 0.2 } -- side2 + } + } + } + ) +end +local nodeId_egg = minetest.get_content_id(nodeName_egg) +local nodeId_airStandIn = minetest.get_content_id(interop.register_clone("air")) + +-- defer assigning the following until all mods are loaded +local nodeId_bed_top +local nodeId_bed_bottom +local nodeId_torch +local nodeId_chest +local nodeId_bookshelf +local nodeId_junk +local nodeId_anvil +local nodeId_workbench +local nodeId_cobweb +local nodeName_bookshelf +local isMineCloneBookshelf + +local function addDetail_secrets(decoration_list, core, data, area, minp, maxp) + + -- if core.biome is nil then renderCores() never rendered it, which means it + -- doesn't instersect this draw region. + if core.biome ~= nil and core.radius > 18 and core.depth > 20 and core.radius + core.depth > 60 then + + local territoryX = math_floor(core.x / core.type.territorySize) + local territoryZ = math_floor(core.z / core.type.territorySize) + local isPolarOutpost = (core.temperature <= 5) and (core.x % 3 == 0) and noise_surfaceMap:get2d({x = core.x, y = core.z - 8}) >= 0 --make sure steps aren't under a pond + local isAncientBurrow = core.humidity >= 60 and core.temperature >= 50 + + -- only allow a checkerboard pattern of territories to help keep the secrets + -- spread out, rather than bunching up too much with climate + if ((territoryX + territoryZ) % 2 == 0) and (isPolarOutpost or isAncientBurrow) then + + local burrowRadius = 7 + local burrowHeight = 5 + local burrowDepth = 12 + local burrowFloor = ALTITUDE + core.y - burrowDepth + local radiusSquared = burrowRadius * burrowRadius + + local function carve(originp, destp, pattern, height, floorId, floorDistance) + + local direction = vector.direction(originp, destp) + local vineSearchDirection = {} + if direction.x > 0 then vineSearchDirection.x = -1 else vineSearchDirection.x = 1 end + if direction.z > 0 then vineSearchDirection.z = -1 else vineSearchDirection.z = 1 end + + local vinePlacements = {} + local function placeVine(vi, pos, only_place_on_nodeId) + if data[vi] == nodeId_air then + local faces = {} + local facing + + local function vineCanGrowOnIt(node_id) + return node_id ~= nodeId_air and node_id ~= nodeId_airStandIn and (node_id == only_place_on_nodeId or only_place_on_nodeId == nil) + end + if vineCanGrowOnIt(data[vi + vineSearchDirection.x]) and pos.x + vineSearchDirection.x >= minp.x and pos.x + vineSearchDirection.x <= maxp.x then + if vineSearchDirection.x > 0 then facing = 2 else facing = 3 end + faces[#faces + 1] = {solid_vi = vi + vineSearchDirection.x, facing = facing} + end + if vineCanGrowOnIt(data[vi + vineSearchDirection.z * area.zstride]) and pos.z + vineSearchDirection.z >= minp.z and pos.z + vineSearchDirection.z <= maxp.z then + if vineSearchDirection.z > 0 then facing = 4 else facing = 5 end + faces[#faces + 1] = {solid_vi = vi + vineSearchDirection.z * area.zstride, facing = facing} + end + + local faceInfo = nil + if #faces == 1 then + faceInfo = faces[1] + elseif #faces == 2 then + local ratio = math.abs(direction.x) / (math.abs(direction.x) + math.abs(direction.z)) + if randomNumbers[(pos.x + pos.y + pos.z) % 256] <= ratio then faceInfo = faces[1] else faceInfo = faces[2] end + end + if faceInfo ~= nil + and (only_place_on_nodeId == nil or only_place_on_nodeId == data[faceInfo.solid_vi]) + and (data[faceInfo.solid_vi] ~= nodeId_airStandIn) then + -- find the highest y value (or maxp.y) where solid_vi is solid + -- and vi is not + local solid_vi = faceInfo.solid_vi + local yOffset = 1 + while (pos.y + yOffset <= maxp.y + 1) + and (data[solid_vi + yOffset * area.ystride] ~= nodeId_air) + and (data[vi + yOffset * area.ystride] == nodeId_air) + and (only_place_on_nodeId == nil or only_place_on_nodeId == data[solid_vi + yOffset * area.ystride]) do + yOffset = yOffset + 1 + end + + -- defer final vine placement until all nodes have been carved + vinePlacements[#vinePlacements + 1] = function(decoration_list) + -- retest that the vine is still going in air and still attached to a solid node + local solidNode = data[solid_vi + (yOffset - 1) * area.ystride] + if solidNode ~= nodeId_airStandIn and solidNode ~= nodeId_air and data[vi] == nodeId_air then + decoration_list[#decoration_list + 1] = {pos={x=pos.x, y=pos.y + yOffset - 1, z=pos.z}, node={name = nodeName_vine, param2 = faceInfo.facing}} + end + end + end + end + end + + local stampedIndexes = {} + local function stamp(pos, pattern, height, node_id, isAir_callback) + local callbackClosures = {} + local index = -1 + for y = pos.y, pos.y + height - 1 do + if y >= minp.y and y <= maxp.y then + if index == -1 then index = area:index(pos.x, y, pos.z) else index = index + area.ystride end + for _,voxel in ipairs(pattern) do + local x = pos.x + voxel.x + local z = pos.z + voxel.z + if x >= minp.x and x <= maxp.x and z >= minp.z and z <= maxp.z then + local vi = index + voxel.x + voxel.z * area.zstride + if data[vi] == nodeId_air then + if isAir_callback ~= nil then + callbackClosures[#callbackClosures + 1] = function() isAir_callback(pos, vi, x, y, z) end + end + else + data[vi] = node_id + stampedIndexes[#stampedIndexes + 1] = vi + end + end + end + end + end + for _,callback in ipairs(callbackClosures) do callback() end + end + + local function excavate(pos, add_floor, add_vines, add_cobwebs) + + local function onAirNode(stampPos, node_vi, node_x, node_y, node_z) + if node_y > stampPos.y and node_y + 1 <= maxp.y then + -- place vines above the entrance, for concealment + placeVine(node_vi + area.ystride, {x=node_x, y=node_y + 1, z=node_z}) + else + -- place vines on the floor - perhaps explorers can climb to the burrow + placeVine(node_vi, {x=node_x, y=node_y, z=node_z}, floorId) + end + end + + local onAirNodeCallback = onAirNode + local fill = nodeId_airStandIn + if not add_vines or nodeId_vine == nodeId_ignore then onAirNodeCallback = nil end + if add_cobwebs and nodeId_cobweb ~= nodeId_ignore then fill = nodeId_cobweb end + + stamp(pos, pattern, height, fill, onAirNodeCallback) + if add_floor and floorId ~= nil then + stamp({x=pos.x, y=pos.y - 1, z=pos.z}, pattern, 1, floorId, onAirNodeCallback) + end + end + + local addVines = core.humidity >= VINES_REQUIRED_HUMIDITY and core.temperature >= VINES_REQUIRED_TEMPERATURE + if floorDistance == nil then floorDistance = 0 end + local distance = round(vector.distance(originp, destp)) + local step = vector.divide(vector.subtract(destp, originp), distance) + + local pos = vector.new(originp) + local newPos = vector.new(originp) + + excavate(originp, 0 >= floorDistance, false) + for i = 1, distance do + newPos.x = newPos.x + step.x + if round(newPos.x) ~= pos.x then + pos.x = round(newPos.x) + excavate(pos, i >= floorDistance, addVines, i <= floorDistance - 1 and i >= floorDistance - 2) + end + newPos.y = newPos.y + step.y + if round(newPos.y) ~= pos.y then + pos.y = round(newPos.y) + excavate(pos, i >= floorDistance, addVines, i <= floorDistance - 1 and i >= floorDistance - 2) + end + newPos.z = newPos.z + step.z + if round(newPos.z) ~= pos.z then + pos.z = round(newPos.z) + excavate(pos, i >= floorDistance, addVines, i <= floorDistance - 1 and i >= floorDistance - 2) + end + end + + -- We only place vines after entire burrow entrance has been carved, to avoid placing + -- vines on blocks which will later be removed. + for _,vineFunction in ipairs(vinePlacements) do vineFunction(decoration_list) end + + -- Replace airStandIn with real air. + -- This two-pass process was neccessary because the vine placing algorithm used + -- the presense of air to determine if a rock was facing outside and should have a vine. + -- Single-pass solutions result in vines inside the tunnel (where I'd rather overgrowth spawned) + for _,stampedIndex in ipairs(stampedIndexes) do + if data[stampedIndex] == nodeId_airStandIn then + data[stampedIndex] = nodeId_air + end + end + + end + + local function placeNode(x, y, z, node_id) + if (x >= minp.x and x <= maxp.x and z >= minp.z and z <= maxp.z and y >= minp.y and y <= maxp.y) then + data[area:index(x, y, z)] = node_id + end + end + + local function posInBounds(pos) + return pos.x >= minp.x and pos.x <= maxp.x and pos.z >= minp.z and pos.z <= maxp.z and pos.y >= minp.y and pos.y <= maxp.y + end + + local zStart = math_max(core.z - burrowRadius, minp.z) + local xStart = math_max(core.x - burrowRadius, minp.x) + local xStop = math_min(core.x + burrowRadius, maxp.x) + local yStart = math_max(burrowFloor, minp.y) + + -- dig burrow + local dataBufferIndex = area:index(xStart, yStart, zStart) + for z = zStart, math_min(core.z + burrowRadius, maxp.z) do + for x = xStart, xStop do + local distanceSquared = (x - core.x)*(x - core.x) + (z - core.z)*(z - core.z) + if distanceSquared < radiusSquared then + local horz_easing = 1 - distanceSquared / radiusSquared + for y = math_max(minp.y, burrowFloor + math_floor(1.4 - horz_easing)), math_min(maxp.y, burrowFloor + 1 + math_min(burrowHeight - 1, math_floor(0.8 + burrowHeight * horz_easing))) do + data[dataBufferIndex + (y - yStart) * area.ystride] = nodeId_air + end + end + dataBufferIndex = dataBufferIndex + 1 + end + dataBufferIndex = dataBufferIndex + area.zstride - (xStop - xStart + 1) + end + + local floorId + if core.biome.node_top == nil then floorId = nil else floorId = minetest.get_content_id(core.biome.node_top) end + + if isAncientBurrow then + -- island overlaps can only happen at territory edges when a coreType has exclusive=true, so + -- angle the burrow entrance toward the center of the terrority to avoid any overlapping islands. + local territoryCenter = vector.new( + core.type.territorySize * math.floor(core.x / core.type.territorySize) + math.floor(0.5 + core.type.territorySize / 2), + burrowFloor, + core.type.territorySize * math.floor(core.z / core.type.territorySize) + math.floor(0.5 + core.type.territorySize / 2) + ) + local burrowStart = vector.new(core.x, burrowFloor, core.z) + local direction = vector.direction(burrowStart, territoryCenter) + local directionOffsetZ = 4 + if direction.z < 0 then directionOffsetZ = -directionOffsetZ end + burrowStart.z = burrowStart.z + directionOffsetZ -- start the burrow enterance off-center + burrowStart.x = burrowStart.x + 2 -- start the burrow enterance off-center + direction = vector.direction(burrowStart, territoryCenter) + if vector.length(direction) == 0 then direction = vector.direction({x=0, y=0, z=0}, {x=2, y=0, z=1}) end + + local path = vector.add(vector.multiply(direction, core.radius), {x=0, y=-4,z=0}) + local floorStartingFrom = 4 + math.floor(0.5 + core.radius * 0.3) + + -- carve burrow entrance + local pattern = {{x=0,z=0}, {x=-1,z=0}, {x=1,z=0}, {x=0,z=-1}, {x=0,z=1}} + carve(burrowStart, vector.add(burrowStart, path), pattern, 2, floorId, floorStartingFrom) + + -- place egg in burrow + local eggX = core.x + local eggZ = core.z - directionOffsetZ * 0.75 -- move the egg away from where the burrow entrance is carved + placeNode(eggX, burrowFloor, eggZ, nodeId_egg) + if nodeId_gravel ~= nodeId_ignore then placeNode(eggX, burrowFloor - 1, eggZ, nodeId_gravel) end + if nodeId_cobweb ~= nodeId_ignore then + placeNode(core.x - 6, burrowFloor + 3, core.z - 1, nodeId_cobweb) + placeNode(core.x + 4, burrowFloor + 4, core.z + 3, nodeId_cobweb) + placeNode(core.x + 6, burrowFloor + 1, core.z - 3, nodeId_cobweb) + end + + else + -- Only attempt this if it can contain beds and a place to store the diary. + if (nodeId_bookshelf ~= nodeId_ignore or nodeId_chest ~= nodeId_ignore) and nodeId_bed_top ~= nodeId_ignore and nodeId_bed_bottom ~= nodeId_ignore then + + -- carve stairs to the surface + local stairsStart = vector.new(core.x - 3, burrowFloor, core.z - 7) + local stairsbottom = vector.add(stairsStart, {x=0,y=0,z=1}) + local stairsMiddle1 = vector.add(stairsStart, {x=8,y=8,z=0}) + local stairsMiddle2 = vector.add(stairsMiddle1, {x=0,y=0,z=-1}) + local stairsEnd = vector.add(stairsMiddle2, {x=-20,y=20,z=0}) + + carve(stairsEnd, stairsMiddle2, {{x=0,z=0}}, 3, floorId, 0) + carve(stairsMiddle1, stairsStart, {{x=0,z=0}}, 2, floorId, 0) + local pattern = {{x=0,z=0}, {x=1,z=0}, {x=0,z=2}, {x=0,z=1}, {x=1,z=1}} + carve(stairsbottom, stairsbottom, pattern, 2, floorId, 0) + + -- fill the outpost + placeNode(core.x + 2, burrowFloor, core.z + 5, nodeId_bed_top) + placeNode(core.x + 2, burrowFloor, core.z + 4, nodeId_bed_bottom) + + placeNode(core.x + 2, burrowFloor, core.z + 2, nodeId_bed_top) + placeNode(core.x + 2, burrowFloor, core.z + 1, nodeId_bed_bottom) + + placeNode(core.x + 4, burrowFloor, core.z + 2, nodeId_bed_top) + placeNode(core.x + 4, burrowFloor, core.z + 1, nodeId_bed_bottom) + + if (nodeId_torch ~= nodeId_ignore) then + decoration_list[#decoration_list + 1] = { + pos={x=core.x, y=burrowFloor + 2, z=core.z + 6}, + node={name = minetest.get_name_from_content_id(nodeId_torch), param2 = 4} + } + end + if nodeId_junk ~= nodeId_ignore then placeNode(core.x - 4, burrowFloor + 1, core.z + 5, nodeId_junk) end + if nodeId_anvil ~= nodeId_ignore then placeNode(core.x - 6, burrowFloor + 1, core.z, nodeId_anvil) end + if nodeId_workbench ~= nodeId_ignore then placeNode(core.x - 5, burrowFloor, core.z + 2, nodeId_workbench) end + if nodeId_cobweb ~= nodeId_ignore then placeNode(core.x + 4, burrowFloor + 4, core.z - 3, nodeId_cobweb) end + + local bookshelf_pos + local invBookshelf = nil + local invChest = nil + if nodeId_chest ~= nodeId_ignore then + local pos = {x = core.x - 3, y = burrowFloor + 1, z = core.z + 6} + + local nodeName_chest = minetest.get_name_from_content_id(nodeId_chest) + local nodeNameAtPos = minetest.get_node(pos).name + -- falls back on the nodeNameAtPos:find("chest") check to avoid a race-condition where if the + -- chest is opened while nearby areas are being generated, the opened chest may be replaced with + -- a new empty closed one. + if nodeNameAtPos ~= nodeName_chest and not nodeNameAtPos:find("chest") then minetest.set_node(pos, {name = nodeName_chest}) end + + if posInBounds(pos) then + data[area:index(pos.x, pos.y, pos.z)] = nodeId_chest + invChest = minetest.get_inventory({type = "node", pos = pos}) + end + end + if nodeId_bookshelf ~= nodeId_ignore then + local pos = {x = core.x - 2, y = burrowFloor + 1, z = core.z + 6} + bookshelf_pos = pos + + if minetest.get_node(pos).name ~= nodeName_bookshelf then minetest.set_node(pos, {name = nodeName_bookshelf}) end + + if posInBounds(pos) then + data[area:index(pos.x, pos.y, pos.z)] = nodeId_bookshelf + if not isMineCloneBookshelf then -- mineclone bookshelves are decorational (like Minecraft) and don't contain anything + invBookshelf = minetest.get_inventory({type = "node", pos = pos}) + end + end + end + + if invBookshelf ~= nil or invChest ~= nil then + -- create diary + local groundDesc = S("rock") + if core.biome.node_filler ~= nil then + local earthNames = string.lower(core.biome.node_filler) .. string.lower(core.biome.node_top) + if string.match(earthNames, "ice") or string.match(earthNames, "snow") or string.match(earthNames, "frozen") then + groundDesc = S("ice") + end + end + + local stackName_writtenBook = "default:book_written" + if isMineCloneBookshelf then stackName_writtenBook = "mcl_books:written_book" end + + local book_itemstack = ItemStack(stackName_writtenBook) + local book_data = {} + book_data.title = S("Weddell Outpost") + -- Instead of being a stand-alone line, the McNish line is tacked on the end of the + -- journey sentence because otherwise it gets truncated off by default:book_written + book_data.text = S([[The aerostat is lost. + +However, salvage attempts throughout the night managed to +save most provisions before it finally broke apart and fell. + + ---====--- + +This island is highly exposed and the weather did not treat +the tents well. We have enlarged a sheltered crag in the @1, +but it is laborous work and the condition of some of the party +is becoming cause for concern. + +Quite a journey is now required, we cannot stay - nobody will +look for us here. McNish is attempting to strengthen the gliders. + + ---====--- +]], groundDesc) + + if isMineCloneBookshelf then book_data.text = book_data.title .. "\n\n" .. book_data.text end -- MineClone2 doesn't show the title + book_data.owner = S("Bert Shackleton") + book_data.author = book_data.owner + book_data.description = S("Diary of Bert Shackleton") + book_data.page = 1 + book_data.page_max = 1 + book_data.generation = 0 + book_itemstack:get_meta():from_table({fields = book_data}) + + if invBookshelf == nil then + -- mineclone bookshelves are decorational like Minecraft, put the book in the chest instead + -- (also testing for nil invBookshelf because it can happen. Weird race condition??) + if invChest ~= nil then invChest:add_item("main", book_itemstack) end + else + -- add the book to the bookshelf and manually trigger update_bookshelf() so its + -- name will reflect the new contents. + invBookshelf:add_item("books", book_itemstack) + local dummyPlayer = {} + dummyPlayer.get_player_name = function() return "server" end + minetest.registered_nodes[nodeName_bookshelf].on_metadata_inventory_put(bookshelf_pos, "books", 1, book_itemstack, dummyPlayer) + end + end + + if invChest ~= nil then + -- leave some junk from the expedition in the chest + local stack + local function addIfFound(item_aliases, amount) + for _,name in ipairs(item_aliases) do + if minetest.registered_items[name] ~= nil then + stack = ItemStack(name .. " " .. amount) + invChest:add_item("main", stack) + break + end + end + end + addIfFound({"mcl_tools:pick_iron", "default:pick_steel"}, 1) + addIfFound({"binoculars:binoculars"}, 1) + addIfFound({"mcl_core:wood", "default:wood"}, 10) + addIfFound({"mcl_torches:torch", "default:torch"}, 3) + end + + end + end + end + end +end + +local function init_secrets() + nodeId_bed_top = interop.find_node_id({"beds:bed_top"}) + nodeId_bed_bottom = interop.find_node_id({"beds:bed_bottom"}) + nodeId_torch = interop.find_node_id({"mcl_torches:torch_wall", "default:torch_wall"}) + nodeId_chest = interop.find_node_id({"chest", "mcl_chests:chest", "default:chest"}) + nodeId_junk = interop.find_node_id({"xdecor:barrel", "cottages:barrel", "homedecor:copper_pans", "vessels:steel_bottle", "mcl_flowerpots:flower_pot"}) + nodeId_anvil = interop.find_node_id({"castle:anvil", "cottages:anvil", "mcl_anvils:anvil", "default:anvil" }) -- "default:anvil" isn't a thing, but perhaps one day. + nodeId_workbench = interop.find_node_id({"homedecor:table", "xdecor:workbench", "mcl_crafting_table:crafting_table", "default:table", "random_buildings:bench"}) -- "default:table" isn't a thing, but perhaps one day. + nodeId_cobweb = interop.find_node_id({"mcl_core:cobweb", "xdecor:cobweb", "homedecor:cobweb_plantlike", "default:cobweb"}) + + local mineCloneBookshelfName = "mcl_books:bookshelf" + nodeId_bookshelf = interop.find_node_id({mineCloneBookshelfName, "default:bookshelf"}) + nodeName_bookshelf = minetest.get_name_from_content_id(nodeId_bookshelf) + isMineCloneBookshelf = nodeName_bookshelf == mineCloneBookshelfName + + local nodeName_standinCobweb = MODNAME .. ":cobweb" + if nodeId_cobweb ~= nodeId_ignore then + -- This game has proper cobwebs, replace any cobwebs this mod may have generated + -- previously (when a cobweb mod wasn't included) with the proper cobwebs. + minetest.register_alias(nodeName_standinCobweb, minetest.get_name_from_content_id(nodeId_cobweb)) + else + -- use a stand-in cobweb created by this mod + nodeId_cobweb = minetest.get_content_id(nodeName_standinCobweb) + end +end +------------------------------------------------------------------------------ +-- End of secrets section +------------------------------------------------------------------------------ + + +local function renderCores(cores, minp, maxp, blockseed) + + local voxelsWereManipulated = false + + local vm, emerge_min, emerge_max = minetest.get_mapgen_object("voxelmanip") + vm:get_data(data) -- put all nodes except the ground surface in this array + local area = VoxelArea:new{MinEdge=emerge_min, MaxEdge=emerge_max} + local overdrawTop = maxp.y + OVERDRAW + + local currentBiomeId = -1 + local nodeId_dust + local nodeId_top + local nodeId_filler + local nodeId_stoneBase + local nodeId_pondBottom + local depth_top + local depth_filler + local fillerFallsWithGravity + local floodableDepth + + for z = minp.z, maxp.z do + + local dataBufferIndex = area:index(minp.x, minp.y, z) + for x = minp.x, maxp.x do + for _,core in pairs(cores) do + local coreTop = ALTITUDE + core.y + + local distanceSquared = (x - core.x)*(x - core.x) + (z - core.z)*(z - core.z) + local radius = core.radius + local radiusSquared = radius * radius + + if distanceSquared <= radiusSquared then + + -- get the biome details for this core + if core.biome == nil then setCoreBiomeData(core) end + if currentBiomeId ~= core.biomeId then + if core.biome.node_top == nil then nodeId_top = nodeId_stone else nodeId_top = minetest.get_content_id(core.biome.node_top) end + if core.biome.node_filler == nil then nodeId_filler = nodeId_stone else nodeId_filler = minetest.get_content_id(core.biome.node_filler) end + if core.biome.node_stone == nil then nodeId_stoneBase = nodeId_stone else nodeId_stoneBase = minetest.get_content_id(core.biome.node_stone) end + if core.biome.node_dust == nil then nodeId_dust = nodeId_ignore else nodeId_dust = minetest.get_content_id(core.biome.node_dust) end + if core.biome.node_riverbed == nil then nodeId_pondBottom = nodeId_silt else nodeId_pondBottom = minetest.get_content_id(core.biome.node_riverbed) end + + if core.biome.depth_top == nil then depth_top = 1 else depth_top = core.biome.depth_top end + if core.biome.depth_filler == nil then depth_filler = 3 else depth_filler = core.biome.depth_filler end + fillerFallsWithGravity = core.biome.node_filler ~= nil and minetest.registered_items[core.biome.node_filler].groups.falling_node == 1 + + --[[Commented out as unnecessary, as a supporting node will be added, but uncommenting + this will make the strata transition less noisey. + if fillerFallsWithGravity then + -- the filler node is affected by gravity and can fall if unsupported, so keep that layer thinner than + -- core.thickness when possible. + --depth_filler = math_min(depth_filler, math_max(1, core.thickness - 1)) + end--]] + + floodableDepth = 0 + if nodeId_top ~= nodeId_stone and minetest.registered_items[core.biome.node_top].floodable then + -- nodeId_top is a node that water floods through, so we can't have ponds appearing at this depth + floodableDepth = depth_top + end + + currentBiomeId = core.biomeId + end + + -- decide on a shape + local horz_easing + local noise_weighting = 1 + local shapeType = math_floor(core.depth + radius + core.x) % 5 + if shapeType < 2 then + -- convex + -- squared easing function, e = 1 - x² + horz_easing = 1 - distanceSquared / radiusSquared + elseif shapeType == 2 then + -- conical + -- linear easing function, e = 1 - x + horz_easing = 1 - math_sqrt(distanceSquared) / radius + else + -- concave + -- root easing function blended/scaled with square easing function, + -- x = normalised distance from center of core + -- a = 1 - x² + -- b = 1 - √x + -- e = 0.8*a*x + 1.2*b*(1 - x) + + local radiusRoot = core.radiusRoot + if radiusRoot == nil then + radiusRoot = math_sqrt(radius) + core.radiusRoot = radiusRoot + end + + local squared = 1 - distanceSquared / radiusSquared + local distance = math_sqrt(distanceSquared) + local distance_normalized = distance / radius + local root = 1 - math_sqrt(distance) / radiusRoot + horz_easing = math_min(1, 0.8*distance_normalized*squared + 1.2*(1-distance_normalized)*root) + + -- this seems to be a more delicate shape that gets wiped out by the + -- density noise, so lower that + noise_weighting = 0.63 + end + if radius + core.depth > 80 then + -- larger islands shapes have a slower easing transition, which leaves large areas + -- dominated by the density noise, so reduce the density noise when the island is large. + -- (the numbers here are arbitrary) + if radius + core.depth > 120 then + noise_weighting = 0.35 + else + noise_weighting = math_min(0.6, noise_weighting) + end + end + + local surfaceNoise = noise_surfaceMap:get2d({x = x, y = z}) + if DEBUG_GEOMETRIC then surfaceNoise = SURFACEMAP_OFFSET end + local surface = round(surfaceNoise * 3 * (core.thickness + 1) * horz_easing) -- if you change this formular then update maxSufaceRise in on_generated() + local coreBottom = math_floor(coreTop - (core.thickness + core.depth)) + local noisyDepthOfFiller = depth_filler; + if noisyDepthOfFiller >= 3 then noisyDepthOfFiller = noisyDepthOfFiller + math_floor(randomNumbers[(x + z) % 256] * 3) - 1 end + + local yBottom = math_max(minp.y, coreBottom - 4) -- the -4 is for rare instances when density noise pushes the bottom of the island deeper + local yBottomIndex = dataBufferIndex + area.ystride * (yBottom - minp.y) -- equivalent to yBottomIndex = area:index(x, yBottom, z) + local topBlockIndex = -1 + local bottomBlockIndex = -1 + local vi = yBottomIndex + local densityNoise = nil + + for y = yBottom, math_min(overdrawTop, coreTop + surface) do + local vert_easing = math_min(1, (y - coreBottom) / core.depth) + + -- If you change the densityNoise calculation, remember to similarly update the copy of this calculation in the pond code + densityNoise = noise_density:get3d({x = x, y = y - coreTop, z = z}) -- TODO: Optimize this!! + densityNoise = noise_weighting * densityNoise + (1 - noise_weighting) * DENSITY_OFFSET + + if DEBUG_GEOMETRIC then densityNoise = DENSITY_OFFSET end + + if densityNoise * ((horz_easing + vert_easing) / 2) >= REQUIRED_DENSITY then + if vi > topBlockIndex then topBlockIndex = vi end + if bottomBlockIndex < 0 and y > minp.y then bottomBlockIndex = vi end -- if y==minp.y then we don't know for sure this is the lowest block + + if y > coreTop + surface - depth_top and data[vi] == nodeId_air then + data[vi] = nodeId_top + elseif y >= coreTop + surface - (depth_top + noisyDepthOfFiller) then + data[vi] = nodeId_filler + else + data[vi] = nodeId_stoneBase + end + end + vi = vi + area.ystride + end + + -- ensure nodeId_top blocks also cover the rounded sides of islands (which may be lower + -- than the flat top), then dust the top surface. + if topBlockIndex >= 0 then + voxelsWereManipulated = true; + + -- we either have the highest block, or overdrawTop - but we don't want to set overdrawTop nodes to nodeId_top + -- (we will err on the side of caution when we can't distinguish the top of a island's side from overdrawTop) + if overdrawTop >= coreTop + surface or vi > topBlockIndex + area.ystride then + if topBlockIndex > yBottomIndex and data[topBlockIndex - area.ystride] ~= nodeId_air and data[topBlockIndex + area.ystride] == nodeId_air then + -- We only set a block to nodeId_top if there's a block under it "holding it up" as + -- it's better to leave 1-deep noise as stone/whatever. + data[topBlockIndex] = nodeId_top + end + if nodeId_dust ~= nodeId_ignore and data[topBlockIndex + area.ystride] == nodeId_air then + -- Delay writing dust to the data buffer until after decoration so avoid preventing tree growth etc + if core.dustLocations == nil then core.dustLocations = {} end + core.dustLocations[#core.dustLocations + 1] = topBlockIndex + area.ystride + end + end + + if fillerFallsWithGravity and bottomBlockIndex >= 0 and data[bottomBlockIndex] == nodeId_filler then + -- the bottom node is affected by gravity and can fall if unsupported, put some support in + data[bottomBlockIndex] = nodeId_stoneBase + end + end + + -- add ponds of water, trying to make sure they're not on an edge. + -- (the only time a pond needs to be rendered when densityNoise is nil (i.e. when there was no land at this x, z), + -- is when the pond is at minp.y - i.e. the reason no land was rendered is it was below minp.y) + if surfaceNoise < 0 and (densityNoise ~= nil or (coreTop + surface < minp.y and coreTop >= minp.y)) and nodeId_water ~= nodeId_ignore then + local pondWallBuffer = core.type.pondWallBuffer + local pondBottom = nodeId_filler + local pondWater = nodeId_water + if radius > 18 and core.depth > 15 and nodeId_silt ~= nodeId_ignore then + -- only give ponds a sandbed when islands are large enough for it not to stick out the side or bottom + pondBottom = nodeId_pondBottom + end + if core.temperature <= ICE_REQUIRED_TEMPERATURE and nodeId_ice ~= nodeId_ignore then pondWater = nodeId_ice end + + if densityNoise == nil then + -- Rare edge case. If the pond is at minp.y, then no land has been rendered, so + -- densityNoise hasn't been calculated. Calculate it now. + densityNoise = noise_density:get3d({x = x, y = minp.y, z = z}) + densityNoise = noise_weighting * densityNoise + (1 - noise_weighting) * DENSITY_OFFSET + if DEBUG_GEOMETRIC then densityNoise = DENSITY_OFFSET end + end + + local surfaceDensity = densityNoise * ((horz_easing + 1) / 2) + local onTheEdge = math_sqrt(distanceSquared) + 1 >= radius + for y = math_max(minp.y, coreTop + surface), math_min(overdrawTop, coreTop - floodableDepth) do + if surfaceDensity > REQUIRED_DENSITY then + vi = dataBufferIndex + area.ystride * (y - minp.y) -- this is the same as vi = area:index(x, y, z) + + if surfaceDensity > (REQUIRED_DENSITY + pondWallBuffer) and not onTheEdge then + data[vi] = pondWater + if y > minp.y then data[vi - area.ystride] = pondBottom end + --remove any dust above ponds + if core.dustLocations ~= nil and core.dustLocations[#core.dustLocations] == vi + area.ystride then core.dustLocations[#core.dustLocations] = nil end + else + -- make sure there are some walls to keep the water in + if y == coreTop then + data[vi] = nodeId_top -- to let isIsland() know not to put vines here (only seems to be an issue when pond is 2 deep or more) + else + data[vi] = nodeId_filler + end + end; + end + end + end; + + end + end + dataBufferIndex = dataBufferIndex + 1 + end + end + + local decorations = {} + for _,core in ipairs(cores) do + addDetail_vines(decorations, core, data, area, minp, maxp) + voxelsWereManipulated = addDetail_skyReef(decorations, core, data, area, minp, maxp) or voxelsWereManipulated + addDetail_secrets(decorations, core, data, area, minp, maxp) + end + + if voxelsWereManipulated then + + vm:set_data(data) + if GENERATE_ORES then minetest.generate_ores(vm) end + minetest.generate_decorations(vm) + + for _,core in ipairs(cores) do + addDetail_skyTree(decorations, core, minp, maxp) + if addDetail_ancientPortal ~= nil then addDetail_ancientPortal(core) end + end + for _,decoration in ipairs(decorations) do + local nodeAtPos = minetest.get_node(decoration.pos) + if nodeAtPos.name == "air" or nodeAtPos.name == "ignore" then minetest.set_node(decoration.pos, decoration.node) end + end + + local dustingInProgress = false + for _,core in ipairs(cores) do + if core.dustLocations ~= nil then + if not dustingInProgress then + vm:get_data(data) + dustingInProgress = true + end + + nodeId_dust = minetest.get_content_id(core.biome.node_dust) + for _, location in ipairs(core.dustLocations) do + if data[location] == nodeId_air and data[location - area.ystride] ~= nodeId_air then + data[location] = nodeId_dust + end + end + end + end + if dustingInProgress then vm:set_data(data) end + + + -- Lighting is a problem. Two problems really... + -- + -- Problem 1: + -- We can't use the usual lua mapgen lighting trick of flags="nolight" e.g.: + -- minetest.set_mapgen_params({mgname = "singlenode", flags = "nolight"}) + -- (https://forum.minetest.net/viewtopic.php?t=19836) + -- + -- because the mod is designed to run with other mapgens. So we must set the light + -- values to zero at islands before calling calc_lighting() to propegate lighting + -- down from above. + -- + -- This causes lighting bugs if we zero the whole emerge_min-emerge_max area because + -- it leaves hard black at the edges of the emerged area (calc_lighting must assume + -- a value of zero for light outside the region, and be blending that in) + -- + -- But we can't simply zero only the minp-maxp area instead, because then calc_lighting + -- reads the daylight values out of the overdraw area and blends those in, cutting + -- up shadows with lines of daylight along chunk boundaries. + -- + -- The correct solution is to zero and calculate the whole emerge_min-emerge_max area, + -- but only write the calculated lighting information from minp-maxp back into the map, + -- however the API doesn't appear to provide a fast way to do that. + -- + -- Workaround: zero an area that extends into the overdraw region, but keeps a gap around + -- the edges to preserve and allow the real light values to propegate in. Then when + -- calc_lighting is called it will have daylight (or existing values) at the emerge boundary + -- but not near the chunk boundary. calc_lighting is able to take the edge lighting into + -- account instead of assuming zero. It's not a perfect solution, but allows shading without + -- glaringly obvious lighting artifacts, and the minor ill effects should only affect the + -- islands and be corrected any time lighting is updated. + -- + -- + -- Problem 2: + -- We don't want islands to blacken the landscape below them in shadow. + -- + -- Workaround 1: Instead of zeroing the lighting before propegating from above, set it + -- to 2, so that shadows are never pitch black. Shadows will still go back to pitch black + -- though if lighting gets recalculated, e.g. player places a torch then removes it. + -- + -- Workaround 2: set the bottom of the chunk to full daylight, ensuring that full + -- daylight is what propegates down below islands. This has the problem of causing a + -- bright horizontal band of light where islands approach a chunk floor or ceiling, + -- but Hallelujah Mountains already had that issue due to having propagate_shadow + -- turned off when calling calc_lighting. This workaround has the same drawback, but + -- does a much better job of preventing undesired shadows. + + local shadowGap = 1 + local brightMin = {x = emerge_min.x + shadowGap, y = minp.y , z = emerge_min.z + shadowGap} + local brightMax = {x = emerge_max.x - shadowGap, y = minp.y + 1, z = emerge_max.z - shadowGap} + local darkMin = {x = emerge_min.x + shadowGap, y = minp.y + 1, z = emerge_min.z + shadowGap} + local darkMax = {x = emerge_max.x - shadowGap, y = maxp.y , z = emerge_max.z - shadowGap} + + vm:set_lighting({day=2, night=0}, darkMin, darkMax) + vm:calc_lighting() + vm:set_lighting({day=15, night=0}, brightMin, brightMax) + + vm:write_to_map() -- seems to be unnecessary when other mods that use vm are running + end +end + + +cloudlands.init = function() + if noise_eddyField == nil then + init_mapgen() + init_secrets() + end +end + +local function on_generated(minp, maxp, blockseed) + + local memUsageT0 + local osClockT0 = os.clock() + if DEBUG then memUsageT0 = collectgarbage("count") end + + local largestCoreType = cloudlands.coreTypes[1] -- the first island type is the biggest/thickest + local maxCoreThickness = largestCoreType.thicknessMax + local maxCoreDepth = largestCoreType.radiusMax * 3 / 2 -- todo: not sure why this is radius based and not maxDepth based?? + local maxSufaceRise = 3 * (maxCoreThickness + 1) + + if minp.y > ALTITUDE + (ALTITUDE_AMPLITUDE + maxSufaceRise + 10) or -- the 10 is an arbitrary number because sometimes the noise values exceed their normal range. + maxp.y < ALTITUDE - (ALTITUDE_AMPLITUDE + maxCoreThickness + maxCoreDepth + 10) then + -- Hallelujah Mountains don't generate here + return + end + + cloudlands.init(); + local cores = cloudlands.get_island_details(minp, maxp) + + if DEBUG then + minetest.log("info", "Cores for on_generated(): " .. #cores) + for _,core in pairs(cores) do + minetest.log("core ("..core.x..","..core.y..","..core.z..") r"..core.radius); + end + end + + if #cores > 0 then + -- voxelmanip has mem-leaking issues, avoid creating one if we're not going to need it + renderCores(cores, minp, maxp, blockseed) + + if DEBUG then + minetest.log( + "info", + MODNAME .. " took " + .. round((os.clock() - osClockT0) * 1000) + .. "ms for " .. #cores .. " cores. Uncollected memory delta: " + .. round(collectgarbage("count") - memUsageT0) .. " KB" + ) + end + end +end + + +minetest.register_on_generated(on_generated) + +minetest.register_on_mapgen_init( + -- invoked after mods initially run but before the environment is created, while the mapgen is being initialized + function(mgparams) + worldSeed = mgparams.seed + --if DEBUG then minetest.set_mapgen_params({mgname = "singlenode"--[[, flags = "nolight"]]}) end + end +) diff --git a/mods/cloudlands/cloudlands_tree1.mts b/mods/cloudlands/cloudlands_tree1.mts new file mode 100644 index 0000000..345cd5d Binary files /dev/null and b/mods/cloudlands/cloudlands_tree1.mts differ diff --git a/mods/cloudlands/cloudlands_tree2.mts b/mods/cloudlands/cloudlands_tree2.mts new file mode 100644 index 0000000..6af3b12 Binary files /dev/null and b/mods/cloudlands/cloudlands_tree2.mts differ diff --git a/mods/cloudlands/init.lua b/mods/cloudlands/init.lua new file mode 100644 index 0000000..b7a65b1 --- /dev/null +++ b/mods/cloudlands/init.lua @@ -0,0 +1,3 @@ +local path = minetest.get_modpath(minetest.get_current_modname()) + +dofile(path.."/cloudlands.lua") diff --git a/mods/cloudlands/license.txt b/mods/cloudlands/license.txt new file mode 100644 index 0000000..9928287 --- /dev/null +++ b/mods/cloudlands/license.txt @@ -0,0 +1,26 @@ +Cloudlands mapgen +~~~~~~~~~~~~~~~~~ + + Copyright © 2018 Treer + + A more permissive license may be available by request. + + For simplicity this Minetest mod is licensed with the same + license as Minetest - "GNU LGPL" version 2.1 or later. + + +GNU LGPL information +-------------------- + + 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 can receive a copy of the GNU Lesser General Public License from + http://www.gnu.org/ \ No newline at end of file diff --git a/mods/cloudlands/locale/template.txt b/mods/cloudlands/locale/template.txt new file mode 100644 index 0000000..b9ed2d6 --- /dev/null +++ b/mods/cloudlands/locale/template.txt @@ -0,0 +1,32 @@ +# textdomain: cloudlands + + +### cloudlands.lua ### + +Ancient Portalstone= +Bark of @1= +Bert Shackleton= +Blossom= +Cobweb= + +Construction requires 14 blocks of ancient portalstone. We have no knowledge of how portalstones were created, the means to craft them are likely lost to time, so our only source has been to scavenge the Nether for the remnants of ancient broken portals. A finished frame is four blocks wide, five blocks high, and stands vertically, like a doorway.= + +Dead bleached wood= +Diary of Bert Shackleton= +Fossilized Egg= +Giant Ziricote= +Giant tree= +Glowing @1= +Hallelujah Mountains Portal= +Heart of the Tree= +Leaves of a giant tree= +Sakura blossom= + +The aerostat is lost.@n@nHowever, salvage attempts throughout the night managed to@nsave most provisions before it finally broke apart and fell.@n@n ---@=@=@=@=---@n@nThis island is highly exposed and the weather did not treat@nthe tents well. We have enlarged a sheltered crag in the @1,@nbut it is laborous work and the condition of some of the party@nis becoming cause for concern.@n@nQuite a journey is now required, we cannot stay - nobody will@nlook for us here. McNish is attempting to strengthen the gliders.@n@n ---@=@=@=@=---@n= + +The only portal we managed to scavenge enough portalstone to build took us to a land of floating islands. There were hills and forests and even water up there, but the edges are a perilous drop — a depth of which we cannot even begin to plumb.= + +Weddell Outpost= +Wisteria blossom= +ice= +rock= diff --git a/mods/cloudlands/mod.conf b/mods/cloudlands/mod.conf new file mode 100644 index 0000000..4ea7c81 --- /dev/null +++ b/mods/cloudlands/mod.conf @@ -0,0 +1,12 @@ +name = cloudlands +optional_depends = vines, schemlib, default, mcl_core, ethereal, biomeinfo, nether +description = """ +Hallelujah Mountains for Minetest + +Giant rocks floating suspended in magnetic eddies. + +This can be run with or without a normal terrain mapgen, allowing pure skylands or an exotic addition to the landscape. + +Configurable settings include the altitude islands appear, and the ability to restrict the area they spawn. If you only ever see snow-covered islands then enable the "Use lowland biomes" option. +""" + diff --git a/mods/cloudlands/screenshot.png b/mods/cloudlands/screenshot.png new file mode 100644 index 0000000..8f90ae7 Binary files /dev/null and b/mods/cloudlands/screenshot.png differ diff --git a/mods/cloudlands/settingtypes.txt b/mods/cloudlands/settingtypes.txt new file mode 100644 index 0000000..460f172 --- /dev/null +++ b/mods/cloudlands/settingtypes.txt @@ -0,0 +1,70 @@ +# If true then islands will use biomes from altitude 10 - higher than beaches +# and lower than mountains. This avoids a problem with some mods which have +# alpine biomes, causing all islands to be alpine/snowy due to their altitude, +# however plant-life may still reflect the actual altitude of the islands. +# +# Turn this off to have each island's altitude affect its biome. +cloudlands_use_lowland_biomes (Use lowland biomes) bool false + +# The average altitude islands are found at +# +# In Minetest game, ores like iron and diamond will be generated if the +# altitude of islands is set above 1200 and "Generate ores inside islands" +# is Enabled. +cloudlands_altitude (Altitude of islands) int 200 + +# The rough variance of altitude in islands (plus or minus this value) +cloudlands_altitude_amplitude (Altitude variance) int 40 + +# Generates patches of sand and dirt inside island stone cores. +cloudlands_generate_ores (Generate ores inside islands - patches of dirt, sand etc.) bool false + +# Set this to 0 to disable vines. +# +# A percentage value between 0 and 100 which controls the likelyhood of each +# node on an island edge having a vine growing down it. +# This option is ignored unless played with a game or mod which provides vines, +# such as plantlife_modpack, vines, or MineClone2. +# This setting does not alter the temperature or humidity determining whether +# vines will be present on an island. +cloudlands_vine_coverage (Vine coverage %) int 30 0 100 + +# If you wish to have large areas of the map without islands then specify +# here the area where islands may spawn. +# +# The format is: +#   minimum_x minimum_z maximum_x maximum_z +cloudlands_limit_rect (Limit island locations within rectange) string -32000 -32000 32000 32000 + +# Leave blank to allow islands to appear in any biome +# Otherwise list biomes by name, with a space between each one. +# +# Example: +#   cold_desert sandstone_desert +cloudlands_limit_biome (Limit island locations within listed biomes) string + +# Only used when "Limit island locations within listed biomes" is set. +# This specifies the altitude of biomes which determine whether islands can +# spawn, allowing islands to have their own biome system at island altitude +# while still having locations limited by the biomes at ground level. +# +#   Set to about 10 to use ground level biomes (10 is higher than beaches) +#   Leave blank to use the islands' altitudes. +cloudlands_limit_biome_altitude (Altitude for listed biomes) string + +# Set this to 0 to disable giant trees. +# +# A percentage value between 0 and 100 which controls the spread of the +# rare and gigantic trees which can sometimes be found growing on islands. +cloudlands_giant_tree_rarety (Giant tree rarety %) int 5 0 100 + +# Set true to allow glowing rarer variants of the rare and gigantic trees +# which can sometimes be found growing on islands. +# +# This option is ignored if tree rarety is set to 0 +cloudlands_bioluminescence (Allow glowing trees) bool false + +# Set true to allow players to build portals to islands. +# +# Portals require the Nether mod. +cloudlands_enable_portals (Enable portals to the islands) bool true diff --git a/mods/commoditymarket/default_markets.lua b/mods/commoditymarket/default_markets.lua new file mode 100644 index 0000000..16d2316 --- /dev/null +++ b/mods/commoditymarket/default_markets.lua @@ -0,0 +1,528 @@ +local default_modpath = minetest.get_modpath("default") +if not default_modpath then return end + +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +-- Only register gold coins once, if required +local gold_coins_registered = false +local register_gold_coins = function() + if not gold_coins_registered then + minetest.register_craftitem("commoditymarket:gold_coins", { + description = S("Gold Coins"), + _doc_items_longdesc = S("A gold ingot is far too valuable to use as a basic unit of value, so it has become common practice to divide the standard gold bar into one thousand small disks to make trade easier."), + _doc_items_usagehelp = S("Gold coins can be deposited and withdrawn from markets that accept them as currency. These markets can make change if you have a thousand coins and would like them back in ingot form again."), + inventory_image = "commoditymarket_gold_coins.png", + stack_max = 1000, + }) + gold_coins_registered = true + end +end + +local default_items = {"default:axe_bronze","default:axe_diamond","default:axe_mese","default:axe_steel","default:axe_steel","default:axe_stone","default:axe_wood","default:pick_bronze","default:pick_diamond","default:pick_mese","default:pick_steel","default:pick_stone","default:pick_wood","default:shovel_bronze","default:shovel_diamond","default:shovel_mese","default:shovel_steel","default:shovel_stone","default:shovel_wood","default:sword_bronze","default:sword_diamond","default:sword_mese","default:sword_steel","default:sword_stone","default:sword_wood", "default:blueberries", "default:book", "default:bronze_ingot", "default:clay_brick", "default:clay_lump", "default:coal_lump", "default:copper_ingot", "default:copper_lump", "default:diamond", "default:flint", "default:gold_ingot", "default:gold_lump", "default:iron_lump", "default:mese_crystal", "default:mese_crystal_fragment", "default:obsidian_shard", "default:paper", "default:steel_ingot", "default:stick", "default:tin_ingot", "default:tin_lump", "default:acacia_tree", "default:acacia_wood", "default:apple", "default:aspen_tree", "default:aspen_wood", "default:blueberry_bush_sapling", "default:bookshelf", "default:brick", "default:bronzeblock", "default:bush_sapling", "default:cactus", "default:clay", "default:coalblock", "default:cobble", "default:copperblock", "default:desert_cobble", "default:desert_sand", "default:desert_sandstone", "default:desert_sandstone_block", "default:desert_sandstone_brick", "default:desert_stone", "default:desert_stone_block", "default:desert_stonebrick", "default:diamondblock", "default:dirt", "default:glass", "default:goldblock", "default:gravel", "default:ice", "default:junglegrass", "default:junglesapling", "default:jungletree", "default:junglewood", "default:ladder_steel", "default:ladder_wood", "default:large_cactus_seedling", "default:mese", "default:mese_post_light", "default:meselamp", "default:mossycobble", "default:obsidian", "default:obsidian_block", "default:obsidian_glass", "default:obsidianbrick", "default:papyrus", "default:pine_sapling", "default:pine_tree", "default:pine_wood", "default:sand", "default:sandstone", "default:sandstone_block", "default:sandstonebrick", "default:sapling", "default:silver_sand", "default:silver_sandstone", "default:silver_sandstone_block", "default:silver_sandstone_brick", "default:snow", "default:snowblock", "default:steelblock", "default:stone", "default:stone_block", "default:stonebrick", "default:tinblock", "default:tree", "default:wood",} + +local usage_help = S("Right-click on this to open the market interface.") + +------------------------------------------------------------------------------ +-- King's Market + +if minetest.settings:get_bool("commoditymarket_enable_kings_market") then + +local kings_def = { + description = S("King's Market"), + long_description = S("The largest and most accessible market for the common man, the King's Market uses gold coins as its medium of exchange (or the equivalent in gold ingots - 1000 coins to the ingot). However, as a respectable institution of the surface world, the King's Market operates only during the hours of daylight. The purchase and sale of swords and explosives is prohibited in the King's Market. Gold coins are represented by a '☼' symbol."), + currency = { + ["default:gold_ingot"] = 1000, + ["commoditymarket:gold_coins"] = 1 + }, + currency_symbol = "☼", -- "\u{263C}" Alchemical symbol for gold + allow_item = function(item) + if item:sub(1,13) == "default:sword" or item:sub(1,4) == "tnt:" then + return false + end + return true + end, + inventory_limit = 100000, + --sell_limit =, -- no sell limit for the King's Market + initial_items = default_items, +} + +register_gold_coins() + +commoditymarket.register_market("kings", kings_def) + +local kings_protect = minetest.settings:get_bool("commoditymarket_protect_kings_market", true) +local on_blast +if kings_protect then + on_blast = function() end +end + +minetest.register_node("commoditymarket:kings_market", { + description = kings_def.description, + _doc_items_longdesc = kings_def.long_description, + _doc_items_usagehelp = usage_help, + tiles = {"default_chest_top.png","default_chest_top.png", + "default_chest_side.png","default_chest_side.png", + "commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_crown.png",}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local timeofday = minetest.get_timeofday() + if timeofday > 0.2 and timeofday < 0.8 then + commoditymarket.show_market("kings", clicker:get_player_name()) + else + minetest.chat_send_player(clicker:get_player_name(), S("At this time of day the King's Market is closed.")) + minetest.sound_play({name = "commoditymarket_error", gain = 0.1}, {to_player=clicker:get_player_name()}) + end + end, + can_dig = function(pos, player) + return not kings_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) +end +------------------------------------------------------------------------------- +-- Night Market + +if minetest.settings:get_bool("commoditymarket_enable_night_market") then +local night_def = { + description = S("Night Market"), + long_description = "When the sun sets and the stalls of the King's Market close, other vendors are just waking up to share their wares. The Night Market is not as voluminous as the King's Market but accepts a wider range of wares. It accepts the same gold coinage of the realm, one thousand coins to the gold ingot.", + currency = { + ["default:gold_ingot"] = 1000, + ["commoditymarket:gold_coins"] = 1 + }, + currency_symbol = "☼", --"\u{263C}" + inventory_limit = 10000, + --sell_limit =, -- no sell limit for the Night Market + initial_items = default_items, + anonymous = true, +} + +register_gold_coins() + +commoditymarket.register_market("night", night_def) + +local night_protect = minetest.settings:get_bool("commoditymarket_protect_night_market", true) +local on_blast +if night_protect then + on_blast = function() end +end + +minetest.register_node("commoditymarket:night_market", { + description = night_def.description, + _doc_items_longdesc = night_def.long_description, + _doc_items_usagehelp = usage_help, + tiles = {"default_chest_top.png","default_chest_top.png", + "default_chest_side.png","default_chest_side.png", + "commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_moon.png",}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local timeofday = minetest.get_timeofday() + if timeofday < 0.2 or timeofday > 0.8 then + commoditymarket.show_market("night", clicker:get_player_name()) + else + minetest.chat_send_player(clicker:get_player_name(), S("At this time of day the Night Market is closed.")) + minetest.sound_play({name = "commoditymarket_error", gain = 0.1}, {to_player=clicker:get_player_name()}) + end + end, + can_dig = function(pos, player) + return not night_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) +end + +------------------------------------------------------------------------------- +if minetest.settings:get_bool("commoditymarket_enable_caravan_market", true) then +-- "Trader's Caravan" - small-capacity market that players can summon + +local time_until_caravan = 120 -- caravan arrives in two minutes +local dwell_time = 600 -- caravan leaves ten minutes after last usage + +local caravan_def = { + description = S("Trader's Caravan"), + long_description = S("Unlike most markets that have well-known fixed locations that travelers congregate to, the network of Trader's Caravans is fluid and dynamic in their locations. A Trader's Caravan can show up anywhere, make modest trades, and then be gone the next time you visit them. These caravans accept gold and gold coins as a currency (one gold ingot to one thousand gold coins exchange rate). Any reasonably-wealthy person can create a signpost marking a location where Trader's Caravans will make a stop."), + currency = { + ["default:gold_ingot"] = 1000, + ["commoditymarket:gold_coins"] = 1 + }, + currency_symbol = "☼", --"\u{263C}" + inventory_limit = 1000, + sell_limit = 1000, + initial_items = default_items, +} + +register_gold_coins() + +minetest.register_craft({ + output = "commoditymarket:caravan_post", + recipe = { + {'group:wood', 'group:wood', ''}, + {'group:wood', "default:gold_ingot", ''}, + {'group:wood', "default:chest_locked", ''}, + } +}) + +commoditymarket.register_market("caravan", caravan_def) + +local create_caravan_def = function(override_table) +local def = { + description = caravan_def.description, + _doc_items_longdesc = caravan_def.long_description, + _doc_items_usagehelp = usage_help, + drawtype = "mesh", + mesh = "commoditymarket_wagon.obj", + tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_wood.png", backface_culling = true }, -- base wood + { name = "default_fence_rail_wood.png", backface_culling = true }, -- wheel sides + { name = "default_coal_block.png", backface_culling = true }, -- wheel tyre + { name = "commoditymarket_shingles_wood.png", backface_culling = true }, -- roof + { name = "default_junglewood.png", backface_culling = true }, -- corner wood + }, + collision_box = { + type = "fixed", + fixed = { + {-0.75, -0.5, -1.25, 0.75, 1.5, 1.25}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.75, -0.5, -1.25, 0.75, 1.5, 1.25}, + }, + }, + + paramtype2 = "facedir", + drop = "", + groups = {choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + commoditymarket.show_market("caravan", clicker:get_player_name()) + local timer = minetest.get_node_timer(pos) + timer:start(dwell_time) + end, + after_destruct = function(pos, oldnode) + local facedir = oldnode.param2 + local dir = minetest.facedir_to_dir(facedir) + local target = vector.add(pos, vector.multiply(dir,-3)) + local target_node = minetest.get_node(target) + if target_node.name == "commoditymarket:caravan_post" then + local meta = minetest.get_meta(target) + meta:set_string("infotext", S("Right-click to summon a trader's caravan")) + end + end, + on_timer = function(pos, elapsed) + minetest.set_node(pos, {name="air"}) + minetest.sound_play("commoditymarket_register_closed", { + pos = pos, + gain = 1.0, -- default + max_hear_distance = 32, -- default, uses an euclidean metric + }) + end, + } + if override_table then + for k, v in pairs(override_table) do + def[k] = v + end + end + return def +end + +-- Create five caravans with different textures, randomly pick which one shows up. +minetest.register_node("commoditymarket:caravan_market_1", create_caravan_def()) +minetest.register_node("commoditymarket:caravan_market_2", create_caravan_def({ +tiles = { + { name = "commoditymarket_door_wood.png^[multiply:#CCCCFF", backface_culling = true }, -- door + { name = "default_acacia_wood.png", backface_culling = true }, -- base wood + { name = "default_fence_rail_wood.png", backface_culling = true }, -- wheel sides + { name = "default_copper_block.png", backface_culling = true }, -- wheel tyre + { name = "commoditymarket_shingles_wood.png^[multiply:#CC8888", backface_culling = true }, -- roof + { name = "default_wood.png", backface_culling = true }, -- corner wood +} +})) +minetest.register_node("commoditymarket:caravan_market_3", create_caravan_def({ +tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_aspen_wood.png", backface_culling = true }, -- base wood + { name = "default_fence_aspen_wood.png", backface_culling = true }, -- wheel sides + { name = "default_cobble.png", backface_culling = true }, -- wheel tyre + { name = "default_stone_brick.png", backface_culling = true }, -- roof + { name = "default_pine_tree.png", backface_culling = true }, -- corner wood +} +})) +minetest.register_node("commoditymarket:caravan_market_4", create_caravan_def({ +tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_junglewood.png", backface_culling = true }, -- base wood + { name = "default_fence_rail_junglewood.png", backface_culling = true }, -- wheel sides + { name = "default_obsidian.png", backface_culling = true }, -- wheel tyre + { name = "commoditymarket_shingles_wood.png^[multiply:#88FF88", backface_culling = true }, -- roof + { name = "default_tree.png", backface_culling = true }, -- corner wood +} +})) +minetest.register_node("commoditymarket:caravan_market_5", create_caravan_def({ +tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_pine_wood.png", backface_culling = true }, -- base wood + { name = "default_chest_lock.png", backface_culling = true }, -- wheel sides + { name = "default_chest_top.png", backface_culling = true }, -- wheel tyre + { name = "default_furnace_top.png", backface_culling = true }, -- roof + { name = "default_wood.png", backface_culling = true }, -- corner wood +} +})) + +local caravan_protect = minetest.settings:get_bool("commoditymarket_protect_caravan_market", true) +local on_blast +if caravan_protect then + on_blast = function() end +end + +-- This one doesn't delete itself, server admins can place a permanent instance of it that way. Maybe inside towns next to bigger stationary markets. +minetest.register_node("commoditymarket:caravan_market_permanent", { + description = caravan_def.description, + _doc_items_longdesc = caravan_def.long_description, + _doc_items_usagehelp = usage_help, + drawtype = "mesh", + mesh = "commoditymarket_wagon.obj", + tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_wood.png", backface_culling = true }, -- base wood + { name = "default_fence_rail_wood.png", backface_culling = true }, -- wheel sides + { name = "default_coal_block.png", backface_culling = true }, -- wheel tyre + { name = "commoditymarket_shingles_wood.png", backface_culling = true }, -- roof + { name = "default_junglewood.png", backface_culling = true }, -- corner wood + }, + collision_box = { + type = "fixed", + fixed = { + {-0.75, -0.5, -1.25, 0.75, 1.5, 1.25}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.75, -0.5, -1.25, 0.75, 1.5, 1.25}, + }, + }, + + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + commoditymarket.show_market("caravan", clicker:get_player_name()) + end, + can_dig = function(pos, player) + return not caravan_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) + +-- is a 5x3 area centered around pos clear of obstruction and has usable ground? +local is_suitable_caravan_space = function(pos, facedir) + local x_dim = 2 + local z_dim = 2 + local dir = minetest.facedir_to_dir(facedir) + if dir.x ~= 0 then + z_dim = 1 + elseif dir.z ~= 0 then + x_dim = 1 + end + + -- walkable ground? + for x = pos.x - x_dim, pos.x + x_dim, 1 do + for z = pos.z - z_dim, pos.z + z_dim, 1 do + local node = minetest.get_node({x=x, y=pos.y-1, z=z}) + local node_def = minetest.registered_nodes[node.name] + if node_def == nil or node_def.walkable ~= true then return false end + end + end + -- buildable_to in the rest? + for y = pos.y, pos.y+2, 1 do + for x = pos.x - x_dim, pos.x + x_dim, 1 do + for z = pos.z - z_dim, pos.z + z_dim, 1 do + local node = minetest.get_node({x=x, y=y, z=z}) + local node_def = minetest.registered_nodes[node.name] + if node_def == nil or node_def.buildable_to ~= true then return false end + end + end + end + return true +end + +minetest.register_node("commoditymarket:caravan_post", { + description = S("Trading Post"), + _long_items_longdesc = S("This post signals passing caravan traders that customers can be found here, and signals to customers that caravan traders can be found here. If no caravan is present, right-click to summon one."), + _doc_items_usagehelp = S("The trader's caravan requires a suitable open space next to the trading post for it to arrive, and takes some time to arrive after being summoned. The post gives a countdown to the caravan's arrival when moused over."), + tiles = {"commoditymarket_sign.png^[transformR90", "commoditymarket_sign.png^[transformR270", + "commoditymarket_sign.png^commoditymarket_caravan_sign.png", "commoditymarket_sign.png^commoditymarket_caravan_sign.png^[transformFX", + "commoditymarket_sign_post.png", "commoditymarket_sign_post.png"}, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + inventory_image = "commoditymarket_caravan_sign_inventory.png", + paramtype= "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.125,-0.5,-0.5,0.125,2.0625,-0.25}, + {-0.0625,1.4375,-0.25,0.0625,2.0,0.5}, + }, + }, + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(1.0) + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local timer = minetest.get_node_timer(pos) + timer:start(1.0) + end, + on_timer = function(pos, elapsed) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + if node.name ~= "commoditymarket:caravan_post" then + return -- the node was removed + end + local facedir = node.param2 + local dir = minetest.facedir_to_dir(facedir) + local target = vector.add(pos, vector.multiply(dir,3)) + + local target_node = minetest.get_node(target) + + if target_node.name:sub(1,string.len("commoditymarket:caravan_market")) == "commoditymarket:caravan_market" then + -- It's already here somehow, shut down timer. + meta:set_string("infotext", "") + meta:set_float("wait_time", 0) + return + end + + local is_suitable_space = is_suitable_caravan_space(target, facedir) + + if not is_suitable_space then + meta:set_string("infotext", S("Indicated parking area isn't suitable.\nA 5x3 open space with solid ground\nis required for a caravan.")) + meta:set_float("wait_time", 0) + local timer = minetest.get_node_timer(pos) + timer:start(1.0) + return + end + + local wait_time = (meta:get_float("wait_time") or 0) + elapsed + meta:set_float("wait_time", wait_time) + if wait_time < time_until_caravan then + meta:set_string("infotext", S("Caravan summoned\nETA: @1 seconds.", math.floor(time_until_caravan - wait_time))) + local timer = minetest.get_node_timer(pos) + timer:start(1.0) + return + end + + -- spawn the caravan. We've already established that the target pos is clear. + minetest.set_node(target, {name="commoditymarket:caravan_market_"..math.random(1,5), param2=facedir}) + minetest.sound_play("commoditymarket_register_opened", { + pos = target, + gain = 1.0, -- default + max_hear_distance = 32, -- default, uses an euclidean metric + }) + local timer = minetest.get_node_timer(target) + timer:start(dwell_time) + meta:set_string("infotext", "") + meta:set_float("wait_time", 0) + end, +}) +end + +------------------------------------------------------------------------------- +-- "Goblin Exchange" +if minetest.settings:get_bool("commoditymarket_enable_goblin_market") then + +local goblin_def = { + description = S("Goblin Exchange"), + long_description = S("One does not usually associate Goblins with the sort of sophistication that running a market requires. Usually one just associates Goblins with savagery and violence. But they understand the principle of tit-for-tat exchange, and if approached correctly they actually respect the concepts of ownership and debt. However, for some peculiar reason they understand this concept in the context of coal lumps. Goblins deal in the standard coal lump as their form of currency, conceptually divided into 100 coal centilumps (though Goblin brokers prefer to \"keep the change\" when giving back actual coal lumps)."), + currency = { + ["default:coal_lump"] = 100 + }, + currency_symbol = "¢", --"\u{00A2}" cent symbol + inventory_limit = 1000, + --sell_limit =, -- no sell limit +} + +commoditymarket.register_market("goblin", goblin_def) + +local goblin_protect = minetest.settings:get_bool("commoditymarket_protect_goblin_market", true) +local on_blast +if goblin_protect then + on_blast = function() end +end + +minetest.register_node("commoditymarket:goblin_market", { + description = goblin_def.description, + _doc_items_longdesc = goblin_def.long_description, + _doc_items_usagehelp = usage_help, + tiles = {"default_chest_top.png^(default_coal_block.png^[opacity:128)","default_chest_top.png^(default_coal_block.png^[opacity:128)", + "default_chest_side.png^(default_coal_block.png^[opacity:128)","default_chest_side.png^(default_coal_block.png^[opacity:128)", + "commoditymarket_empty_shelf.png^(default_coal_block.png^[opacity:128)","default_chest_side.png^(default_coal_block.png^[opacity:128)^commoditymarket_goblin.png",}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + commoditymarket.show_market("goblin", clicker:get_player_name()) + end, + can_dig = function(pos, player) + return not goblin_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) +end +-------------------------------------------------------------------------------- + +if minetest.settings:get_bool("commoditymarket_enable_under_market") then +local undermarket_def = { + description = S("Undermarket"), + long_description = S("Deep in the bowels of the world, below even the goblin-infested warrens and ancient delvings of the dwarves, dark and mysterious beings once dwelled. A few still linger to this day, and facilitate barter for those brave souls willing to travel in their lost realms. The Undermarket uses Mese chips ('â‚¥') as a currency - twenty chips to the Mese fragment. Though traders are loathe to physically break Mese crystals up into units that small, as it renders it useless for other purposes."), + currency = { + ["default:mese"] = 9*9*20, + ["default:mese_crystal"] = 9*20, + ["default:mese_crystal_fragment"] = 20 + }, + currency_symbol = "â‚¥", --"\u{20A5}" mill sign + inventory_limit = 10000, + --sell_limit =, -- no sell limit +} + +commoditymarket.register_market("under", undermarket_def) + +local under_protect = minetest.settings:get_bool("commoditymarket_protect_under_market", true) +local on_blast +if under_protect then + on_blast = function() end +end + +minetest.register_node("commoditymarket:under_market", { + description = undermarket_def.description, + _doc_items_longdesc = undermarket_def.long_description, + _doc_items_usagehelp = usage_help, + tiles = {"commoditymarket_under_top.png","commoditymarket_under_top.png", + "commoditymarket_under.png","commoditymarket_under.png","commoditymarket_under.png","commoditymarket_under.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_stone_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + commoditymarket.show_market("under", clicker:get_player_name()) + end, + can_dig = function(pos, player) + return not under_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) +end +------------------------------------------------------------------ diff --git a/mods/commoditymarket/doc.lua b/mods/commoditymarket/doc.lua new file mode 100644 index 0000000..7fa24db --- /dev/null +++ b/mods/commoditymarket/doc.lua @@ -0,0 +1,41 @@ +if not minetest.get_modpath("doc") then + return +end + +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +doc.add_category("commoditymarket", +{ + name = S("Commodity Markets"), + description = S("Game-wide marketplaces where goods can be bought and sold at prices of your choice."), + build_formspec = doc.entry_builders.text_and_gallery, +}) + +doc.add_entry("commoditymarket", "ui_inventory", { + name = S("User Interface: Inventory"), + data = { text = +S("Each player's account has an inventory that serves as a holding area for items that are destined to be sold or that have been bought by the player but not yet retrieved. This inventory is a bit different from the standard Minetest inventory in that it doesn't hold item \"stacks\", it just tracks the total number of that item present. Some markets allow for extremely large quantities of an item to be stored here for sale." +.."\n\n".. +"To add an item to your market inventory for eventual sale either shift-click on the item in your player inventory or drag the item stack to the inventory slot below the main market inventory list. Some markets may have restrictions on what items can be bought and sold, if an item is not valid for that market it won't go into the market's inventory. Some items are considered \"currency\" and will add to your account's currency balance instead of being listed in your market inventory." +.."\n\n".. +"Tools cannot be added to the market inventory if they have any wear on them. The market also can't handle items with attached metadata such as books that have had text added to them." +.."\n\n".. +"To remove an item from your market inventory, double-click in it in the market inventory list. As much of the item as can fit into your player inventory will be transferred to you, with any remainder staying behind in the market inventory. To withdraw currency from your market balance type the amount you'd like to withdraw in the field next to the \"Withdraw\" button. The currency will be converted into items and added to your player inventory, with whatever cannot be converted remaining behind in your market balance.") +}}) + +doc.add_entry("commoditymarket", "ui_orders", { + name = S("User Interface: Orders"), + data = { text = +S( +"At the core of how a market operates are \"buy\" and \"sell\" orders. A buy order is an announcement to the world that you are interested in purchasing a certain quantity of item and are willing to pay a certain amount of currency in exchange for each unit of that item. Conversely, a sell order is an announcement to the world that you are interested in selling a certain quantity of item and will accept a certain amount of currency in exchange for each unit of that item." +.."\n\n".. +"The market price of an item is determined by where the existing buy and sell orders for that item intersect. When you offer to buy an item for a price that someone is offering to sell it at, the item is transferred to you and currency is transferred from your account to theirs to cover the cost. The market will keep track of the most recent price that an item was successfully sold for, but note that this information is for historical interest only - there's no guarantee that anyone is currently willing to match the historical price." +.."\n\n".. +"When an item is selected in the upper list, the currently existing buy and sell orders for that item will be displayed in the lower list. Sell orders are listed first in descending price, followed by buy orders in ascending price. The current market price will be somewhere in between the lowest sell order and the highest buy order. If you wish to cancel a buy or sell order that you've placed for an item, double-click on the order and the item or currency that you put into that order will be returned to your inventory." +.."\n\n".. +"If you place a buy order and there are already sell orders for the item that meet or are below your price, some or all of your buy order might be immediately fulfilled. Your purchases will be made at the price that the sell orders have been set to - if you were willing to pay 15 units of currency per item but someone was already offering to sell for 2 units of currency per item, you only pay 2 units for each of that offer's items. If there aren't enough compatible sell orders to fulfill your buy order, the remainder will be placed into the market and made available for future sellers to see and fulfill if they agree to your price. Your buy order will immediately deduct the currency required for it from your account's balance, but if you cancel your order you will get that currency back - it's not gone until the order is actually fulfilled." +.."\n\n".. +"If you place a sell order and there are already buy orders that meet or exceed your price, some or all of your sell order may be immediately fulfilled. You'll be paid the price that the buyers are offering rather than the amount you're demanding. If any of your sell offer is left unfulfilled, the sell order will be added to the market for future buyers to see. The items for this offer will be immediately taken from your market inventory but if you cancel your order you will get those items back.") +}}) \ No newline at end of file diff --git a/mods/commoditymarket/formspecs.lua b/mods/commoditymarket/formspecs.lua new file mode 100644 index 0000000..9f50421 --- /dev/null +++ b/mods/commoditymarket/formspecs.lua @@ -0,0 +1,790 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local truncate_item_names_to = 30 + +-- Large textures can screw with the formspecs. +-- See https://github.com/minetest/minetest/issues/9300 for a feature request that would simplify and improve icon generation, if supported. +-- In the meantime, here's some methods for overriding item icons to manually work around this: +local override_item_icon = {} +commoditymarket.override_item_icon = function(item_name, new_icon_texture) + override_item_icon[item_name] = new_icon_texture +end +local override_image_icon = {} +commoditymarket.override_image_icon = function(old_icon_texture, new_icon_texture) + override_image_icon[old_icon_texture] = new_icon_texture +end +-- And a setting for disabling icons entirely: +local global_enable_item_icons = minetest.settings:get_bool("commoditymarket_enable_item_icons", true) + +--[inventorycube{{{ +--Escaping does not apply here and `^` is replaced by `&` in texture names instead. +--Example: +-- [inventorycube{grass.png{dirt.png&grass_side.png{dirt.png&grass_side.png +--Creates an inventorycube with `grass.png`, `dirt.png^grass_side.png` and `dirt.png^grass_side.png` textures +local process_inventory_cube = function(texture_string) + if not texture_string:sub(1,14) == "[inventorycube" then + return texture_string + end + local split = texture_string:split("{") + local left = split[3] -- the "front" of the cube we're seeing in the inventory list + if left == nil then -- in case something weird happens, don't crash. + return texture_string + end + left = left:gsub("&", "^") + return left +end + +local get_icon = function(item) + local def = minetest.registered_items[item] + local returnstring = "unknown_item.png" + if def == nil then + return returnstring + end + + local override = override_item_icon[item] + if override then + return override + end + + local inventory_image = def.inventory_image + if inventory_image and inventory_image ~= "" then + returnstring = inventory_image + else + local tiles = def.tiles + if tiles then + local tilecount = #tiles + -- Textures of node; +Y, -Y, +X, -X, +Z, -Z + local selected_tile = tiles[math.min(5,tilecount)] + if type(selected_tile) == "string" then + returnstring = selected_tile + else + local tile_name = selected_tile.name + if tile_name then + returnstring = tile_name + end + end + end + end + returnstring = process_inventory_cube(returnstring) + + -- Formspec tables can't handle image compositing and modifiers + local found_caret = returnstring:find("%^") + if found_caret then + returnstring = returnstring:sub(1, found_caret-1) + end + + override = override_image_icon[returnstring] + if override then + return override + end + + return minetest.formspec_escape(returnstring) +end +-- Exposed so that the purge_unknowns command can use it. +commoditymarket.get_icon = get_icon + + +local truncate_string = function(target, length) + if target:len() > length then + return target:sub(1,length-2).."..." + end + return target +end + +local get_item_description = function(item) + local def = minetest.registered_items[item] + if def then + local description = def.description + if description then + return minetest.formspec_escape(description:gsub("\n", " ")) + end + end + return S("Unknown Item") +end + +-- Inventory formspec +------------------------------------------------------------------------------------- + +local inventory_item_comp = function(invitem1, invitem2) return invitem1.item < invitem2.item end +local inventory_desc_comp = function(invitem1, invitem2) return invitem1.description < invitem2.description end + +local get_account_formspec = function(market, account) + local show_itemnames = account.show_itemnames == "true" + local show_icons = global_enable_item_icons and ((account.show_icons or "true") == "true") + local market_def = market.def + + local inventory = {} + local inventory_count = 0 + for item, quantity in pairs(account.inventory) do + local icon + if show_icons then + icon = get_icon(item) + end + table.insert(inventory, {item=item, quantity=quantity, icon=icon, description=get_item_description(item)}) + inventory_count = inventory_count + quantity + end + if show_itemnames then + table.sort(inventory, inventory_item_comp) + else + table.sort(inventory, inventory_desc_comp) + end + + local formspec = { + "size[10,10]" + .."tabheader[0,0;tabs;"..market_def.description..","..S("Your Inventory")..","..S("Market Orders")..";2;false;true]" + } + formspec[#formspec+1] = "tablecolumns[" + + if show_icons then + formspec[#formspec+1] = "image" + for i=1, #inventory, 2 do + formspec[#formspec+1] = ","..i.."="..inventory[i].icon + end + formspec[#formspec+1] = ";" + end + if show_itemnames then + formspec[#formspec+1] = "text;" + end + formspec[#formspec+1] = "text;text,align=center" + if show_icons then + formspec[#formspec+1] = ";image" + for i=2, #inventory, 2 do + formspec[#formspec+1] = ","..i.."="..inventory[i].icon + end + end + if show_itemnames then + formspec[#formspec+1] = ";text" + end + formspec[#formspec+1] = ";text;text,align=center]" + .."tooltip[inventory;"..S("All the items you've transfered to the market to sell and the items you've\npurchased with buy orders. Double-click on an item to bring it back into your\npersonal inventory.").."]" + .."table[0,0;9.75,4;inventory;" + if show_icons then + formspec[#formspec+1] = "0," + end + if show_itemnames then + formspec[#formspec+1] = S("Item").."," + end + formspec[#formspec+1] = S("Description")..","..S("Quantity") + if show_icons then + formspec[#formspec+1] = ",0" + end + if show_itemnames then + formspec[#formspec+1] = ","..S("Item") + end + formspec[#formspec+1] = ","..S("Description")..","..S("Quantity") + + for i, entry in ipairs(inventory) do + if show_icons then + formspec[#formspec+1] = "," .. i + end + if show_itemnames then + formspec[#formspec+1] = "," .. truncate_string(entry.item, truncate_item_names_to) + end + -- no need to formspec_escape description here, it gets done when it's initially added to the inventory table + formspec[#formspec+1] = "," .. entry.description .. "," .. entry.quantity + end + + formspec[#formspec+1] = "]container[1,4.5]list[detached:commoditymarket:" .. market.name .. ";add;0,0;1,1;]" + .."label[1,0;"..S("Drop items here to\nadd to your account").."]" + .."listring[current_player;main]listring[detached:commoditymarket:" .. market.name .. ";add]" + + if market_def.inventory_limit then + formspec[#formspec+1] = "label[3,0;"..S("Inventory limit:").."\n" .. inventory_count.."/" .. market_def.inventory_limit .. "]" + .. "tooltip[3,0;1.5,1;"..S("You can still receive purchased items if you've exceeded your inventory limit,\nbut you won't be able to transfer items from your personal inventory into\nthe market until you've emptied it back down below the limit again.").."]" + end + formspec[#formspec+1] = "label[4.9,0;"..S("Balance:") .. "\n" .. market_def.currency_symbol .. account.balance .. "]" + .."tooltip[4.9,0;3.5,1;"..S("Enter the amount of currency you'd like to withdraw then click the 'Withdraw'\nbutton to convert it into items and transfer it to your personal inventory.").."]" + .."field[6.1,0.325;1,1;withdrawamount;;]" + .."field_close_on_enter[withdrawamount;false]" + .."button[6.7,0;1.2,1;withdraw;"..S("Withdraw").."]" + .."container_end[]" + .."container[1,5.75]list[current_player;main;0,0;8,1;]" + .."list[current_player;main;0,1.25;8,3;8]container_end[]" + + return table.concat(formspec) +end + + +-- Market formspec +-------------------------------------------------------------------------------------------------------- + +local compare_market_item = function(mkt1, mkt2) + return mkt1.item < mkt2.item +end +local compare_market_desc = function(mkt1, mkt2) + -- TODO: see https://github.com/minetest/minetest/issues/8398 for sorting localized strings + return get_item_description(mkt1.item) < get_item_description(mkt2.item) +end +local compare_buy_volume = function(mkt1, mkt2) + return mkt1.buy_volume > mkt2.buy_volume +end +local compare_buy_max = function(mkt1, mkt2) + return ((mkt1.buy_orders[#mkt1.buy_orders] or {}).price or -2^30) > ((mkt2.buy_orders[#mkt2.buy_orders] or {}).price or -2^30) +end +local compare_sell_volume = function(mkt1, mkt2) + return mkt1.sell_volume > mkt2.sell_volume +end +local compare_sell_min = function(mkt1, mkt2) + return ((mkt1.sell_orders[#mkt1.sell_orders] or {}).price or 2^31) < ((mkt2.sell_orders[#mkt2.sell_orders] or {}).price or 2^31) +end +local compare_last_price = function(mkt1, mkt2) + return (mkt1.last_price or 2^31) < (mkt2.last_price or 2^31) +end + +local sort_marketlist = function(item_list, account) + -- I think tonumber is now redundant here, leaving it in in case upgrading a world that has text recorded in this field for an existing player account + local sort_by = tonumber(account.sort_markets_by_column) + if sort_by == nil then return end + local show_itemnames = account.show_itemnames == "true" + local show_icons = global_enable_item_icons and ((account.show_icons or "true") == "true") + + local icon_displace = 0 + if show_icons then + icon_displace = 1 + end + local itemname_displace = 0 + if show_itemnames then + itemname_displace = 1 + end + + -- "Icon,Item,Description,#00FF00,Buy Vol,Buy Max,#FF0000,Sell Vol,Sell Min,Last Price" + if sort_by == 1 + icon_displace and show_itemnames then + table.sort(item_list, compare_market_item) + elseif sort_by == 1 + icon_displace + itemname_displace then + table.sort(item_list, compare_market_desc) + elseif sort_by == 3 + icon_displace + itemname_displace then + table.sort(item_list, compare_buy_volume) + elseif sort_by == 4 + icon_displace + itemname_displace then + table.sort(item_list, compare_buy_max) + elseif sort_by == 6 + icon_displace + itemname_displace then + table.sort(item_list, compare_sell_volume) + elseif sort_by == 7 + icon_displace + itemname_displace then + table.sort(item_list, compare_sell_min) + elseif sort_by == 8 + icon_displace + itemname_displace then + table.sort(item_list, compare_last_price) + elseif sort_by == 9 + icon_displace + itemname_displace then + table.sort(item_list, function(mkt1, mkt2) + -- Define locally so that account is available + return (account.inventory[mkt1.item] or 0) > (account.inventory[mkt2.item] or 0) + end) + end +end + +local make_marketlist = function(market, account) + local market_list = {} + local search_filter = account.search or "" + for item, row in pairs(market.orders_for_items) do + if (search_filter == "" or string.find(item, search_filter)) then + if account.filter_participating == "true" then + local found = false + for _, order in ipairs(row.buy_orders) do + if account == order.account then + found = true + break + end + end + if not found then + for _, order in ipairs(row.sell_orders) do + if account == order.account then + found = true + break + end + end + end + if found then + table.insert(market_list, row) + end + else + table.insert(market_list, row) + end + end + end + sort_marketlist(market_list, account) + return market_list +end + +local get_account_name = function(target_account, this_account, anonymous) + if anonymous and target_account ~= this_account then + return "" + end + return target_account.name +end + +local get_market_formspec = function(market, account) + local market_def = market.def + local selected = account.selected + local market_list = make_marketlist(market, account) + local show_itemnames = account.show_itemnames == "true" + local show_icons = global_enable_item_icons and ((account.show_icons or "true") == "true") + local anonymous = market_def.anonymous + + local formspec = { + "size[10,10]" + .."tabheader[0,0;tabs;"..market_def.description..","..S("Your Inventory")..","..S("Market Orders")..";3;false;true]" + } + + -- column definitions + formspec[#formspec+1] = "tablecolumns[" + if show_icons then + formspec[#formspec+1] = "image" -- icon + for i, row in ipairs(market_list) do + formspec[#formspec+1] = "," .. i .. "=" .. get_icon(row.item) + end + formspec[#formspec+1] = ";" + end if show_itemnames then + formspec[#formspec+1] = "text;" -- itemname + end + formspec[#formspec+1] = "text;" -- description + .."color,span=2;" + .."text,align=right,tooltip="..S("Number of items there's demand for in the market.")..";" + .."text,align=right,tooltip="..S("Maximum price being offered to buy one of these.")..";" + .."color,span=2;" + .."text,align=right,tooltip="..S("Number of items available for sale in the market.")..";" + .."text,align=right,tooltip="..S("Minimum price being demanded to sell one of these.")..";" + .."text,align=right,tooltip="..S("Price paid for one of these the last time one was sold.")..";" + .."text,align=right,tooltip="..S("Quantity of this item that you have in your inventory ready to sell.").."]" + .."table[0,0;9.75,5;summary;" + if show_icons then + formspec[#formspec+1] = "0,"-- icon + end + + -- header row + if show_itemnames then + formspec[#formspec+1] = "Item," -- itemname + end + formspec[#formspec+1] = S("Description")..",#00FF00,"..S("Buy Vol")..","..S("Buy Max") + ..",#FF0000,"..S("Sell Vol")..","..S("Sell Min")..","..S("Last Price")..","..S("Inventory") + + local selected_idx + local selected_row + + -- Show list of item market summaries + for i, row in ipairs(market_list) do + if show_icons then + formspec[#formspec+1] = ","..i -- icon + end + + if show_itemnames then + formspec[#formspec+1] = "," .. truncate_string(row.item, truncate_item_names_to) + end + + formspec[#formspec+1] = "," .. get_item_description(row.item) + .. ",#00FF00," + .. row.buy_volume + .. "," .. ((row.buy_orders[#row.buy_orders] or {}).price or "-") + .. ",#FF0000," + .. row.sell_volume + .. "," .. ((row.sell_orders[#row.sell_orders] or {}).price or "-") + .. "," .. (row.last_price or "-") + .. "," .. (account.inventory[row.item] or "-") + + -- we happen to be processing the row that matches the item this player has selected. Record that. + if selected == row.item then + selected_row = row + selected_idx = i + 1 + end + + end + -- a row that's visible is marked as the selected item, so make it selected in the formspec + if selected_row then + formspec[#formspec+1] = ";"..selected_idx + end + formspec[#formspec+1] = "]" + + -- search field + formspec[#formspec+1] = "container[2.5,5]field_close_on_enter[search_filter;false]" + .."field[0,0.85;2.5,1;search_filter;;"..minetest.formspec_escape(account.search or "").."]" + .."image_button[2.05,0.65;0.8,0.8;commoditymarket_search.png;apply_search;]" + .."image_button[2.7,0.65;0.8,0.8;commoditymarket_clear.png;clear_search;]" + .."checkbox[1.77,0;filter_participating;"..S("My orders")..";".. account.filter_participating .."]" + .."tooltip[filter_participating;"..S("Select this to show only the markets where you have either a buy or a sell order pending.").."]" + .."tooltip[search_filter;"..S("Enter substring to search item identifiers for.").."]" + .."tooltip[apply_search;"..S("Apply search to outputs.").."]" + .."tooltip[clear_search;"..S("Clear search.").."]" + .."container_end[]" + + -- if a visible item market is selected, show the orders for it in detail + if selected_row then + local current_time = minetest.get_gametime() + + local desc_display + if show_itemnames then + desc_display = selected + else + local def = minetest.registered_items[selected_row.item] or {description=S("Unknown Item")} + desc_display = minetest.formspec_escape(def.description:gsub("\n", " ")) + end + + -- player inventory for this item and for currency + formspec[#formspec+1] = "label[0.1,5.1;"..desc_display.."\n"..S("In inventory:").." " + .. tostring(account.inventory[selected] or 0) .."\n"..S("Balance:").." "..market_def.currency_symbol..account.balance .."]" + -- buy/sell controls + .. "container[6.1,5]" + local sell_limit = market_def.sell_limit + if sell_limit then + local total_sell = 0 + for item, orders in pairs(market.orders_for_items) do + for _, order in ipairs(orders.sell_orders) do + if order.account == account then + total_sell = total_sell + order.quantity + end + end + end + formspec[#formspec+1] = "label[0,0;"..S("Sell limit:").." ".. total_sell .. "/" .. sell_limit .."]" + .."tooltip[0,0;2,0.25;"..S("This market limits the total number of items a given seller can have for sale at a time.\nYou have @1 items remaining. Cancel old sell orders to free up space.", sell_limit-total_sell).."]" + end + -- Buy, sell, quantity and price button + formspec[#formspec+1] = "tooltip[0,0.25;3.75,1;"..S("Use these fields to enter buy and sell orders for the selected item.").."]" + .."button[0,0.55;1,1;buy;"..S("Buy").."]field[1.2,0.85;1,1;quantity;"..S("Quantity")..";]" + .."field[2.1,0.85;1,1;price;"..S("Price per")..";]button[2.7,0.55;1,1;sell;Sell]" + .."field_close_on_enter[quantity;false]field_close_on_enter[price;false]" + .."container_end[]" + -- table of buy and sell orders + .."tablecolumns[color;text;" + .."text,align=right,tooltip="..S("The price per item in this order.")..";" + .."text,align=right,tooltip="..S("The total amount of items in this particular order.")..";" + .."text,align=right,tooltip="..S("The total amount of items available at this price accounting for the other orders also currently being offered.")..";" + .."text,tooltip="..S("The name of the player who placed this order.\nDouble-click your own orders to cancel them.")..";" + .."text,align=right,tooltip="..S("How many days ago this order was placed.").."]" + .."table[0,6.5;9.75,3.5;orders;#FFFFFF,"..S("Order")..","..S("Price")..","..S("Quantity")..","..S("Total Volume")..","..S("Player")..","..S("Days Old") + + local sell_volume = selected_row.sell_volume + for i, sell in ipairs(selected_row.sell_orders) do + formspec[#formspec+1] = ",#FF0000,"..S("Sell").."," + ..sell.price.."," + ..sell.quantity.."," + ..sell_volume.."," + ..get_account_name(sell.account, account, anonymous).."," + ..math.floor((current_time-sell.timestamp)/86400) + sell_volume = sell_volume - sell.quantity + end + local buy_volume = 0 + local buy_orders = selected_row.buy_orders + local buy_count = #buy_orders + -- Show buy orders in reverse order + for i = buy_count, 1, -1 do + local buy = buy_orders[i] + buy_volume = buy_volume + buy.quantity + formspec[#formspec+1] = ",#00FF00,"..S("Buy").."," + ..buy.price.."," + ..buy.quantity.."," + ..buy_volume.."," + ..get_account_name(buy.account, account, anonymous).."," + ..math.floor((current_time-buy.timestamp)/86400) + end + formspec[#formspec+1] = "]" + else + formspec[#formspec+1] = "label[0.1,5.1;"..S("Select an item to view or place orders.").."]" + end + + return table.concat(formspec) +end + +------------------------------------------------------------------------------------- +-- Information formspec + +--{item=item, quantity=quantity, price=price, purchaser=purchaser, seller=seller, timestamp = minetest.get_gametime()} +local log_to_string = function(market, log_entry, account) + local anonymous = market.def.anonymous + local purchaser = log_entry.purchaser + local seller = log_entry.seller + local purchaser_name + if purchaser == seller then + purchaser_name = S("yourself") + elseif anonymous and purchaser ~= account then + purchaser_name = S("someone") + elseif purchaser == account then + purchaser_name = S("you") + else + purchaser_name = purchaser.name + end + local seller_name + if anonymous and seller ~= account then + seller_name = S("someone") + elseif seller == account then + seller_name = S("you") + else + seller_name = seller.name + end + local colour + local new + local last_acknowledged = account.last_acknowledged or 0 + if log_entry.timestamp > last_acknowledged then + colour = "#FFFF00" + new = true + else + colour = "#FFFFFF" + new = false + end + local show_itemnames = account.show_itemnames == "true" + local itemname = log_entry.item + if not show_itemnames then + local item_def = minetest.registered_items[log_entry.item] + if item_def then + itemname = minetest.formspec_escape(item_def.description:gsub("\n", " ")) + end + end + + local currency_symbol = market.def.currency_symbol + return colour .. S("On day @1 @2 sold @3 @4 to @5 at @6@7 each for a total of @8@9.", + math.ceil(log_entry.timestamp/86400), seller_name, log_entry.quantity, itemname, + purchaser_name, currency_symbol, log_entry.price, currency_symbol, log_entry.quantity*log_entry.price), new +end + + +local get_info_formspec = function(market, account) + local formspec = { + "size[10,10]" + .."tabheader[0,0;tabs;"..market.def.description..","..S("Your Inventory")..","..S("Market Orders")..";1;false;true]" + .."textarea[0.75,0.5;9.25,1.5;;"..S("Description:")..";"..market.def.long_description.."]" + .."label[0.5,2.2;"..S("Your Recent Purchases and Sales:").."]" + .."textlist[0.5,2.6;8.75,4;log_entries;" + } + if next(account.log) then + local new = false + for _, log_entry in ipairs(account.log) do + local log_string, new_log = log_to_string(market, log_entry, account) + new = new or new_log + formspec[#formspec+1] = log_string + formspec[#formspec+1] = "," + end + formspec[#formspec] = "]" -- Note: there's no +1 here deliberately, that way the "]" overwrites the last comma added by the loop above. + if new then + formspec[#formspec+1] = "button[7.1,6.9;2,0.5;acknowledge_log;"..S("Mark logs as read").."]" .. + "tooltip[acknowledge_log;"..S("Log entries in yellow are new since last time you marked your log as read.").."]" + end + else + formspec[#formspec+1] = "#CCCCCC"..S("No logged activities in this market yet.").."]" + end + local show_itemnames = account.show_itemnames or "false" + + formspec[#formspec+1] = "]container[0.5, 7.5]label[0,0;Settings:]checkbox[0,0.25;show_itemnames;"..S("Show Itemnames")..";" + ..show_itemnames.."]" + if global_enable_item_icons then + local show_icons = account.show_icons or "true" + formspec[#formspec+1] = "checkbox[2,0.25;show_icons;"..S("Show Icons")..";"..show_icons.."]" + end + formspec[#formspec+1] = "container_end[]" + + return table.concat(formspec) +end + +--------------------------------------------------------------------------------------- + +commoditymarket.get_formspec = function(market, account) + local tab = account.tab + if tab == 1 then + return get_info_formspec(market, account) + elseif tab == 2 then + return get_account_formspec(market, account) + else + return get_market_formspec(market, account) + end +end + + +------------------------------------------------------------------------------------ +-- Handling recieve_fields + +local add_to_player_inventory = function(name, item, amount) + local playerinv = minetest.get_inventory({type="player", name=name}) + local not_full = true + while amount > 0 and not_full do + local stack = ItemStack(item .. " " .. amount) + amount = amount - stack:get_count() + local leftover = playerinv:add_item("main", stack) + if leftover:get_count() > 0 then + amount = amount + leftover:get_count() + return amount + end + end + return amount +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local formname_split = formname:split(":") + + if formname_split[1] ~= "commoditymarket" then + return false + end + local market = commoditymarket.registered_markets[formname_split[2]] + if not market then + return false + end + + local name = formname_split[3] + if name ~= player:get_player_name() then + return false + end + + local account = market:get_account(name) + local show_icons = global_enable_item_icons and ((account.show_icons or "true") == "true") + + local something_changed = false + if fields.tabs then + account.tab = tonumber(fields.tabs) + something_changed = true + end + -- player clicked on an item in the market summary table + if fields.summary then + local summaryevent = minetest.explode_table_event(fields.summary) + if summaryevent.type == "DCL" or summaryevent.type == "CHG" then + if summaryevent.row == 1 then + -- header clicked, sort by column + local column = tonumber(summaryevent.column) + if not (column == 1 and show_icons) then -- ignore clicks on the icon column header + account.sort_markets_by_column = column + end + else + -- item clicked, recreate the list to find out which one + local marketlist = make_marketlist(market, account) + local selected = marketlist[summaryevent.row-1] + if selected then + account.selected = selected.item + end + end + elseif summaryevent.type == "INV" then + account.selected = nil + end + something_changed = true + end + if fields.orders then + local ordersevent = minetest.explode_table_event(fields.orders) + if ordersevent.type == "DCL" and ordersevent.column > 0 then + local selected_idx = ordersevent.row - 1 -- account for header + local selected_row = market.orders_for_items[account.selected] -- sell orders come first + local sell_orders = selected_row.sell_orders + local sell_order_count = #sell_orders + local selected_order + if selected_idx <= sell_order_count then -- if the index is within the range of sell orders, + selected_order = sell_orders[selected_idx] + if selected_order and selected_order.account == account then -- and the order belongs to the current player, + market:cancel_sell(account.selected, selected_order) -- cancel it + something_changed = true + end + else + -- otherwise we're in the buy group, shift the index up by sell_order_count and reverse index order + local buy_orders = selected_row.buy_orders + local buy_orders_count = #buy_orders + selected_order = buy_orders[buy_orders_count - (selected_idx - sell_order_count - 1)] + if selected_order and selected_order.account == account then + market:cancel_buy(account.selected, selected_order) + something_changed = true + end + end + end + end + + if fields.buy then + local quantity = tonumber(fields.quantity) + local price = tonumber(fields.price) + if price ~= nil and quantity ~= nil then + market:buy(name, account.selected, quantity, price) + something_changed = true + end + end + if fields.sell then + local quantity = tonumber(fields.quantity) + local price = tonumber(fields.price) + if price ~= nil and quantity ~= nil then + market:sell(name, account.selected, quantity, price) + something_changed = true + end + end + + -- player clicked in their inventory table, may need to give him his stuff back + if fields.inventory then + local invevent = minetest.explode_table_event(fields.inventory) + if invevent.type == "DCL" and invevent.column > 0 then + local col_count = 8 + local show_itemnames = account.show_itemnames == "true" + if not show_itemnames then + col_count = col_count - 2 + end + if not show_icons then + col_count = col_count - 2 + end + local index = math.floor(((invevent.row-1)*col_count + invevent.column - 1)/(col_count/2)) - 1 + local account = market:get_account(name) + -- build a local copy of the inventory that would be displayed in the formspec so we can + -- figure out what item the index we were given is pointing to + local inventory = {} + for item, quantity in pairs(account.inventory) do + table.insert(inventory, {item=item, quantity=quantity, description=get_item_description(item)}) + end + if show_itemnames then + table.sort(inventory, inventory_item_comp) + else + table.sort(inventory, inventory_desc_comp) + end + if inventory[index] then + local item = inventory[index].item + local amount = account.inventory[item] + local remaining = add_to_player_inventory(name, item, amount) + if remaining == 0 then + account.inventory[item] = nil + else + account.inventory[item] = remaining + end + if remaining ~= amount then + something_changed = true + end + end + end + end + + if fields.withdraw or fields.key_enter_field == "withdrawamount" then + local withdrawvalue = tonumber(fields.withdrawamount) + if withdrawvalue then + local account = market:get_account(name) + withdrawvalue = math.min(withdrawvalue, account.balance) + for _, currency in ipairs(market.def.currency_ordered) do + this_unit_amount = math.floor(withdrawvalue/currency.amount) + if this_unit_amount > 0 then + local remaining = add_to_player_inventory(name, currency.item, this_unit_amount) + local value_given = (this_unit_amount - remaining) * currency.amount + account.balance = account.balance - value_given + withdrawvalue = withdrawvalue - value_given + something_changed = true + end + end + end + end + + if fields.search_filter then + local value = string.lower(fields.search_filter) + if account.search ~= value then + account.search = value + end + end + + local process_checkbox = function(property_name, fields, account) + if (fields[property_name] == "true" and account[property_name] ~= "true") or + (fields[property_name] == "false" and account[property_name] ~= "false") then + account[property_name] = fields[property_name] + return true + end + return false + end + + if process_checkbox("filter_participating", fields, account) then something_changed = true end + if process_checkbox("show_itemnames", fields, account) then something_changed = true end + if process_checkbox("show_icons", fields, account) then something_changed = true end + + if fields.acknowledge_log then + account.last_acknowledged = minetest.get_gametime() + something_changed = true + end + + if fields.apply_search or fields.key_enter_field == "search_filter" then + something_changed = true + end + + if fields.clear_search then + account.search = "" + something_changed = true + end + if something_changed then + minetest.show_formspec(name, formname, market:get_formspec(account)) + end +end) diff --git a/mods/commoditymarket/init.lua b/mods/commoditymarket/init.lua new file mode 100644 index 0000000..2edc593 --- /dev/null +++ b/mods/commoditymarket/init.lua @@ -0,0 +1,6 @@ +commoditymarket = {} + +local MP = minetest.get_modpath(minetest.get_current_modname()) +dofile(MP.."/formspecs.lua") +dofile(MP.."/market.lua") +dofile(MP.."/doc.lua") diff --git a/mods/commoditymarket/intllib.lua b/mods/commoditymarket/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/commoditymarket/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/commoditymarket/license.txt b/mods/commoditymarket/license.txt new file mode 100644 index 0000000..33bee86 --- /dev/null +++ b/mods/commoditymarket/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 FaceDeer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/commoditymarket/locale/template.pot b/mods/commoditymarket/locale/template.pot new file mode 100644 index 0000000..5ccc9a7 --- /dev/null +++ b/mods/commoditymarket/locale/template.pot @@ -0,0 +1,478 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-18 16:58-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: commoditymarket\doc.lua:11 +msgid "Commodity Markets" +msgstr "" + +#: commoditymarket\doc.lua:12 +msgid "" +"Game-wide marketplaces where goods can be bought and sold at prices of your " +"choice." +msgstr "" + +#: commoditymarket\doc.lua:17 +msgid "User Interface: Inventory" +msgstr "" + +#: commoditymarket\doc.lua:19 +msgid "" +"Each player's account has an inventory that serves as a holding area for " +"items that are destined to be sold or that have been bought by the player " +"but not yet retrieved. This inventory is a bit different from the standard " +"Minetest inventory in that it doesn't hold item \"stacks\", it just tracks " +"the total number of that item present. Some markets allow for extremely " +"large quantities of an item to be stored here for sale.\n" +"\n" +"To add an item to your market inventory for eventual sale either shift-click " +"on the item in your player inventory or drag the item stack to the inventory " +"slot below the main market inventory list. Some markets may have " +"restrictions on what items can be bought and sold, if an item is not valid " +"for that market it won't go into the market's inventory. Some items are " +"considered \"currency\" and will add to your account's currency balance " +"instead of being listed in your market inventory.\n" +"\n" +"Tools cannot be added to the market inventory if they have any wear on them. " +"The market also can't handle items with attached metadata such as books that " +"have had text added to them.\n" +"\n" +"To remove an item from your market inventory, double-click in it in the " +"market inventory list. As much of the item as can fit into your player " +"inventory will be transferred to you, with any remainder staying behind in " +"the market inventory. To withdraw currency from your market balance type the " +"amount you'd like to withdraw in the field next to the \"Withdraw\" button. " +"The currency will be converted into items and added to your player " +"inventory, with whatever cannot be converted remaining behind in your market " +"balance." +msgstr "" + +#: commoditymarket\doc.lua:29 +msgid "User Interface: Orders" +msgstr "" + +#: commoditymarket\doc.lua:32 +msgid "" +"At the core of how a market operates are \"buy\" and \"sell\" orders. A buy " +"order is an announcement to the world that you are interested in purchasing " +"a certain quantity of item and are willing to pay a certain amount of " +"currency in exchange for each unit of that item. Conversely, a sell order is " +"an announcement to the world that you are interested in selling a certain " +"quantity of item and will accept a certain amount of currency in exchange " +"for each unit of that item.\n" +"\n" +"The market price of an item is determined by where the existing buy and sell " +"orders for that item intersect. When you offer to buy an item for a price " +"that someone is offering to sell it at, the item is transferred to you and " +"currency is transferred from your account to theirs to cover the cost. The " +"market will keep track of the most recent price that an item was " +"successfully sold for, but note that this information is for historical " +"interest only - there's no guarantee that anyone is currently willing to " +"match the historical price.\n" +"\n" +"When an item is selected in the upper list, the currently existing buy and " +"sell orders for that item will be displayed in the lower list. Sell orders " +"are listed first in descending price, followed by buy orders in ascending " +"price. The current market price will be somewhere in between the lowest sell " +"order and the highest buy order. If you wish to cancel a buy or sell order " +"that you've placed for an item, double-click on the order and the item or " +"currency that you put into that order will be returned to your inventory.\n" +"\n" +"If you place a buy order and there are already sell orders for the item that " +"meet or are below your price, some or all of your buy order might be " +"immediately fulfilled. Your purchases will be made at the price that the " +"sell orders have been set to - if you were willing to pay 15 units of " +"currency per item but someone was already offering to sell for 2 units of " +"currency per item, you only pay 2 units for each of that offer's items. If " +"there aren't enough compatible sell orders to fulfill your buy order, the " +"remainder will be placed into the market and made available for future " +"sellers to see and fulfill if they agree to your price. Your buy order will " +"immediately deduct the currency required for it from your account's balance, " +"but if you cancel your order you will get that currency back - it's not gone " +"until the order is actually fulfilled.\n" +"\n" +"If you place a sell order and there are already buy orders that meet or " +"exceed your price, some or all of your sell order may be immediately " +"fulfilled. You'll be paid the price that the buyers are offering rather than " +"the amount you're demanding. If any of your sell offer is left unfulfilled, " +"the sell order will be added to the market for future buyers to see. The " +"items for this offer will be immediately taken from your market inventory " +"but if you cancel your order you will get those items back." +msgstr "" + +#: commoditymarket\formspecs.lua:104 +#: commoditymarket\formspecs.lua:424 +msgid "Unknown Item" +msgstr "" + +#: commoditymarket\formspecs.lua:136 +#: commoditymarket\formspecs.lua:333 +#: commoditymarket\formspecs.lua:547 +msgid "Your Inventory" +msgstr "" + +#: commoditymarket\formspecs.lua:136 +#: commoditymarket\formspecs.lua:333 +#: commoditymarket\formspecs.lua:547 +msgid "Market Orders" +msgstr "" + +#: commoditymarket\formspecs.lua:161 +msgid "" +"All the items you've transfered to the market to sell and the items you've\n" +"purchased with buy orders. Double-click on an item to bring it back into " +"your\n" +"personal inventory." +msgstr "" + +#: commoditymarket\formspecs.lua:167 +#: commoditymarket\formspecs.lua:174 +msgid "Item" +msgstr "" + +#: commoditymarket\formspecs.lua:169 +#: commoditymarket\formspecs.lua:176 +#: commoditymarket\formspecs.lua:365 +msgid "Description" +msgstr "" + +#: commoditymarket\formspecs.lua:169 +#: commoditymarket\formspecs.lua:176 +#: commoditymarket\formspecs.lua:448 +#: commoditymarket\formspecs.lua:459 +msgid "Quantity" +msgstr "" + +#: commoditymarket\formspecs.lua:190 +msgid "" +"Drop items here to\n" +"add to your account" +msgstr "" + +#: commoditymarket\formspecs.lua:194 +msgid "Inventory limit:" +msgstr "" + +#: commoditymarket\formspecs.lua:195 +msgid "" +"You can still receive purchased items if you've exceeded your inventory " +"limit,\n" +"but you won't be able to transfer items from your personal inventory into\n" +"the market until you've emptied it back down below the limit again." +msgstr "" + +#: commoditymarket\formspecs.lua:198 +msgid "" +"Enter the amount of currency you'd like to withdraw then click the " +"'Withdraw'\n" +"button to convert it into items and transfer it to your personal inventory." +msgstr "" + +#: commoditymarket\formspecs.lua:201 +msgid "Withdraw" +msgstr "" + +#: commoditymarket\formspecs.lua:349 +msgid "Number of items there's demand for in the market." +msgstr "" + +#: commoditymarket\formspecs.lua:350 +msgid "Maximum price being offered to buy one of these." +msgstr "" + +#: commoditymarket\formspecs.lua:352 +msgid "Number of items available for sale in the market." +msgstr "" + +#: commoditymarket\formspecs.lua:353 +msgid "Minimum price being demanded to sell one of these." +msgstr "" + +#: commoditymarket\formspecs.lua:354 +msgid "Price paid for one of these the last time one was sold." +msgstr "" + +#: commoditymarket\formspecs.lua:355 +msgid "Quantity of this item that you have in your inventory ready to sell." +msgstr "" + +#: commoditymarket\formspecs.lua:365 +msgid "Buy Vol" +msgstr "" + +#: commoditymarket\formspecs.lua:365 +msgid "Buy Max" +msgstr "" + +#: commoditymarket\formspecs.lua:366 +msgid "Sell Vol" +msgstr "" + +#: commoditymarket\formspecs.lua:366 +msgid "Sell Min" +msgstr "" + +#: commoditymarket\formspecs.lua:366 +msgid "Last Price" +msgstr "" + +#: commoditymarket\formspecs.lua:366 +msgid "Inventory" +msgstr "" + +#: commoditymarket\formspecs.lua:409 +msgid "My orders" +msgstr "" + +#: commoditymarket\formspecs.lua:410 +msgid "" +"Select this to show only the markets where you have either a buy or a sell " +"order pending." +msgstr "" + +#: commoditymarket\formspecs.lua:411 +msgid "Enter substring to search item identifiers for." +msgstr "" + +#: commoditymarket\formspecs.lua:412 +msgid "Apply search to outputs." +msgstr "" + +#: commoditymarket\formspecs.lua:413 +msgid "Clear search." +msgstr "" + +#: commoditymarket\formspecs.lua:429 +msgid "In inventory:" +msgstr "" + +#: commoditymarket\formspecs.lua:430 +msgid "Balance:" +msgstr "" + +#: commoditymarket\formspecs.lua:443 +msgid "Sell limit:" +msgstr "" + +#: commoditymarket\formspecs.lua:444 +msgid "" +"This market limits the total number of items a given seller can have for " +"sale at a time.\n" +"You have @1 items remaining. Cancel old sell orders to free up space." +msgstr "" + +#: commoditymarket\formspecs.lua:447 +msgid "Use these fields to enter buy and sell orders for the selected item." +msgstr "" + +#: commoditymarket\formspecs.lua:448 +#: commoditymarket\formspecs.lua:478 +msgid "Buy" +msgstr "" + +#: commoditymarket\formspecs.lua:449 +msgid "Price per" +msgstr "" + +#: commoditymarket\formspecs.lua:454 +msgid "The price per item in this order." +msgstr "" + +#: commoditymarket\formspecs.lua:455 +msgid "The total amount of items in this particular order." +msgstr "" + +#: commoditymarket\formspecs.lua:456 +msgid "" +"The total amount of items available at this price accounting for the other " +"orders also currently being offered." +msgstr "" + +#: commoditymarket\formspecs.lua:457 +msgid "" +"The name of the player who placed this order.\n" +"Double-click your own orders to cancel them." +msgstr "" + +#: commoditymarket\formspecs.lua:458 +msgid "How many days ago this order was placed." +msgstr "" + +#: commoditymarket\formspecs.lua:459 +msgid "Order" +msgstr "" + +#: commoditymarket\formspecs.lua:459 +msgid "Price" +msgstr "" + +#: commoditymarket\formspecs.lua:459 +msgid "Total Volume" +msgstr "" + +#: commoditymarket\formspecs.lua:459 +msgid "Player" +msgstr "" + +#: commoditymarket\formspecs.lua:459 +msgid "Days Old" +msgstr "" + +#: commoditymarket\formspecs.lua:463 +msgid "Sell" +msgstr "" + +#: commoditymarket\formspecs.lua:487 +msgid "Select an item to view or place orders." +msgstr "" + +#: commoditymarket\formspecs.lua:503 +msgid "yourself" +msgstr "" + +#: commoditymarket\formspecs.lua:505 +#: commoditymarket\formspecs.lua:513 +msgid "someone" +msgstr "" + +#: commoditymarket\formspecs.lua:507 +#: commoditymarket\formspecs.lua:515 +msgid "you" +msgstr "" + +#: commoditymarket\formspecs.lua:538 +msgid "On day @1 @2 sold @3 @4 to @5 at @6@7 each for a total of @6@8." +msgstr "" + +#: commoditymarket\formspecs.lua:548 +msgid "Description:" +msgstr "" + +#: commoditymarket\formspecs.lua:549 +msgid "Your Recent Purchases and Sales:" +msgstr "" + +#: commoditymarket\formspecs.lua:562 +msgid "Mark logs as read" +msgstr "" + +#: commoditymarket\formspecs.lua:563 +msgid "" +"Log entries in yellow are new since last time you marked your log as read." +msgstr "" + +#: commoditymarket\formspecs.lua:566 +msgid "No logged activites in this market yet." +msgstr "" + +#: commoditymarket\formspecs.lua:570 +msgid "Show Itemnames" +msgstr "" + +#: commoditymarket\formspecs.lua:574 +msgid "Show Icons" +msgstr "" + +#: commoditymarket\market.lua:198 +msgid "" +"You have too many items listed for sale in this market, please cancel some " +"sell orders to make room for new ones." +msgstr "" + +#: commoditymarket\market.lua:200 +msgid "You can't sell items for a negative price." +msgstr "" + +#: commoditymarket\market.lua:202 +msgid "You can't sell fewer than one item." +msgstr "" + +#: commoditymarket\market.lua:204 +msgid "" +"You don't have enough of that item in your inventory to post this sell order." +msgstr "" + +#: commoditymarket\market.lua:295 +msgid "You can't pay less than nothing for an item." +msgstr "" + +#: commoditymarket\market.lua:297 +msgid "You have to buy at least one item." +msgstr "" + +#: commoditymarket\market.lua:299 +msgid "You can't afford that many of this item." +msgstr "" + +#: commoditymarket\market.lua:385 +msgid "show market formspec" +msgstr "" + +#: commoditymarket\market.lua:397 +msgid "list all registered markets" +msgstr "" + +#: commoditymarket\market.lua:426 +msgid "remove item from market. All existing buys and sells will be canceled." +msgstr "" + +#: commoditymarket\market.lua:445 +msgid "" +"removes all unknown items from all markets. All existing buys and sells for " +"those items will be canceled." +msgstr "" + +#: commoditymarket\market.lua:457 +msgid "Purging item: @1 from market: @2" +msgstr "" + +#: commoditymarket\market.lua:471 +msgid "Add all registered items to the provided market" +msgstr "" + +#: commoditymarket\market.lua:531 +msgid "1 @1 = @2@3" +msgstr "" + +#: commoditymarket\market.lua:535 +msgid "Market inventory is limited to @1 items." +msgstr "" + +#: commoditymarket\market.lua:537 +msgid "Market has unlimited inventory space." +msgstr "" + +#: commoditymarket\market.lua:542 +msgid "Total pending sell orders are limited to @1 items." +msgstr "" + +#: commoditymarket\market.lua:544 +msgid "Market supports unlimited pending sell orders." +msgstr "" + +#: commoditymarket\market.lua:551 +msgid "Currency item values:" +msgstr "" + +#: commoditymarket\market.lua:566 +msgid "Market" +msgstr "" + +#: commoditymarket\market.lua:567 +msgid "A market where orders to buy or sell items can be placed and fulfilled." +msgstr "" diff --git a/mods/commoditymarket/locale/template.txt b/mods/commoditymarket/locale/template.txt new file mode 100644 index 0000000..d620dfe --- /dev/null +++ b/mods/commoditymarket/locale/template.txt @@ -0,0 +1,176 @@ +# textdomain: commoditymarket + + +### doc.lua ### + +#long-form description of how markets work, for documentation +At the core of how a market operates are "buy" and "sell" orders. A buy order is an announcement to the world that you are interested in purchasing a certain quantity of item and are willing to pay a certain amount of currency in exchange for each unit of that item. Conversely, a sell order is an announcement to the world that you are interested in selling a certain quantity of item and will accept a certain amount of currency in exchange for each unit of that item.@n@nThe market price of an item is determined by where the existing buy and sell orders for that item intersect. When you offer to buy an item for a price that someone is offering to sell it at, the item is transferred to you and currency is transferred from your account to theirs to cover the cost. The market will keep track of the most recent price that an item was successfully sold for, but note that this information is for historical interest only - there's no guarantee that anyone is currently willing to match the historical price.@n@nWhen an item is selected in the upper list, the currently existing buy and sell orders for that item will be displayed in the lower list. Sell orders are listed first in descending price, followed by buy orders in ascending price. The current market price will be somewhere in between the lowest sell order and the highest buy order. If you wish to cancel a buy or sell order that you've placed for an item, double-click on the order and the item or currency that you put into that order will be returned to your inventory.@n@nIf you place a buy order and there are already sell orders for the item that meet or are below your price, some or all of your buy order might be immediately fulfilled. Your purchases will be made at the price that the sell orders have been set to - if you were willing to pay 15 units of currency per item but someone was already offering to sell for 2 units of currency per item, you only pay 2 units for each of that offer's items. If there aren't enough compatible sell orders to fulfill your buy order, the remainder will be placed into the market and made available for future sellers to see and fulfill if they agree to your price. Your buy order will immediately deduct the currency required for it from your account's balance, but if you cancel your order you will get that currency back - it's not gone until the order is actually fulfilled.@n@nIf you place a sell order and there are already buy orders that meet or exceed your price, some or all of your sell order may be immediately fulfilled. You'll be paid the price that the buyers are offering rather than the amount you're demanding. If any of your sell offer is left unfulfilled, the sell order will be added to the market for future buyers to see. The items for this offer will be immediately taken from your market inventory but if you cancel your order you will get those items back.= + +#documentation tab text +Commodity Markets= + +#long-form description of how markets work, for documentation +Each player's account has an inventory that serves as a holding area for items that are destined to be sold or that have been bought by the player but not yet retrieved. This inventory is a bit different from the standard Minetest inventory in that it doesn't hold item "stacks", it just tracks the total number of that item present. Some markets allow for extremely large quantities of an item to be stored here for sale.@n@nTo add an item to your market inventory for eventual sale either shift-click on the item in your player inventory or drag the item stack to the inventory slot below the main market inventory list. Some markets may have restrictions on what items can be bought and sold, if an item is not valid for that market it won't go into the market's inventory. Some items are considered "currency" and will add to your account's currency balance instead of being listed in your market inventory.@n@nTools cannot be added to the market inventory if they have any wear on them. The market also can't handle items with attached metadata such as books that have had text added to them.@n@nTo remove an item from your market inventory, double-click in it in the market inventory list. As much of the item as can fit into your player inventory will be transferred to you, with any remainder staying behind in the market inventory. To withdraw currency from your market balance type the amount you'd like to withdraw in the field next to the "Withdraw" button. The currency will be converted into items and added to your player inventory, with whatever cannot be converted remaining behind in your market balance.= + +#documentation category description +Game-wide marketplaces where goods can be bought and sold at prices of your choice.= + +#title of documentation page +User Interface: Inventory= +#title of documentation page +User Interface: Orders= + +### formspecs.lua ### + +#tooltip +All the items you've transfered to the market to sell and the items you've@npurchased with buy orders. Double-click on an item to bring it back into your@npersonal inventory.= + +#tooltip +Apply search to outputs.= +Balance:= +#label +#button label +Buy= +#table column header +Buy Max= +#table column header +Buy Vol= +#tooltip +Clear search.= +Days Old= +#table column header +Description= +Description:= +#label for inventory drop target. The hard return is needed to fit it into the UI +Drop items here to@nadd to your account= +#tooltip +Enter substring to search item identifiers for.= + +#tooltip +Enter the amount of currency you'd like to withdraw then click the 'Withdraw'@nbutton to convert it into items and transfer it to your personal inventory.= + +How many days ago this order was placed.= +#label +In inventory:= +#table column header +Inventory= +#label +Inventory limit:= +#table column header +Item= +#table column header +Last Price= + +#tooltip +Log entries in yellow are new since last time you marked your log as read.= + +Mark logs as read= +#tab label +Market Orders= +#tooltip +Maximum price being offered to buy one of these.= +#tooltip +Minimum price being demanded to sell one of these.= +#checkbox label +My orders= +#shown if there are no transactions the player has participated in to list in the log +No logged activities in this market yet.= +#tooltip +Number of items available for sale in the market.= +#tooltip +Number of items there's demand for in the market.= + +#transaction log entry. @1 is a day number, @2 is a player name, @3 is a quantity of items, @4 is the item name, @5 is a player name, @6 is a currency symbol, @7 is a number (price), @8 is the currency symbol again and @9 is a number (price) +On day @1 @2 sold @3 @4 to @5 at @6@7 each for a total of @8@9.= + +Order= +Player= +Price= +#tooltip +Price paid for one of these the last time one was sold.= +Price per= +#table column header, field label +Quantity= + +#tooltip +Quantity of this item that you have in your inventory ready to sell.= + +Select an item to view or place orders.= + +#tooltip +Select this to show only the markets where you have either a buy or a sell order pending.= + +Sell= +#table column header +Sell Min= +#table column header +Sell Vol= +Sell limit:= +#checkbox label +Show Icons= +#checkbox label +Show Itemnames= + +The name of the player who placed this order.@nDouble-click your own orders to cancel them.= + +The price per item in this order.= + +The total amount of items available at this price accounting for the other orders also currently being offered.= + +The total amount of items in this particular order.= + +#tooltip +This market limits the total number of items a given seller can have for sale at a time.@nYou have @1 items remaining. Cancel old sell orders to free up space.= + +Total Volume= +#undefined item +Unknown Item= + +#tooltip +Use these fields to enter buy and sell orders for the selected item.= + +#button label +Withdraw= + +#tooltip +You can still receive purchased items if you've exceeded your inventory limit,@nbut you won't be able to transfer items from your personal inventory into@nthe market until you've emptied it back down below the limit again.= + +#tab label +Your Inventory= +Your Recent Purchases and Sales:= +someone= +you= +yourself= + +### market.lua ### + +1 @1 @= @2@3= + +A market where orders to buy or sell items can be placed and fulfilled.= + +Add all registered items to the provided market= +Currency item values:= +Market= +Market has unlimited inventory space.= +Market inventory is limited to @1 items.= +Market supports unlimited pending sell orders.= +Purging item: @1 from market: @2= +Total pending sell orders are limited to @1 items.= +You can't afford that many of this item.= +You can't pay less than nothing for an item.= +You can't sell fewer than one item.= +You can't sell items for a negative price.= + +You don't have enough of that item in your inventory to post this sell order.= + +You have to buy at least one item.= + +You have too many items listed for sale in this market, please cancel some sell orders to make room for new ones.= + +list all registered markets= + +remove item from market. All existing buys and sells will be canceled.= + +removes all unknown items from all markets. All existing buys and sells for those items will be canceled.= + +show market interface= diff --git a/mods/commoditymarket/locale/update.bat b/mods/commoditymarket/locale/update.bat new file mode 100644 index 0000000..e87d44c --- /dev/null +++ b/mods/commoditymarket/locale/update.bat @@ -0,0 +1,6 @@ +@echo off +setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION +cd .. +set LIST= +for /r %%X in (*.lua) do set LIST=!LIST! %%X +..\intllib\tools\xgettext.bat %LIST% \ No newline at end of file diff --git a/mods/commoditymarket/mapgen_dungeon_markets.lua b/mods/commoditymarket/mapgen_dungeon_markets.lua new file mode 100644 index 0000000..fb766f2 --- /dev/null +++ b/mods/commoditymarket/mapgen_dungeon_markets.lua @@ -0,0 +1,153 @@ +local goblin_enabled = minetest.settings:get_bool("commoditymarket_enable_goblin_market") +local under_enabled = minetest.settings:get_bool("commoditymarket_enable_under_market") +local goblin_prob = tonumber(minetest.settings:get("commoditymarket_goblin_market_dungeon_prob")) or 0.25 +local under_prob = tonumber(minetest.settings:get("commoditymarket_under_market_dungeon_prob")) or 0.1 + +local goblin_max = tonumber(minetest.settings:get("commoditymarket_goblin_market_dungeon_max")) or 100 +local goblin_min = tonumber(minetest.settings:get("commoditymarket_goblin_market_dungeon_min")) or -400 +local under_max = tonumber(minetest.settings:get("commoditymarket_under_market_dungeon_max")) or -500 +local under_min = tonumber(minetest.settings:get("commoditymarket_under_market_dungeon_min")) or -31000 + +local bad_goblin_range = goblin_min >= goblin_max +local bad_under_range = under_min >= under_max + +if bad_goblin_range then + minetest.log("error", "[commoditymarket] Goblin market dungeon generation range has a higher minimum y than maximum y") +end +if bad_under_range then + minetest.log("error", "[commoditymarket] Undermarket dungeon generation range has a higher minimum y than maximum y") +end + +local gen_goblin = goblin_enabled and goblin_prob > 0 and not bad_goblin_range +local gen_under = under_enabled and under_prob > 0 and not bad_under_range + +if not (gen_goblin or gen_under) then + return +end + + +------------------------------------------------------- +-- The following is shamelessly copied from dungeon_loot and tweaked for placing markets instead of chests +--Licensed under the MIT License (MIT) Copyright (C) 2017 sfan5 + +minetest.set_gen_notify({dungeon = true, temple = true}) + +local function noise3d_integer(noise, pos) + return math.abs(math.floor(noise:get_3d(pos) * 0x7fffffff)) +end + +local is_wall = function(node) + return node.name ~= "air" and node.name ~= "ignore" +end + +local function find_walls(cpos) + local dirs = {{x=1, z=0}, {x=-1, z=0}, {x=0, z=1}, {x=0, z=-1}} + local get_node = minetest.get_node + + local ret = {} + local mindist = {x=0, z=0} + local min = function(a, b) return a ~= 0 and math.min(a, b) or b end + for _, dir in ipairs(dirs) do + for i = 1, 9 do -- 9 = max room size / 2 + local pos = vector.add(cpos, {x=dir.x*i, y=0, z=dir.z*i}) + + -- continue in that direction until we find a wall-like node + local node = get_node(pos) + if is_wall(node) then + local front_below = vector.subtract(pos, {x=dir.x, y=1, z=dir.z}) + local above = vector.add(pos, {x=0, y=1, z=0}) + + -- check that it: + --- is at least 2 nodes high (not a staircase) + --- has a floor + if is_wall(get_node(front_below)) and is_wall(get_node(above)) then + pos = vector.subtract(pos, {x=dir.x, y=0, z=dir.z}) -- move goblin markets one node away from the wall + table.insert(ret, {pos = pos, facing = {x=-dir.x, y=0, z=-dir.z}}) + if dir.z == 0 then + mindist.x = min(mindist.x, i-1) + else + mindist.z = min(mindist.z, i-1) + end + end + -- abort even if it wasn't a wall cause something is in the way + break + end + end + end + + return { + walls = ret, + size = {x=mindist.x*2, z=mindist.z*2}, + cpos = cpos, + } +end + +minetest.register_on_generated(function(minp, maxp, blockseed) + local min_y = minp.y + local max_y = maxp.y + + local gen_goblin_range = gen_goblin and not (min_y > goblin_max or max_y < goblin_min) + local gen_under_range = gen_under and not (min_y > under_max or max_y < under_min) + + if not (gen_goblin_range or gen_under_range) then + -- out of both ranges + return + end + + local gennotify = minetest.get_mapgen_object("gennotify") + local poslist = gennotify["dungeon"] or {} + for _, entry in ipairs(gennotify["temple"] or {}) do + table.insert(poslist, entry) + end + if #poslist == 0 then return end + + local noise = minetest.get_perlin(151994, 4, 0.5, 1) + local rand = PcgRandom(noise3d_integer(noise, poslist[1])) + + local rooms = {} + -- process at most 8 rooms to keep runtime of this predictable + local num_process = math.min(#poslist, 8) + for i = 1, num_process do + local room = find_walls(poslist[i]) + -- skip small rooms and everything that doesn't at least have 3 walls + if math.min(room.size.x, room.size.z) >= 4 and #room.walls >= 3 then + table.insert(rooms, room) + end + end + if #rooms == 0 then return end + + if gen_under_range and rand:next(0, 2147483647)/2147483647 < under_prob then + -- choose a random room + local room = rooms[rand:next(1, #rooms)] + local under_loc = room.cpos + + -- put undermarkets in the center of the room + if minetest.get_node(under_loc).name == "air" + and is_wall(vector.subtract(under_loc, {x=0, y=1, z=0})) then + minetest.add_node(under_loc, {name="commoditymarket:under_market"}) + end + end + + if gen_goblin_range and rand:next(0, 2147483647)/2147483647 < goblin_prob then + -- choose a random room + local room = rooms[rand:next(1, #rooms)] + + -- choose place somewhere in front of any of the walls + local wall = room.walls[rand:next(1, #room.walls)] + local v, vi -- vector / axis that runs alongside the wall + if wall.facing.x ~= 0 then + v, vi = {x=0, y=0, z=1}, "z" + else + v, vi = {x=1, y=0, z=0}, "x" + end + local marketpos = vector.add(wall.pos, wall.facing) + local off = rand:next(-room.size[vi]/2 + 1, room.size[vi]/2 - 1) + marketpos = vector.add(marketpos, vector.multiply(v, off)) + + if minetest.get_node(marketpos).name == "air" then + -- make it face inwards to the room + local facedir = minetest.dir_to_facedir(vector.multiply(wall.facing, -1)) + minetest.add_node(marketpos, {name = "commoditymarket:goblin_market", param2 = facedir}) + end + end +end) \ No newline at end of file diff --git a/mods/commoditymarket/market.lua b/mods/commoditymarket/market.lua new file mode 100644 index 0000000..8dd3631 --- /dev/null +++ b/mods/commoditymarket/market.lua @@ -0,0 +1,718 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +commoditymarket.registered_markets = {} +local log_length_limit = 30 + +-- from http://lua-users.org/wiki/BinaryInsert +--[[ + table.bininsert( table, value [, comp] ) + + Inserts a given value through BinaryInsert into the table sorted by [, comp]. + + If 'comp' is given, then it must be a function that receives + two table elements, and returns true when the first is less + than the second, e.g. comp = function(a, b) return a > b end, + will give a sorted table, with the biggest value on position 1. + [, comp] behaves as in table.sort(table, value [, comp]) + returns the index where 'value' was inserted +]]-- +local comp_default = function(a, b) return a < b end +function table.bininsert(t, value, comp) + -- Initialise compare function + local comp = comp or comp_default + -- Initialise numbers + local iStart, iEnd, iMid, iState = 1, #t, 1, 0 + -- Get insert position + while iStart <= iEnd do + -- calculate middle + iMid = math.floor( (iStart+iEnd)/2 ) + -- compare + if comp(value, t[iMid]) then + iEnd, iState = iMid - 1, 0 + else + iStart, iState = iMid + 1, 1 + end + end + local target = iMid+iState + table.insert(t, target, value) + return target +end + +-- lowest price first +local buy_comp = function(order1, order2) + local price1 = order1.price + local price2 = order2.price + if price1 < price2 then + return true + elseif price1 == price2 and order1.timestamp < order2.timestamp then + return true + end + return false +end +-- highest price first +local sell_comp = function(order1, order2) + local price1 = order1.price + local price2 = order2.price + if price1 > price2 then + return true + elseif price1 == price2 and order1.timestamp < order2.timestamp then + return true + end + return false +end + +--------------------------------- + +local get_account = function(market, player_name) + local account = market.player_accounts[player_name] + if account then + return account + end + account = {} + account.search = "" + account.name = player_name + account.balance = 0 -- currency + account.inventory = {} -- items stored in the market inventory that aren't part of sell orders yet. stored as "[item] = count" + account.filter_participating = "false" + account.log = {} -- might want to use a more sophisticated queue, but this isn't going to be a big list so that's more trouble than it's worth right now. + market.player_accounts[player_name] = account + return account +end + +-- Caution: the data structures produced by sale logging caused me to discover +-- issue https://github.com/minetest/minetest/issues/8719 with minetest.serialize() +-- I'm working around it by using the code in persistence.lua instead +local log_sale = function(item, quantity, price, purchaser, seller) + local log_entry = {item=item, quantity=quantity, price=price, purchaser=purchaser, seller=seller, timestamp = minetest.get_gametime()} + local purchaser_log = purchaser.log + local seller_log = seller.log + table.insert(purchaser_log, log_entry) + if #purchaser_log > log_length_limit then + table.remove(purchaser_log, 1) + end + if (purchaser ~= seller) then + table.insert(seller_log, log_entry) + if #seller_log > log_length_limit then + table.remove(seller_log, 1) + end + end +end + +local remove_orders_by_account = function(orders, account) + if not orders then return end + local i = 1 + while i < #orders do + local order = orders[i] + if order.account == account then + table.remove(orders, i) + else + i = i + 1 + end + end +end + +local remove_account = function(player_name) + local account = player_accounts[player_name] + if account == nil then + return + end + + player_accounts[player_name] = nil + for item, lists in pairs(market) do + remove_orders_by_account(lists.buy_orders, account) + remove_orders_by_account(lists.sell_orders, account) + end +end + +------------------------------------------------------------------------------------------ + +local add_inventory_to_account = function(market, account, item, quantity) + if quantity < 1 then + return false + end + + if market.def.currency[item] then + account.balance = account.balance + market.def.currency[item] * quantity + else + account.inventory[item] = (account.inventory[item] or 0) + quantity + end + return true +end + +local remove_inventory_from_account = function(account, item, quantity) + if quantity < 1 then + return false + end + + local inventory = account.inventory + local current_quantity = inventory[item] or 0 + if current_quantity < quantity then + return false + end + + local new_quantity = current_quantity - quantity + if new_quantity == 0 then + inventory[item] = nil + else + inventory[item] = new_quantity + end + return true +end + +local remove_order = function(order, array) + for i, market_order in ipairs(array) do + if order == market_order then + table.remove(array, i) + return true + end + end + return false +end + +----------------------------------------------------------------------------------------------------------- + +local add_sell = function(market, account, item, price, quantity) + price = tonumber(price) + quantity = tonumber(quantity) + + local sell_limit = market.def.sell_limit + local sell_limit_exceeded + if sell_limit then + local total_sell = 0 + for item, orders in pairs(market.orders_for_items) do + for _, order in ipairs(orders.sell_orders) do + if order.account == account then + total_sell = total_sell + order.quantity + end + end + end + sell_limit_exceeded = total_sell + quantity > sell_limit + end + + -- validate that this sell order is possible + if sell_limit_exceeded or price < 0 or quantity < 1 or not remove_inventory_from_account(account, item, quantity) then + minetest.sound_play({name = "commoditymarket_error", gain = 0.1}, {to_player=account.name}) + if sell_limit_exceeded then + minetest.chat_send_player(account.name, S("You have too many items listed for sale in this market, please cancel some sell orders to make room for new ones.")) + elseif price < 0 then + minetest.chat_send_player(account.name, S("You can't sell items for a negative price.")) + elseif quantity < 1 then + minetest.chat_send_player(account.name, S("You can't sell fewer than one item.")) + else + minetest.chat_send_player(account.name, S("You don't have enough of that item in your inventory to post this sell order.")) + end + return false + end + + local buy_market = market.orders_for_items[item].buy_orders + local buy_order = buy_market[#buy_market] + local current_buy_volume = market.orders_for_items[item].buy_volume + + -- go through existing buy orders that are more expensive than or equal to the price + -- we're demanding, selling them at the order's price until we run out of + -- buy orders or run out of demand + while quantity > 0 and buy_order and buy_order.price >= price do + local quantity_to_sell = math.min(buy_order.quantity, quantity) + quantity = quantity - quantity_to_sell + local earned = quantity_to_sell*buy_order.price + account.balance = account.balance + earned + add_inventory_to_account(market, buy_order.account, item, quantity_to_sell) + buy_order.quantity = buy_order.quantity - quantity_to_sell + current_buy_volume = current_buy_volume - quantity_to_sell + + if buy_order.account ~= account then + -- don't update the last price if a player is just buying and selling from themselves + market.orders_for_items[item].last_price = buy_order.price + end + + log_sale(item, quantity_to_sell, buy_order.price, buy_order.account, account) + + if buy_order.quantity == 0 then + table.remove(buy_market, #buy_market) + end + buy_order = buy_market[#buy_market] + end + market.orders_for_items[item].buy_volume = current_buy_volume + + if quantity > 0 then + local sell_market = market.orders_for_items[item].sell_orders + + -- create the order and insert it into order arrays + local order = {account=account, price=price, quantity=quantity, timestamp=minetest.get_gametime()} + table.bininsert(sell_market, order, sell_comp) + market.orders_for_items[item].sell_volume = market.orders_for_items[item].sell_volume + quantity + end + + minetest.sound_play({name = "commoditymarket_register_opened", gain = 0.1}, {to_player=account.name}) + return true +end + +local cancel_sell = function(market, item, order) + local account = order.account + local quantity = order.quantity + + local sell_market = market.orders_for_items[item].sell_orders + + remove_order(order, sell_market) + market.orders_for_items[item].sell_volume = market.orders_for_items[item].sell_volume - quantity + add_inventory_to_account(market, account, item, quantity) + + minetest.sound_play({name = "commoditymarket_register_closed", gain = 0.1}, {to_player=account.name}) +end + +----------------------------------------------------------------------------------------------------------- + +local test_buy = function(market, balance, item, price, quantity) + local sell_market = market.orders_for_items[item].sell_orders + local test_quantity = quantity + local test_balance = balance + local i = 0 + local sell_order = sell_market[#sell_market] + while test_quantity > 0 and sell_order and sell_order.price <= price do + local quantity_to_buy = math.min(sell_order.quantity, test_quantity) + test_quantity = test_quantity - quantity_to_buy + test_balance = test_balance - quantity_to_buy*sell_order.price + i = i + 1 + sell_order = sell_market[#sell_market-i] + end + local spent = balance - test_balance + test_balance = test_balance - test_quantity*price + if test_balance < 0 then + return false, spent, test_quantity + end + + return true, spent, test_quantity +end + +local add_buy = function(market, account, item, price, quantity) + price = tonumber(price) + quantity = tonumber(quantity) + if price < 0 or quantity < 1 or not test_buy(market, account.balance, item, price, quantity) then + minetest.sound_play({name = "commoditymarket_error", gain = 0.1}, {to_player=account.name}) + if price < 0 then + minetest.chat_send_player(account.name, S("You can't pay less than nothing for an item.")) + elseif quantity < 1 then + minetest.chat_send_player(account.name, S("You have to buy at least one item.")) + else + minetest.chat_send_player(account.name, S("You can't afford that many of this item.")) + end + return false + end + + local sell_market = market.orders_for_items[item].sell_orders + local sell_order = sell_market[#sell_market] + local current_sell_volume = market.orders_for_items[item].sell_volume + + -- go through existing sell orders that are cheaper than or equal to the price + -- we're wanting to offer, buying them up at the offered price until we run out of + -- sell orders or run out of supply + while quantity > 0 and sell_order and sell_order.price <= price do + local quantity_to_buy = math.min(sell_order.quantity, quantity) + quantity = quantity - quantity_to_buy + local spent = quantity_to_buy*sell_order.price + account.balance = account.balance - spent + sell_order.account.balance = sell_order.account.balance + spent + sell_order.quantity = sell_order.quantity - quantity_to_buy + current_sell_volume = current_sell_volume - quantity_to_buy + add_inventory_to_account(market, account, item, quantity_to_buy) + + if sell_order.account ~= account then + -- don't update the last price if a player is just buying and selling from themselves + market.orders_for_items[item].last_price = sell_order.price + end + + log_sale(item, quantity_to_buy, sell_order.price, account, sell_order.account) + + -- Sell order completely used up, remove it + if sell_order.quantity == 0 then + table.remove(sell_market, #sell_market) + end + + -- get the next sell order + sell_order = sell_market[#sell_market] + end + market.orders_for_items[item].sell_volume = current_sell_volume + + if quantity > 0 then + local buy_market = market.orders_for_items[item].buy_orders + -- create the order for the remainder and insert it into order arrays + local order = {account=account, price=price, quantity=quantity, timestamp=minetest.get_gametime()} + account.balance = account.balance - quantity*price -- buy orders are pre-paid + table.bininsert(buy_market, order, buy_comp) + market.orders_for_items[item].buy_volume = market.orders_for_items[item].buy_volume + quantity + end + + minetest.sound_play({name = "commoditymarket_register_opened", gain = 0.1}, {to_player=account.name}) + return true +end + +local cancel_buy = function(market, item, order) + local account = order.account + local quantity = order.quantity + local price = order.price + + local buy_market = market.orders_for_items[item].buy_orders + market.orders_for_items[item].buy_volume = market.orders_for_items[item].buy_volume - quantity + + remove_order(order, buy_market) + + account.balance = account.balance + price*quantity + + minetest.sound_play({name = "commoditymarket_register_closed", gain = 0.1}, {to_player=account.name}) +end + +local initialize_market_item = function(orders_for_items, item) + if orders_for_items[item] == nil then + local lists = {} + lists.buy_orders = {} + lists.sell_orders = {} + lists.buy_volume = 0 + lists.sell_volume = 0 + lists.item = item + -- leave last_price nil to indicate it's never been sold before + orders_for_items[item] = lists + end +end + +----------------------------------------------------------------------------------------------------------- +-- Chat commands + +minetest.register_chatcommand("market.show", { + params = "marketname", + privs = {server=true}, + description = S("show market interface"), + func = function(name, param) + local market = commoditymarket.registered_markets[param] + if market == nil then return end + local formspec = market:get_formspec(market:get_account(name)) + minetest.show_formspec(name, "commoditymarket:"..param..":"..name, formspec) + end, +}) + +minetest.register_chatcommand("market.list", { + params = "", + privs = {server=true}, + description = S("list all registered markets"), + func = function(name, param) + local list = {} + for marketname, def in pairs(commoditymarket.registered_markets) do + table.insert(list, marketname) + end + table.sort(list) + minetest.chat_send_player(name, "Registered markets: " .. table.concat(list, ", ")) + end, +}) + +local remove_market_item = function(market, item) + local marketitem = market.orders_for_items[item] + if marketitem then + local buy_orders = marketitem.buy_orders + while #buy_orders > 0 do + market:cancel_buy(item, buy_orders[#buy_orders]) + end + local sell_orders = marketitem.sell_orders + while #sell_orders > 0 do + market:cancel_sell(item, sell_orders[#sell_orders]) + end + market.orders_for_items[item] = nil + end +end + +minetest.register_chatcommand("market.removeitem", { + params = "marketname item", + privs = {server=true}, + description = S("remove item from market. All existing buys and sells will be canceled."), + func = function(name, param) + local params = param:split(" ") + if #params ~= 2 then + minetest.chat_send_player(name, "Incorrect parameter count") + return + end + local market = commoditymarket.registered_markets[params[1]] + if market == nil then + minetest.chat_send_player(name, "No such market: " .. params[1]) + return + end + remove_market_item(market, params[2]) + end, +}) + +minetest.register_chatcommand("market.purge_unknowns", { + params = "", + privs = {server=true}, + description = S("removes all unknown items from all markets. All existing buys and sells for those items will be canceled."), + func = function(name, param) + for market_name, market in pairs(commoditymarket.registered_markets) do + local items_to_remove = {} + local items_to_move = {} + for item, orders in pairs(market.orders_for_items) do + local icon = commoditymarket.get_icon(item) + if icon == "unknown_item.png" then + table.insert(items_to_remove, item) + end + end + for _, item in ipairs(items_to_remove) do + minetest.chat_send_player(name, S("Purging item: @1 from market: @2", tostring(item), market_name)) + minetest.log("warning", "[commoditymarket] Purging unknown item: " .. tostring(item) .. " from market: " .. market_name) + remove_market_item(market, item) + end + end + end, +}) + +-- Used during development and debugging to find items that break the market formspecs when added +local debugging_commands = false +if debugging_commands then + minetest.register_chatcommand("market.addeverything", { + params = "marketname", + privs = {server=true}, + description = S("Add all registered items to the provided market"), + func = function(name, param) + local params = param:split(" ") + if #params ~= 1 then + minetest.chat_send_player(name, "Incorrect parameter count") + return + end + local market = commoditymarket.registered_markets[params[1]] + if market == nil then + minetest.chat_send_player(name, "No such market: " .. params[1]) + return + end + for item_name, def in pairs(minetest.registered_items) do + initialize_market_item(market.orders_for_items, item_name) + end + end, + }) +end + +----------------------------------------------------------------------------------------------------------- + +-- API exposed to the outside world +local add_inventory = function(self, player_name, item, quantity) + return add_inventory_to_account(self, get_account(self, player_name), item, quantity) +end +local remove_inventory = function(self, player_name, item, quantity) + return remove_inventory_from_account(get_account(self, player_name), item, quantity) +end +local sell = function(self, player_name, item, quantity, price) + return add_sell(self, get_account(self, player_name), item, price, quantity) +end +local buy = function(self, player_name, item, quantity, price) + return add_buy(self, get_account(self, player_name), item, price, quantity) +end + +-- Using this instead of minetest.serialize because of https://github.com/minetest/minetest/issues/8719 +local MP = minetest.get_modpath(minetest.get_current_modname()) +local persistence_store, persistence_load = dofile(MP.."/persistence.lua") + +local worldpath = minetest.get_worldpath() +local load_market_data = function(marketname) + local filename = worldpath .. "/market_"..marketname..".lua" + return persistence_load(filename) +end + +local save_market_data = function(market) + local filename = worldpath .. "/market_"..market.name..".lua" + local data = {} + data.player_accounts = market.player_accounts + data.orders_for_items = market.orders_for_items + persistence_store(filename, data) + return true +end + +local make_doc_entry = function() return end +if minetest.get_modpath("doc") then + make_doc_entry = function(market_name, market_def) + local currencies = {} + for _, currency_item in ipairs(market_def.currency_ordered) do + local item_def = minetest.registered_items[currency_item.item] + table.insert(currencies, S("1 @1 = @2@3", item_def.description, market_def.currency_symbol, currency_item.amount)) + end + local inventory_limit + if market_def.inventory_limit then + inventory_limit = S("Market inventory is limited to @1 items.", market_def.inventory_limit) + else + inventory_limit = S("Market has unlimited inventory space.") + end + + local sell_limit + if market_def.sell_limit then + sell_limit = S("Total pending sell orders are limited to @1 items.", market_def.inventory_limit) + else + sell_limit = S("Market supports unlimited pending sell orders.") + end + + doc.add_entry("commoditymarket", "market_"..market_name, { + name = market_def.description, + data = { text = market_def.long_description + .."\n\n" + ..S("Currency item values:") .. "\n " .. table.concat(currencies, "\n ") + .."\n\n" + ..inventory_limit + .."\n" + ..sell_limit + } + }) + end +end + +commoditymarket.register_market = function(market_name, market_def) + assert(not commoditymarket.registered_markets[market_name]) + assert(market_def.currency) + + market_def.currency_symbol = market_def.currency_symbol or "¤" -- \u{00A4} -- defaults to the generic currency symbol ("scarab") + market_def.description = market_def.description or S("Market") + market_def.long_description = market_def.long_description or S("A market where orders to buy or sell items can be placed and fulfilled.") + + -- Reprocess currency table into a form easier for the withdraw code to work with + market_def.currency_ordered = {} + for item, amount in pairs(market_def.currency) do + table.insert(market_def.currency_ordered, {item=item, amount=amount}) + end + table.sort(market_def.currency_ordered, function(currency1, currency2) return currency1.amount > currency2.amount end) + + make_doc_entry(market_name, market_def) -- market_def has now been normalized, make documentation for it if doc is installed. + + -- Just in case a developer supplied strings that don't work well in formspecs, escape them now so we don't have to do it + -- wherever they're used. + market_def.currency_symbol = minetest.formspec_escape(market_def.currency_symbol) + market_def.description = minetest.formspec_escape(market_def.description) + market_def.long_description = minetest.formspec_escape(market_def.long_description) + + local new_market = {} + new_market.def = market_def + commoditymarket.registered_markets[market_name] = new_market + + local loaded_data = load_market_data(market_name) + if loaded_data then + new_market.player_accounts = loaded_data.player_accounts + new_market.orders_for_items = loaded_data.orders_for_items + else + new_market.player_accounts = {} + new_market.orders_for_items = {} + end + + -- If there's a list of initial items in the market def, initialize them. allow_item can trump this. + local initial_items = market_def.initial_items + if initial_items then + -- defer until after to ensure that all initial items have been registered, so we can guard against invalid items + minetest.after(0, + function() + for _, item in ipairs(initial_items) do + if minetest.registered_items[item] and + ((not market_def.allow_item) or market_def.allow_item(item)) and + not market_def.currency[item] then + initialize_market_item(new_market.orders_for_items, item) + end + end + end) + end + market_def.initial_items = nil -- don't need this any more + + new_market.name = market_name + + new_market.add_inventory = add_inventory + new_market.remove_inventory = remove_inventory + new_market.sell = sell + new_market.buy = buy + new_market.cancel_sell = cancel_sell + new_market.cancel_buy = cancel_buy + new_market.get_formspec = commoditymarket.get_formspec + new_market.get_account = get_account + new_market.save = save_market_data + + -- save markets on shutdown + minetest.register_on_shutdown(function() new_market:save() end) + + -- and also every ten minutes, to be on the safe side in case Minetest crashes + -- TODO: a more sophisticated approach that checks whether the market data is "dirty" before actually saving + local until_next_save = 600 + minetest.register_globalstep(function(dtime) + until_next_save = until_next_save - dtime + if until_next_save < 0 then + new_market:save() + until_next_save = 600 + end + end) + + ---------------------------------------------------------------------- + -- Detached inventory for adding items into the market + + local inv = minetest.create_detached_inventory("commoditymarket:"..market_name, { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + allow_put = function(inv, listname, index, stack, player) + local item = stack:get_name() + + -- reject unknown items + if minetest.registered_items[item] == nil then + return 0 + end + + -- Currency items are always allowed + if new_market.def.currency[item] then + return stack:get_count() + end + + -- only new tools, no used tools + if stack:get_wear() ~= 0 then + return 0 + end + + --nothing with metadata permitted + local meta = stack:get_meta():to_table() + local fields = meta.fields + local inventory = meta.inventory + if (fields and next(fields)) or (inventory and next(inventory)) then + return 0 + end + + -- If there's no allow_item function defined, allow everything. Otherwise check if the item is allowed + if (not market_def.allow_item) or market_def.allow_item(item) then + local allowed_count = stack:get_count() + + if market_def.inventory_limit then + -- limit additions to the inventory_limit, if there is one + local current_count = 0 + for _, inventory_quantity in pairs(new_market:get_account(player:get_player_name()).inventory) do + current_count = current_count + inventory_quantity + end + allowed_count = math.min(allowed_count, allowed_count + market_def.inventory_limit - (current_count+allowed_count)) + if allowed_count <= 0 then return 0 end + end + + --ensures the item is in the market listing if it wasn't before + initialize_market_item(new_market.orders_for_items, item) + return allowed_count + end + return 0 + end, + allow_take = function(inv, listname, index, stack, player) + return 0 + end, + on_move = function(inv, from_list, from_index, to_list, to_index, count, player) + end, + on_take = function(inv, listname, index, stack, player) + end, + on_put = function(inv, listname, index, stack, player) + if listname == "add" then + local item = stack:get_name() + local count = stack:get_count() + new_market:add_inventory(player:get_player_name(), item, count) + inv:set_list("add", {}) + local name = player:get_player_name() + local formspec = new_market:get_formspec(new_market:get_account(name)) + minetest.show_formspec(name, "commoditymarket:"..market_name..":"..name, formspec) + end + end + }) + inv:set_size("add", 1) +end + +commoditymarket.show_market = function(market_name, player_name) + local market = commoditymarket.registered_markets[market_name] + if market == nil then return end + local formspec = market:get_formspec(market:get_account(player_name)) + minetest.show_formspec(player_name, "commoditymarket:"..market_name..":"..player_name, formspec) +end \ No newline at end of file diff --git a/mods/commoditymarket/mod.conf b/mods/commoditymarket/mod.conf new file mode 100644 index 0000000..2a79af8 --- /dev/null +++ b/mods/commoditymarket/mod.conf @@ -0,0 +1,3 @@ +name = commoditymarket +description = Provides API support for various in-world commodity markets +optional_depends = doc \ No newline at end of file diff --git a/mods/commoditymarket/models/commoditymarket_wagon.obj b/mods/commoditymarket/models/commoditymarket_wagon.obj new file mode 100644 index 0000000..333924f --- /dev/null +++ b/mods/commoditymarket/models/commoditymarket_wagon.obj @@ -0,0 +1,852 @@ +# Blender v2.79 (sub 0) OBJ File: 'wagon.blend' +# www.blender.org +g Cube.004_Cube.012 +v 0.234629 1.147573 -1.166732 +v -0.234629 1.147573 -1.166732 +v 0.234629 0.678315 -1.166732 +v -0.234629 0.678315 -1.166732 +v 0.731823 1.147573 -0.234629 +v 0.731823 1.147573 0.234629 +v 0.731823 0.678315 -0.234629 +v 0.731823 0.678315 0.234629 +v -0.731823 1.147573 0.234629 +v -0.731823 1.147573 -0.234629 +v -0.731823 0.678315 0.234629 +v -0.731823 0.678315 -0.234629 +v -0.259667 0.016670 1.168107 +v 0.259668 0.016670 1.168107 +v -0.259667 1.170112 1.168107 +v 0.259668 1.170112 1.168107 +vt 0.000000 0.533333 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.533333 +vt -0.000000 0.533333 +vt 1.000000 0.533333 +vt 1.000000 1.000000 +vt -0.000000 1.000000 +vt 0.000000 0.533333 +vt 1.000000 0.533333 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +s off +f 4/1/1 2/2/1 1/3/1 3/4/1 +f 8/5/2 7/6/2 5/7/2 6/8/2 +f 12/9/3 11/10/3 9/11/3 10/12/3 +f 13/13/4 14/14/4 16/15/4 15/16/4 +g Cube.003_Cube.011 +v -0.720902 -0.096672 1.153442 +v -0.720901 -0.096672 -1.153443 +v -0.720902 1.200951 1.153442 +v -0.720902 1.200951 -1.153443 +v -0.509754 1.608755 -1.153443 +v -0.509754 1.608755 1.153443 +v -0.792992 1.200951 -1.268787 +v -0.792992 1.200951 1.268787 +v -0.560730 1.649535 -1.268787 +v -0.560730 1.649535 1.268787 +v -0.726391 1.178882 -1.268787 +v -0.726391 1.178882 1.268787 +v -0.509756 1.608756 -1.268787 +v -0.509756 1.608756 1.268787 +v -0.692620 0.037741 -1.018928 +v -0.692620 0.163735 -1.089024 +v -0.692620 -0.523026 -2.026881 +v -0.692620 -0.397032 -2.096977 +v -0.512394 0.037741 -1.018928 +v -0.512394 0.163735 -1.089024 +v -0.512394 -0.523026 -2.026881 +v -0.512394 -0.397032 -2.096977 +v -0.324406 0.582331 -1.134006 +v -0.324406 0.654421 -1.134006 +v -0.324406 0.582331 -1.441803 +v -0.324406 0.654421 -1.441803 +v 0.720901 -0.096672 -1.153443 +v 0.720902 -0.096672 1.153442 +v -0.000000 1.200951 1.153443 +v 0.720902 1.200951 1.153442 +v -0.000000 1.200951 -1.153443 +v -0.000000 1.777673 -1.153443 +v -0.000000 1.777673 1.153443 +v 0.720902 1.200951 -1.153443 +v 0.509754 1.608755 -1.153443 +v 0.509754 1.608755 1.153443 +v -0.000000 1.835345 1.268787 +v -0.000000 1.835345 -1.268787 +v 0.792992 1.200951 -1.268787 +v 0.792992 1.200951 1.268787 +v 0.560730 1.649535 -1.268787 +v 0.560730 1.649535 1.268787 +v -0.000000 1.777673 1.268787 +v -0.000000 1.777673 -1.268787 +v 0.726391 1.178882 -1.268787 +v 0.726391 1.178882 1.268787 +v 0.509756 1.608756 -1.268787 +v 0.509756 1.608756 1.268787 +v 0.692620 0.037741 -1.018928 +v 0.692620 0.163735 -1.089024 +v 0.692620 -0.523026 -2.026881 +v 0.692620 -0.397032 -2.096977 +v 0.512394 0.037741 -1.018928 +v 0.512394 0.163735 -1.089024 +v 0.512394 -0.523026 -2.026881 +v 0.512394 -0.397032 -2.096977 +v 0.324406 0.582331 -1.134006 +v 0.324406 0.654421 -1.134006 +v 0.324406 0.582331 -1.441803 +v 0.324406 0.654421 -1.441803 +vt -1.425823 3.001615 +vt -1.425823 2.882734 +vt -0.355896 2.882734 +vt -0.355896 3.001615 +vt 0.375155 -3.373241 +vt 0.375155 -2.579424 +vt -3.809447 -2.579426 +vt -3.809447 -3.373241 +vt 0.375154 -1.693858 +vt -3.809447 -1.693859 +vt 0.381165 -0.154615 +vt 4.565710 -0.154608 +vt 4.565710 -0.038908 +vt 0.381165 -0.038908 +vt -0.235621 2.375158 +vt -0.235621 3.208172 +vt -0.341187 3.187105 +vt -0.349886 2.393338 +vt 2.764791 -0.422899 +vt 2.764791 -1.255914 +vt 2.879056 -1.237734 +vt 2.870357 -0.443966 +vt -1.425823 3.804063 +vt -0.451704 3.804062 +vt -0.481619 3.894339 +vt -1.367183 3.894337 +vt -0.451699 3.798052 +vt -1.425823 3.798051 +vt -1.367184 3.707779 +vt -0.481614 3.707775 +vt 2.764791 -2.832267 +vt 2.764791 -3.070028 +vt 4.666879 -3.070028 +vt 4.666879 -2.832265 +vt 2.885066 -1.553966 +vt 2.885066 -1.791727 +vt 3.182267 -1.791727 +vt 3.182267 -1.553966 +vt 4.666881 -2.826254 +vt 4.666881 -2.588493 +vt 2.764791 -2.588493 +vt 2.764791 -2.826255 +vt 3.182267 -1.547955 +vt 3.182267 -1.310194 +vt 2.885066 -1.310194 +vt 2.885066 -1.547955 +vt 1.902838 4.586475 +vt 1.902838 4.883677 +vt 0.000747 4.883678 +vt 0.000747 4.586475 +vt 1.902835 4.283262 +vt 1.902835 4.580463 +vt 0.000747 4.580466 +vt 0.000747 4.283262 +vt 2.764791 -0.298008 +vt 2.764791 -0.416888 +vt 3.272367 -0.416888 +vt 3.272367 -0.298008 +vt -1.425823 2.375158 +vt -0.355896 2.375158 +vt -0.355896 3.509191 +vt -1.425823 3.509191 +vt -3.809448 2.369149 +vt -3.809448 -0.008467 +vt -0.005263 -0.008466 +vt -0.005264 2.369148 +vt 0.375154 -0.014477 +vt -3.809448 -0.014477 +vt -3.809448 -0.808292 +vt 0.375154 -0.808291 +vt 0.381165 -0.160630 +vt 0.381165 -0.276331 +vt 4.565711 -0.276331 +vt 4.565711 -0.160625 +vt 2.764791 -2.094939 +vt 2.879056 -2.076759 +vt 2.870358 -1.282992 +vt 2.764791 -1.261924 +vt -0.115346 3.208172 +vt -0.220912 3.187105 +vt -0.229611 2.393338 +vt -0.115346 2.375158 +vt -0.451703 3.515201 +vt -0.510342 3.605475 +vt -1.395907 3.605478 +vt -1.425823 3.515201 +vt -1.425823 3.701766 +vt -1.395907 3.611488 +vt -0.510338 3.611492 +vt -0.451699 3.701765 +vt 2.764791 -2.338711 +vt 4.666883 -2.338711 +vt 4.666883 -2.100949 +vt 2.764791 -2.100949 +vt 3.122827 -2.094939 +vt 3.122827 -1.797738 +vt 2.885066 -1.797738 +vt 2.885066 -2.094939 +vt 4.666883 -2.344721 +vt 2.764791 -2.344721 +vt 2.764791 -2.582482 +vt 4.666883 -2.582483 +vt -0.349886 3.214182 +vt -0.052684 3.214182 +vt -0.052684 3.451943 +vt -0.349886 3.451943 +vt 4.666882 -3.076038 +vt 2.764791 -3.076038 +vt 2.764791 -3.373240 +vt 4.666883 -3.373241 +vt 3.810932 4.580466 +vt 1.908845 4.580463 +vt 1.908845 4.283263 +vt 3.810934 4.283262 +vt 2.885066 -1.304184 +vt 3.392642 -1.304184 +vt 3.392642 -1.185303 +vt 2.885066 -1.185303 +vt 0.061193 0.029274 +vt 2.438806 0.029274 +vt 2.438807 2.169126 +vt 1.250000 2.169127 +vt 0.061193 2.169127 +vt 2.438741 0.029448 +vt 2.438741 2.169301 +vt 6.242925 2.169302 +vt 6.242926 0.029448 +vt 2.090614 2.841618 +vt 1.250000 2.169127 +vt 0.409386 2.841618 +vt 0.061192 2.169127 +vt 1.250000 3.120173 +vt 1.250000 3.120173 +vt 2.438532 0.029230 +vt 6.242717 0.029228 +vt 6.242717 2.169081 +vt 2.438534 2.169083 +vt 0.409386 2.841618 +vt 2.438807 2.169127 +vt 2.090614 2.841617 +vt 0.061193 0.029273 +vt 2.438807 0.029273 +vn 0.0000 0.0000 -1.0000 +vn 0.8930 -0.4500 -0.0000 +vn 0.3145 -0.9492 0.0000 +vn -0.3145 -0.9492 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -0.4862 -0.8739 +vn 1.0000 -0.0000 0.0000 +vn 0.0000 0.4862 0.8739 +vn 0.0000 -0.8739 0.4862 +vn 0.0000 0.8739 -0.4862 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn -0.8930 -0.4500 -0.0000 +s off +f 41/17/5 42/18/5 76/19/5 75/20/5 +f 27/21/6 29/22/6 30/23/6 28/24/6 +f 29/22/7 60/25/7 59/26/7 30/23/7 +f 24/27/8 23/28/8 27/29/8 28/30/8 +f 23/31/5 25/32/5 29/33/5 27/34/5 +f 26/35/9 24/36/9 28/37/9 30/38/9 +f 25/39/5 54/40/5 60/41/5 29/42/5 +f 53/43/9 26/44/9 30/45/9 59/46/9 +f 31/47/10 32/48/10 34/49/10 33/50/10 +f 33/51/11 34/52/11 38/53/11 37/54/11 +f 37/55/12 38/56/12 36/57/12 35/58/12 +f 35/59/13 36/60/13 32/61/13 31/62/13 +f 33/63/14 37/64/14 35/65/14 31/66/14 +f 38/67/15 34/68/15 32/69/15 36/70/15 +f 39/71/10 40/72/10 42/73/10 41/74/10 +f 76/19/16 42/18/16 40/75/16 74/76/16 +f 41/17/17 75/20/17 73/77/17 39/78/17 +f 44/79/17 17/80/17 18/81/17 43/82/17 +f 61/83/18 62/84/18 64/85/18 63/86/18 +f 63/86/8 64/85/8 59/26/8 60/25/8 +f 56/87/7 62/88/7 61/89/7 55/90/7 +f 55/91/5 61/92/5 63/93/5 57/94/5 +f 58/95/9 64/96/9 62/97/9 56/98/9 +f 57/99/5 63/100/5 60/101/5 54/102/5 +f 53/103/9 59/104/9 64/105/9 58/106/9 +f 65/107/12 67/108/12 68/109/12 66/110/12 +f 67/111/11 71/112/11 72/113/11 68/114/11 +f 71/115/10 69/116/10 70/117/10 72/118/10 +f 69/119/13 65/120/13 66/121/13 70/122/13 +f 67/123/14 65/124/14 69/125/14 71/126/14 +f 72/127/15 70/128/15 66/129/15 68/130/15 +f 73/131/12 75/132/12 76/133/12 74/134/12 +f 43/135/5 18/136/5 20/137/5 47/138/5 50/139/5 +f 17/140/10 19/141/10 20/142/10 18/143/10 +f 47/138/5 20/137/5 21/144/5 +f 45/145/9 22/146/9 19/147/9 +f 47/138/5 21/144/5 48/148/5 +f 45/145/9 49/149/9 22/146/9 +f 44/150/12 43/151/12 50/152/12 46/153/12 +f 47/138/5 51/154/5 50/139/5 +f 45/145/9 46/155/9 52/156/9 +f 47/138/5 48/148/5 51/154/5 +f 45/145/9 52/156/9 49/149/9 +f 45/145/9 19/147/9 17/157/9 44/158/9 46/155/9 +g Cube.002_Cube.010 +v -0.901127 0.047509 -0.576721 +v -0.720902 0.047509 -0.576721 +v -0.901127 0.268210 -1.109542 +v -0.720902 0.268210 -1.109542 +v -0.901127 -0.173193 -1.109542 +v -0.720902 -0.173193 -1.109542 +v -0.901127 -0.485312 -0.797423 +v -0.720902 -0.485312 -0.797423 +v -0.901127 -0.485312 -0.356020 +v -0.720902 -0.485312 -0.356020 +v -0.901127 -0.173193 -0.043900 +v -0.720902 -0.173193 -0.043900 +v -0.901127 0.268210 -0.043900 +v -0.720902 0.268210 -0.043900 +v -0.901127 0.580330 -0.356020 +v -0.720902 0.580330 -0.356020 +v -0.901127 0.580330 -0.797423 +v -0.720902 0.580330 -0.797423 +v -0.901127 0.047509 0.576721 +v -0.720902 0.047509 0.576721 +v -0.901127 0.268210 0.043900 +v -0.720902 0.268210 0.043900 +v -0.901127 -0.173193 0.043900 +v -0.720902 -0.173193 0.043900 +v -0.901127 -0.485312 0.356020 +v -0.720902 -0.485312 0.356020 +v -0.901127 -0.485312 0.797423 +v -0.720902 -0.485312 0.797423 +v -0.901127 -0.173193 1.109542 +v -0.720902 -0.173193 1.109542 +v -0.901127 0.268210 1.109542 +v -0.720902 0.268210 1.109542 +v -0.901127 0.580330 0.797423 +v -0.720902 0.580330 0.797423 +v -0.901127 0.580330 0.356020 +v -0.720902 0.580330 0.356020 +v 0.901127 0.047509 -0.576721 +v 0.720902 0.047509 -0.576721 +v 0.901127 0.268210 -1.109542 +v 0.720902 0.268210 -1.109542 +v 0.901127 -0.173193 -1.109542 +v 0.720902 -0.173193 -1.109542 +v 0.901127 -0.485312 -0.797423 +v 0.720902 -0.485312 -0.797423 +v 0.901127 -0.485312 -0.356020 +v 0.720902 -0.485312 -0.356020 +v 0.901127 -0.173193 -0.043900 +v 0.720902 -0.173193 -0.043900 +v 0.901127 0.268210 -0.043900 +v 0.720902 0.268210 -0.043900 +v 0.901127 0.580330 -0.356020 +v 0.720902 0.580330 -0.356020 +v 0.901127 0.580330 -0.797423 +v 0.720902 0.580330 -0.797423 +v 0.901127 0.047509 0.576721 +v 0.720902 0.047509 0.576721 +v 0.901127 0.268210 0.043900 +v 0.720902 0.268210 0.043900 +v 0.901127 -0.173193 0.043900 +v 0.720902 -0.173193 0.043900 +v 0.901127 -0.485312 0.356020 +v 0.720902 -0.485312 0.356020 +v 0.901127 -0.485312 0.797423 +v 0.720902 -0.485312 0.797423 +v 0.901127 -0.173193 1.109542 +v 0.720902 -0.173193 1.109542 +v 0.901127 0.268210 1.109542 +v 0.720902 0.268210 1.109542 +v 0.901127 0.580330 0.797423 +v 0.720902 0.580330 0.797423 +v 0.901127 0.580330 0.356020 +v 0.720902 0.580330 0.356020 +vt 0.499873 0.992213 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.499873 0.992213 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.499873 0.992213 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.499873 0.992213 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.499873 0.992213 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.499873 0.992213 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.499873 0.992213 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.499873 0.992213 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 0.0000 +s off +f 77/159/19 79/160/19 81/161/19 +f 78/162/20 82/163/20 80/164/20 +f 77/159/19 81/165/19 83/166/19 +f 78/162/20 84/167/20 82/168/20 +f 77/159/19 83/169/19 85/170/19 +f 78/162/20 86/171/20 84/172/20 +f 77/159/19 85/173/19 87/174/19 +f 78/162/20 88/175/20 86/176/20 +f 77/159/19 87/177/19 89/178/19 +f 78/162/20 90/179/20 88/180/20 +f 77/159/19 89/181/19 91/182/19 +f 78/162/20 92/183/20 90/184/20 +f 77/159/19 91/185/19 93/186/19 +f 78/162/20 94/187/20 92/188/20 +f 77/159/19 93/189/19 79/190/19 +f 78/162/20 80/191/20 94/192/20 +f 95/193/19 97/194/19 99/195/19 +f 96/196/20 100/197/20 98/198/20 +f 95/193/19 99/199/19 101/200/19 +f 96/196/20 102/201/20 100/202/20 +f 95/193/19 101/203/19 103/204/19 +f 96/196/20 104/205/20 102/206/20 +f 95/193/19 103/207/19 105/208/19 +f 96/196/20 106/209/20 104/210/20 +f 95/193/19 105/211/19 107/212/19 +f 96/196/20 108/213/20 106/214/20 +f 95/193/19 107/215/19 109/216/19 +f 96/196/20 110/217/20 108/218/20 +f 95/193/19 109/219/19 111/220/19 +f 96/196/20 112/221/20 110/222/20 +f 95/193/19 111/223/19 97/224/19 +f 96/196/20 98/225/20 112/226/20 +f 113/227/20 117/228/20 115/229/20 +f 114/230/19 116/231/19 118/232/19 +f 113/227/20 119/233/20 117/234/20 +f 114/230/19 118/235/19 120/236/19 +f 113/227/20 121/237/20 119/238/20 +f 114/230/19 120/239/19 122/240/19 +f 113/227/20 123/241/20 121/242/20 +f 114/230/19 122/243/19 124/244/19 +f 113/227/20 125/245/20 123/246/20 +f 114/230/19 124/247/19 126/248/19 +f 113/227/20 127/249/20 125/250/20 +f 114/230/19 126/251/19 128/252/19 +f 113/227/20 129/253/20 127/254/20 +f 114/230/19 128/255/19 130/256/19 +f 113/227/20 115/257/20 129/258/20 +f 114/230/19 130/259/19 116/260/19 +f 131/261/20 135/262/20 133/263/20 +f 132/264/19 134/265/19 136/266/19 +f 131/261/20 137/267/20 135/268/20 +f 132/264/19 136/269/19 138/270/19 +f 131/261/20 139/271/20 137/272/20 +f 132/264/19 138/273/19 140/274/19 +f 131/261/20 141/275/20 139/276/20 +f 132/264/19 140/277/19 142/278/19 +f 131/261/20 143/279/20 141/280/20 +f 132/264/19 142/281/19 144/282/19 +f 131/261/20 145/283/20 143/284/20 +f 132/264/19 144/285/19 146/286/19 +f 131/261/20 147/287/20 145/288/20 +f 132/264/19 146/289/19 148/290/19 +f 131/261/20 133/291/20 147/292/20 +f 132/264/19 148/293/19 134/294/19 +g Cube.001_Cube.009 +v -0.901127 0.268210 -1.109542 +v -0.720902 0.268210 -1.109542 +v -0.901127 -0.173193 -1.109542 +v -0.720902 -0.173193 -1.109542 +v -0.901127 -0.485312 -0.797423 +v -0.720902 -0.485312 -0.797423 +v -0.901127 -0.485312 -0.356020 +v -0.720902 -0.485312 -0.356020 +v -0.901127 -0.173193 -0.043900 +v -0.720902 -0.173193 -0.043900 +v -0.901127 0.268210 -0.043900 +v -0.720902 0.268210 -0.043900 +v -0.901127 0.580330 -0.356020 +v -0.720902 0.580330 -0.356020 +v -0.901127 0.580330 -0.797423 +v -0.720902 0.580330 -0.797423 +v -0.901127 0.268210 0.043900 +v -0.720902 0.268210 0.043900 +v -0.901127 -0.173193 0.043900 +v -0.720902 -0.173193 0.043900 +v -0.901127 -0.485312 0.356020 +v -0.720902 -0.485312 0.356020 +v -0.901127 -0.485312 0.797423 +v -0.720902 -0.485312 0.797423 +v -0.901127 -0.173193 1.109542 +v -0.720902 -0.173193 1.109542 +v -0.901127 0.268210 1.109542 +v -0.720902 0.268210 1.109542 +v -0.901127 0.580330 0.797423 +v -0.720902 0.580330 0.797423 +v -0.901127 0.580330 0.356020 +v -0.720902 0.580330 0.356020 +v 0.901127 0.268210 -1.109542 +v 0.720902 0.268210 -1.109542 +v 0.901127 -0.173193 -1.109542 +v 0.720902 -0.173193 -1.109542 +v 0.901127 -0.485312 -0.797423 +v 0.720902 -0.485312 -0.797423 +v 0.901127 -0.485312 -0.356020 +v 0.720902 -0.485312 -0.356020 +v 0.901127 -0.173193 -0.043900 +v 0.720902 -0.173193 -0.043900 +v 0.901127 0.268210 -0.043900 +v 0.720902 0.268210 -0.043900 +v 0.901127 0.580330 -0.356020 +v 0.720902 0.580330 -0.356020 +v 0.901127 0.580330 -0.797423 +v 0.720902 0.580330 -0.797423 +v 0.901127 0.268210 0.043900 +v 0.720902 0.268210 0.043900 +v 0.901127 -0.173193 0.043900 +v 0.720902 -0.173193 0.043900 +v 0.901127 -0.485312 0.356020 +v 0.720902 -0.485312 0.356020 +v 0.901127 -0.485312 0.797423 +v 0.720902 -0.485312 0.797423 +v 0.901127 -0.173193 1.109542 +v 0.720902 -0.173193 1.109542 +v 0.901127 0.268210 1.109542 +v 0.720902 0.268210 1.109542 +v 0.901127 0.580330 0.797423 +v 0.720902 0.580330 0.797423 +v 0.901127 0.580330 0.356020 +v 0.720902 0.580330 0.356020 +vt 0.279164 0.493799 +vt 0.072560 0.493799 +vt 0.072560 -0.012210 +vt 0.279164 -0.012210 +vt 0.072559 -0.518219 +vt 0.279163 -0.518219 +vt 0.072559 -1.024229 +vt 0.279163 -1.024229 +vt 0.072559 -1.530238 +vt 0.279163 -1.530238 +vt 0.279165 2.517837 +vt 0.072561 2.517837 +vt 0.072561 2.011827 +vt 0.279165 2.011827 +vt 0.072561 1.505818 +vt 0.279165 1.505818 +vt 0.072560 0.999809 +vt 0.279165 0.999809 +vt 0.694571 2.011827 +vt 0.901175 2.011827 +vt 0.901175 2.517837 +vt 0.694571 2.517837 +vt 0.694571 -1.530238 +vt 0.901175 -1.530238 +vt 0.901175 -1.024228 +vt 0.694571 -1.024228 +vt 0.901175 -0.518219 +vt 0.694571 -0.518219 +vt 0.901175 -0.012210 +vt 0.694571 -0.012210 +vt 0.901174 0.493799 +vt 0.694570 0.493799 +vt 0.901174 0.999809 +vt 0.694570 0.999809 +vt 0.901175 1.505817 +vt 0.694570 1.505818 +vt 0.279897 0.493799 +vt 0.279898 -0.012210 +vt 0.486502 -0.012210 +vt 0.486501 0.493799 +vt 0.279898 -0.518219 +vt 0.486502 -0.518219 +vt 0.279898 -1.024228 +vt 0.486502 -1.024229 +vt 0.279898 -1.530238 +vt 0.486502 -1.530238 +vt 0.279897 2.517837 +vt 0.279897 2.011827 +vt 0.486501 2.011827 +vt 0.486501 2.517837 +vt 0.279897 1.505818 +vt 0.486501 1.505818 +vt 0.279897 0.999809 +vt 0.486501 0.999809 +vt 0.693838 2.011827 +vt 0.693838 2.517837 +vt 0.487234 2.517837 +vt 0.487234 2.011827 +vt 0.693839 -1.530238 +vt 0.693838 -1.024229 +vt 0.487234 -1.024229 +vt 0.487234 -1.530238 +vt 0.693838 -0.518220 +vt 0.487234 -0.518220 +vt 0.693838 -0.012210 +vt 0.487234 -0.012210 +vt 0.693838 0.493800 +vt 0.487234 0.493800 +vt 0.693838 0.999809 +vt 0.487234 0.999809 +vt 0.693838 1.505818 +vt 0.487234 1.505818 +vn 0.0000 0.0000 -1.0000 +vn -0.0000 -0.7071 -0.7071 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 -0.7071 0.7071 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.7071 0.7071 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.7071 -0.7071 +s off +f 149/295/21 150/296/21 152/297/21 151/298/21 +f 151/298/22 152/297/22 154/299/22 153/300/22 +f 153/300/23 154/299/23 156/301/23 155/302/23 +f 155/302/24 156/301/24 158/303/24 157/304/24 +f 157/305/25 158/306/25 160/307/25 159/308/25 +f 159/308/26 160/307/26 162/309/26 161/310/26 +f 161/310/27 162/309/27 164/311/27 163/312/27 +f 163/312/28 164/311/28 150/296/28 149/295/28 +f 165/313/21 166/314/21 168/315/21 167/316/21 +f 167/317/22 168/318/22 170/319/22 169/320/22 +f 169/320/23 170/319/23 172/321/23 171/322/23 +f 171/322/24 172/321/24 174/323/24 173/324/24 +f 173/324/25 174/323/25 176/325/25 175/326/25 +f 175/326/26 176/325/26 178/327/26 177/328/26 +f 177/328/27 178/327/27 180/329/27 179/330/27 +f 179/330/28 180/329/28 166/314/28 165/313/28 +f 181/331/21 183/332/21 184/333/21 182/334/21 +f 183/332/22 185/335/22 186/336/22 184/333/22 +f 185/335/23 187/337/23 188/338/23 186/336/23 +f 187/337/24 189/339/24 190/340/24 188/338/24 +f 189/341/25 191/342/25 192/343/25 190/344/25 +f 191/342/26 193/345/26 194/346/26 192/343/26 +f 193/345/27 195/347/27 196/348/27 194/346/27 +f 195/347/28 181/331/28 182/334/28 196/348/28 +f 197/349/21 199/350/21 200/351/21 198/352/21 +f 199/353/22 201/354/22 202/355/22 200/356/22 +f 201/354/23 203/357/23 204/358/23 202/355/23 +f 203/357/24 205/359/24 206/360/24 204/358/24 +f 205/359/25 207/361/25 208/362/25 206/360/25 +f 207/361/26 209/363/26 210/364/26 208/362/26 +f 209/363/27 211/365/27 212/366/27 210/364/27 +f 211/365/28 197/349/28 198/352/28 212/366/28 +g Cube.000_Cube.008 +v -0.792992 1.200951 -1.268787 +v -0.792992 1.200951 1.268787 +v -0.560730 1.649535 -1.268787 +v -0.560730 1.649535 1.268787 +v -0.000000 1.835345 1.268787 +v -0.000000 1.835345 -1.268787 +v 0.792992 1.200951 -1.268787 +v 0.792992 1.200951 1.268787 +v 0.560730 1.649535 -1.268787 +v 0.560730 1.649535 1.268787 +vt 3.173871 2.353881 +vt -2.391578 2.353881 +vt -2.391578 1.288979 +vt 3.173871 1.288979 +vt -2.391578 0.224077 +vt 3.173871 0.224077 +vt 3.173871 -1.905729 +vt 3.173871 -0.840826 +vt -2.391578 -0.840826 +vt -2.391578 -1.905728 +vn -0.8880 0.4598 0.0000 +vn -0.3146 0.9492 0.0000 +vn 0.8880 0.4598 0.0000 +vn 0.3146 0.9492 0.0000 +s off +f 213/367/29 214/368/29 216/369/29 215/370/29 +f 215/370/30 216/369/30 217/371/30 218/372/30 +f 219/373/31 221/374/31 222/375/31 220/376/31 +f 221/374/32 218/372/32 217/371/32 222/375/32 +g Cube.006_Cube.007 +v -0.722861 -0.094866 1.158711 +v -0.722861 1.240430 1.158711 +v -0.722861 -0.094866 1.059710 +v -0.722861 1.240430 1.059710 +v -0.623860 -0.094866 1.158711 +v -0.623860 1.240430 1.158711 +v -0.725927 -0.094866 -1.158643 +v -0.725927 1.240430 -1.158643 +v -0.725927 -0.094866 -1.059642 +v -0.725927 1.240430 -1.059642 +v -0.626926 -0.094866 -1.158643 +v -0.626926 1.240430 -1.158643 +v 0.722861 -0.094866 1.158711 +v 0.722861 1.240430 1.158711 +v 0.722861 -0.094866 1.059710 +v 0.722861 1.240430 1.059710 +v 0.623860 -0.094866 1.158711 +v 0.623860 1.240430 1.158711 +v 0.725927 -0.094866 -1.158643 +v 0.725927 1.240430 -1.158643 +v 0.725927 -0.094866 -1.059642 +v 0.725927 1.240430 -1.059642 +v 0.626926 -0.094866 -1.158643 +v 0.626926 1.240430 -1.158643 +vt -0.339657 0.628705 +vt 1.340090 0.628704 +vt 1.340090 0.753243 +vt -0.339657 0.753243 +vt -0.339658 0.504167 +vt 1.340090 0.504165 +vt -0.339657 0.129512 +vt -0.339657 0.004973 +vt 1.340090 0.004973 +vt 1.340090 0.129512 +vt -0.339657 0.254051 +vt 1.340090 0.254050 +vt -0.339658 0.878300 +vt -0.339658 0.753761 +vt 1.340090 0.753762 +vt 1.340090 0.878300 +vt -0.339657 1.002839 +vt 1.340090 1.002838 +vt -0.339657 0.379109 +vt 1.340090 0.379108 +vt 1.340090 0.503647 +vt -0.339657 0.503647 +vt -0.339658 0.254571 +vt 1.340090 0.254569 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +s off +f 223/377/33 224/378/33 226/379/33 225/380/33 +f 227/381/34 228/382/34 224/378/34 223/377/34 +f 229/383/33 231/384/33 232/385/33 230/386/33 +f 233/387/35 229/383/35 230/386/35 234/388/35 +f 235/389/36 237/390/36 238/391/36 236/392/36 +f 239/393/34 235/389/34 236/392/34 240/394/34 +f 241/395/36 242/396/36 244/397/36 243/398/36 +f 245/399/35 246/400/35 242/396/35 241/395/35 diff --git a/mods/commoditymarket/persistence.lua b/mods/commoditymarket/persistence.lua new file mode 100644 index 0000000..edff9b1 --- /dev/null +++ b/mods/commoditymarket/persistence.lua @@ -0,0 +1,200 @@ +-- Internal persistence library + +--[[ Provides ]] +-- persistence.store(path, ...): Stores arbitrary items to the file at the given path +-- persistence.load(path): Loads files that were previously stored with store and returns them + +--[[ Limitations ]] +-- Does not export userdata, threads or most function values +-- Function export is not portable + +--[[ License: MIT (see bottom) ]] + +-- Private methods +local write, writeIndent, writers, refCount; + +-- write thing (dispatcher) +write = function (file, item, level, objRefNames) + writers[type(item)](file, item, level, objRefNames); +end; + +-- write indent +writeIndent = function (file, level) + for i = 1, level do + file:write("\t"); + end; +end; + +-- recursively count references +refCount = function (objRefCount, item) + -- only count reference types (tables) + if type(item) == "table" then + -- Increase ref count + if objRefCount[item] then + objRefCount[item] = objRefCount[item] + 1; + else + objRefCount[item] = 1; + -- If first encounter, traverse + for k, v in pairs(item) do + refCount(objRefCount, k); + refCount(objRefCount, v); + end; + end; + end; +end; + +-- Format items for the purpose of restoring +writers = { + ["nil"] = function (file, item) + file:write("nil"); + end; + ["number"] = function (file, item) + file:write(tostring(item)); + end; + ["string"] = function (file, item) + file:write(string.format("%q", item)); + end; + ["boolean"] = function (file, item) + if item then + file:write("true"); + else + file:write("false"); + end + end; + ["table"] = function (file, item, level, objRefNames) + local refIdx = objRefNames[item]; + if refIdx then + -- Table with multiple references + file:write("multiRefObjects["..refIdx.."]"); + else + -- Single use table + file:write("{\n"); + for k, v in pairs(item) do + writeIndent(file, level+1); + file:write("["); + write(file, k, level+1, objRefNames); + file:write("] = "); + write(file, v, level+1, objRefNames); + file:write(";\n"); + end + writeIndent(file, level); + file:write("}"); + end; + end; + ["function"] = function (file, item) + -- Does only work for "normal" functions, not those + -- with upvalues or c functions + local dInfo = debug.getinfo(item, "uS"); + if dInfo.nups > 0 then + file:write("nil --[[functions with upvalue not supported]]"); + elseif dInfo.what ~= "Lua" then + file:write("nil --[[non-lua function not supported]]"); + else + local r, s = pcall(string.dump,item); + if r then + file:write(string.format("loadstring(%q)", s)); + else + file:write("nil --[[function could not be dumped]]"); + end + end + end; + ["thread"] = function (file, item) + file:write("nil --[[thread]]\n"); + end; + ["userdata"] = function (file, item) + file:write("nil --[[userdata]]\n"); + end; +} + +return function (path, ...) + local file, e; + if type(path) == "string" then + -- Path, open a file + file, e = io.open(path, "w"); + if not file then + return error(e); + end + else + -- Just treat it as file + file = path; + end + local n = select("#", ...); + -- Count references + local objRefCount = {}; -- Stores reference that will be exported + for i = 1, n do + refCount(objRefCount, (select(i,...))); + end; + -- Export Objects with more than one ref and assign name + -- First, create empty tables for each + local objRefNames = {}; + local objRefIdx = 0; + file:write("-- Persistent Data\n"); + file:write("local multiRefObjects = {\n"); + for obj, count in pairs(objRefCount) do + if count > 1 then + objRefIdx = objRefIdx + 1; + objRefNames[obj] = objRefIdx; + file:write("{};"); -- table objRefIdx + end; + end; + file:write("\n} -- multiRefObjects\n"); + -- Then fill them (this requires all empty multiRefObjects to exist) + for obj, idx in pairs(objRefNames) do + for k, v in pairs(obj) do + file:write("multiRefObjects["..idx.."]["); + write(file, k, 0, objRefNames); + file:write("] = "); + write(file, v, 0, objRefNames); + file:write(";\n"); + end; + end; + -- Create the remaining objects + for i = 1, n do + file:write("local ".."obj"..i.." = "); + write(file, (select(i,...)), 0, objRefNames); + file:write("\n"); + end + -- Return them + if n > 0 then + file:write("return obj1"); + for i = 2, n do + file:write(" ,obj"..i); + end; + file:write("\n"); + else + file:write("return\n"); + end; + file:close(); +end, function (path) + local f, e = loadfile(path); + if f then + return f(); + else + return nil, e; + end; +end + +--[[ + Copyright (c) 2010 Gerhard Roethlin + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. +]] diff --git a/mods/commoditymarket/readme.md b/mods/commoditymarket/readme.md new file mode 100644 index 0000000..a1672dd --- /dev/null +++ b/mods/commoditymarket/readme.md @@ -0,0 +1,95 @@ +This mod implements marketplaces where players can post buy and sell offers for various items, allowing for organic market forces to determine the relative values of the resources in a world. + +The basic market interface is the same across all markets and market types, but this mod allows for a variety of different ways that markets can be configured to support different playstyles. Markets can have restrictions on what they will allow to be bought and sold, different types of "currency", and can share a common inventory across multiple locations or can be localized to just one spot at the discretion of the server owner. + +![](screenshot.png) + +## Currency + +Each market has one or more "currency" items defined that are treated differently from the other items that can be bought and sold there. Currency items are translated into a player's currency balance rather than being bought and sold directly. + +For example, some of the markets offered by the "commoditymarket_fantasy" mod have this currency definition: + + { + ["default:gold_ingot"] = 1000, + ["commoditymarket_fantasy:gold_coin"] = 1 + } + +When a gold ingot is added to the player's market account it turns into 1000 units of currency. When a gold coin is added it turns into 1 unit of currency. You can't buy and sell gold directly in this market, it is instead the "standard" by which the value of other items is measured. + +There's no reason that all markets in a given world have to use the same currency. Having variety in currency types adds flavour to the world and also introduces opportunities for enterprising traders to make a profit by moneychanging between different marketplaces. + +## Account Inventory + +In addition to tracking a player's currency balance, each player's account has an inventory that serves as a holding area for items that are destined to be sold or that have been bought by the player but not yet retrieved. This inventory is a bit different from the standard Minetest inventory in that it doesn't hold individual item "stacks", allowing for larger quantities of items to be accumulated than would otherwise be practical. If a player needs to buy 20,000 stone bricks for a major construction project then their account's inventory will hold that. + +To prevent abuse of the market inventory as a free storage space, or just to add some unique flavor to a particular market, a limit on the inventory's size can be added. This limit only affects transfers from a player's personal inventory into the market inventory; the limit can be exceeded by incoming items being sold to the player. + +Note that tools cannot be added to the market inventory if they have any wear on them, nor can the market handle items with attached metadata (such as books that have had text added to them). + +## Placing a "Buy" Order + +A buy order is an offer to give a certain amount of currency in exchange for a particular type of item. To place a buy order go to the "Market Orders" tab of the market's interface and select the item from the list of items on the market. If the item isn't listed it may be that the market is simply "unaware" of the item's existence; try placing an example of the item into your personal inventory and if the item is permitted on the market a new entry will be added to Market Orders. + +Enter the quantity and price you desire and then click the "buy" button to place a buy order. + +If there are already "sell" orders for the item when you place a buy order, some or all of your buy order might be immediately fulfilled provided you are offering a sufficient price. Your purchases will be made at the price that the sell orders have been set to - if you were willing to pay 15 units of currency per item but someone was already offering to sell for 2 units of currency per item, you only pay 2 units for each of that offer's items. + +If there aren't enough compatible sell orders to fulfill your buy order, the remainder will be placed into the market and made available for future sellers to see and fulfill if they agree to your price. Your buy order will immediately deduct the currency required for it from your account's balance, but if you cancel your order you will get that currency back - it's not gone until the order is actually fulfilled. + +Double-click on your order in the orders list to cancel it. + +## Placing a "Sell" Order + +Sell orders are an offer of a certain amount of an item and a price you're willing to accept in exchange for them. They're placed in a similar manner to buy orders, except by clicking the "sell" button instead of the "buy" button. + +If there are already buyers with buy orders that meet or exceed your price, some or all of your sell order may be immediately fulfilled. You'll be paid the price that the buyers are offering rather than the amount you're demanding. + +If any of your sell offer is left unfulfilled, the sell order will be added to the market for future buyers to see. The items for this offer will be immediately taken from your market inventory but if you cancel your order you will get those items back. + +Double-click on your order in the orders list to cancel it. + +## Commands + +This mod has several commands that a server administrator can use: + +* `market.removeitem marketname item` -- cancels all existing buy and sell orders for an item and removes its entry from the market tab. This is useful if you've changed what items are permitted in a particular market and need to clear out items that are no longer allowed. +* `market.show marketname` -- opens the market's formspec +* `market.list` -- lists the marketnames of all registered markets +* `market.purge_unknowns` -- executes "removeitem" for all markets on all items that don't have a definition. Useful for clearing out items that are no longer defined due to a mod being updated or removed. +* `market.addeverything marketname` - Adds all registered items to a market's listings. NOTE: this is intended as a debugging tool, not for use in a live server, as it doesn't filter out items that a player cannot actually harvest in-world. + +## Registering a market + +The mod "[commoditymarket_fantasy](https://github.com/FaceDeer/commoditymarket_fantasy)" contains a number of pre-defined markets that provide examples of what's possible with this mod. They include: + +* King's Market - a basic sort of "commoner's marketplace", only open during the day +* Night Market - the shadier side of commerce, only open during the night +* Trader's Caravan - a type of market that players can build and place themselves, with a small inventory capacity. +* Goblin Exchange - a strange marketplace that uses coal as a currency +* Undermarket - where dark powers make their trades, using Mese as a currency + +All of these except for the Trader's Caravan are intended to be placed in specific locations by server administrators or mapgen, they don't have crafting recipes. Modifying these markets or creating your own from scratch should hopefully be a fairly straightforward task. + +### Market definition API + +``` +local market_def = { + description = "Night Market", -- A short name for this market, appears as the text of the "info" tab of the market's UI + long_description = "When the sun sets and the stalls of the King's Market close, other vendors are just waking up to share their wares. The Night Market is not as voluminous as the King's Market but accepts a wider range of wares. It accepts the same gold coinage of the realm, one thousand coins to the gold ingot.", -- A longer description with flavor text and other information to present to the user, shown in the info tab. Optional. + currency = { + ["default:gold_ingot"] = 1000, + ["commoditymarket:gold_coins"] = 1 + }, -- List all items that get translated into "currency" here, along with their conversion rates. Take care to ensure there's no way for a player to multiply their money when crafting currency items into each other (eg, if there was some way to get more than 1000 coin items out of a gold ingot, in this case) + currency_symbol = "☼", -- Used in various places in the UI. If not defined, defaults to "¤" (the generic currency symbol) + inventory_limit = 10000, -- Optional, when set this prevents the player from adding items to their market inventory when it's over this limit + sell_limit = 10000, -- Optional, when set this prevents sell orders from being added if the player already has this many items for sale + initial_items = {"default:cobble", "default:wood"}, -- Optional, a list of items that the market will be initialized with on startup. Players can add other items during play. + allow_item = function(item) return true end, -- Optional, this function is used to determine whether the market permits a player to add a particular item to its inventory. + anonymous = true, -- If set to true then the player won't be able to see the names associated with other player's orders, only their own. +} + +commoditymarket.register_market("market_name", market_def) +``` + +Once a market is defined, use `commoditymarket.show_market(market_name, player_name)` to show the market interface to a player. \ No newline at end of file diff --git a/mods/commoditymarket/screenshot.png b/mods/commoditymarket/screenshot.png new file mode 100644 index 0000000..057b312 Binary files /dev/null and b/mods/commoditymarket/screenshot.png differ diff --git a/mods/commoditymarket/settingtypes.txt b/mods/commoditymarket/settingtypes.txt new file mode 100644 index 0000000..7840f98 --- /dev/null +++ b/mods/commoditymarket/settingtypes.txt @@ -0,0 +1,8 @@ +#Some item images are very large and break the market formspec. +#See https://github.com/minetest/minetest/issues/9300 +#Alternately, use: +#commoditymarket.override_item_icon(item_name, new_icon_texture) +#or +#commoditymarket.override_image_icon(old_icon_texture, new_icon_texture) +#to override a troublesome image directly. +commoditymarket_enable_item_icons (Enable item icon images in market formspecs) bool true diff --git a/mods/commoditymarket/sounds/commoditymarket_error.ogg b/mods/commoditymarket/sounds/commoditymarket_error.ogg new file mode 100644 index 0000000..d1ae7c9 Binary files /dev/null and b/mods/commoditymarket/sounds/commoditymarket_error.ogg differ diff --git a/mods/commoditymarket/sounds/commoditymarket_register_closed.ogg b/mods/commoditymarket/sounds/commoditymarket_register_closed.ogg new file mode 100644 index 0000000..bc30f33 Binary files /dev/null and b/mods/commoditymarket/sounds/commoditymarket_register_closed.ogg differ diff --git a/mods/commoditymarket/sounds/commoditymarket_register_opened.ogg b/mods/commoditymarket/sounds/commoditymarket_register_opened.ogg new file mode 100644 index 0000000..9aa6230 Binary files /dev/null and b/mods/commoditymarket/sounds/commoditymarket_register_opened.ogg differ diff --git a/mods/commoditymarket/sounds/license.txt b/mods/commoditymarket/sounds/license.txt new file mode 100644 index 0000000..fed2253 --- /dev/null +++ b/mods/commoditymarket/sounds/license.txt @@ -0,0 +1,3 @@ +commoditymarket_register_closed.ogg - from https://freesound.org/people/bspiller5/sounds/180252/ by bspiller5 under the CC-BY 3.0 license +commoditymarket_register_opened.ogg - from https://freesound.org/people/kiddpark/sounds/201159/ by kiddpark under the CC-BY 3.0 license +commoditymarket_error.ogg - from https://freesound.org/people/LorenzoTheGreat/sounds/417794/ by LorenzoTheGreat under the CC-BY-SA 3.0 license \ No newline at end of file diff --git a/mods/commoditymarket/textures/commoditymarket_caravan.png b/mods/commoditymarket/textures/commoditymarket_caravan.png new file mode 100644 index 0000000..d193a1f Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_caravan.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_caravan_sign.png b/mods/commoditymarket/textures/commoditymarket_caravan_sign.png new file mode 100644 index 0000000..2c5280b Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_caravan_sign.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_caravan_sign_inventory.png b/mods/commoditymarket/textures/commoditymarket_caravan_sign_inventory.png new file mode 100644 index 0000000..d1d3d14 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_caravan_sign_inventory.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_clear.png b/mods/commoditymarket/textures/commoditymarket_clear.png new file mode 100644 index 0000000..ac6f3c3 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_clear.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_crown.png b/mods/commoditymarket/textures/commoditymarket_crown.png new file mode 100644 index 0000000..2df1148 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_crown.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_door_wood.png b/mods/commoditymarket/textures/commoditymarket_door_wood.png new file mode 100644 index 0000000..ae70bda Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_door_wood.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_empty_shelf.png b/mods/commoditymarket/textures/commoditymarket_empty_shelf.png new file mode 100644 index 0000000..404fc8b Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_empty_shelf.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_goblin.png b/mods/commoditymarket/textures/commoditymarket_goblin.png new file mode 100644 index 0000000..b167d22 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_goblin.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_gold_coins.png b/mods/commoditymarket/textures/commoditymarket_gold_coins.png new file mode 100644 index 0000000..73f4e83 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_gold_coins.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_moon.png b/mods/commoditymarket/textures/commoditymarket_moon.png new file mode 100644 index 0000000..7341050 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_moon.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_search.png b/mods/commoditymarket/textures/commoditymarket_search.png new file mode 100644 index 0000000..2ba479e Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_search.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_shingles_wood.png b/mods/commoditymarket/textures/commoditymarket_shingles_wood.png new file mode 100644 index 0000000..6e86ea6 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_shingles_wood.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_sign.png b/mods/commoditymarket/textures/commoditymarket_sign.png new file mode 100644 index 0000000..fcdd409 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_sign.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_sign_post.png b/mods/commoditymarket/textures/commoditymarket_sign_post.png new file mode 100644 index 0000000..7181397 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_sign_post.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_trade.png b/mods/commoditymarket/textures/commoditymarket_trade.png new file mode 100644 index 0000000..b6401b0 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_trade.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_trapdoor.png b/mods/commoditymarket/textures/commoditymarket_trapdoor.png new file mode 100644 index 0000000..3c64693 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_trapdoor.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_under.png b/mods/commoditymarket/textures/commoditymarket_under.png new file mode 100644 index 0000000..007be31 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_under.png differ diff --git a/mods/commoditymarket/textures/commoditymarket_under_top.png b/mods/commoditymarket/textures/commoditymarket_under_top.png new file mode 100644 index 0000000..22a1bb1 Binary files /dev/null and b/mods/commoditymarket/textures/commoditymarket_under_top.png differ diff --git a/mods/commoditymarket/textures/license.txt b/mods/commoditymarket/textures/license.txt new file mode 100644 index 0000000..67af3a6 --- /dev/null +++ b/mods/commoditymarket/textures/license.txt @@ -0,0 +1 @@ +commoditymarket_search.png, commoditymarket_clear.png - Copyright © Diego Martínez (kaeza): CC BY-SA 3.0 diff --git a/mods/commoditymarket_fantasy/init.lua b/mods/commoditymarket_fantasy/init.lua new file mode 100644 index 0000000..b1e2ce0 --- /dev/null +++ b/mods/commoditymarket_fantasy/init.lua @@ -0,0 +1,534 @@ +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +local S = minetest.get_translator(minetest.get_current_modname()) + +dofile(modpath.."/mapgen_dungeon_markets.lua") + +local coins_per_ingot = math.floor(tonumber(minetest.settings:get("commoditymarket_coins_per_ingot")) or 1000) + +-- Only register gold coins once, if required +local gold_coins_registered = false +local register_gold_coins = function() + if not gold_coins_registered then + minetest.register_craftitem("commoditymarket_fantasy:gold_coins", { + description = S("Gold Coins"), + _doc_items_longdesc = S("A gold ingot is far too valuable to use as a basic unit of value, so it has become common practice to divide the standard gold bar into @1 small disks to make trade easier.", coins_per_ingot), + _doc_items_usagehelp = S("Gold coins can be deposited and withdrawn from markets that accept them as currency. These markets can make change if you have @1 coins and would like them back in ingot form again.", coins_per_ingot), + inventory_image = "commoditymarket_gold_coins.png", + stack_max = coins_per_ingot, + }) + gold_coins_registered = true + end +end + +local default_items = {"default:axe_bronze","default:axe_diamond","default:axe_mese","default:axe_steel","default:axe_steel","default:axe_stone","default:axe_wood","default:pick_bronze","default:pick_diamond","default:pick_mese","default:pick_steel","default:pick_stone","default:pick_wood","default:shovel_bronze","default:shovel_diamond","default:shovel_mese","default:shovel_steel","default:shovel_stone","default:shovel_wood","default:sword_bronze","default:sword_diamond","default:sword_mese","default:sword_steel","default:sword_stone","default:sword_wood", "default:blueberries", "default:book", "default:bronze_ingot", "default:clay_brick", "default:clay_lump", "default:coal_lump", "default:copper_ingot", "default:copper_lump", "default:diamond", "default:flint", "default:gold_ingot", "default:gold_lump", "default:iron_lump", "default:mese_crystal", "default:mese_crystal_fragment", "default:obsidian_shard", "default:paper", "default:steel_ingot", "default:stick", "default:tin_ingot", "default:tin_lump", "default:acacia_tree", "default:acacia_wood", "default:apple", "default:aspen_tree", "default:aspen_wood", "default:blueberry_bush_sapling", "default:bookshelf", "default:brick", "default:bronzeblock", "default:bush_sapling", "default:cactus", "default:clay", "default:coalblock", "default:cobble", "default:copperblock", "default:desert_cobble", "default:desert_sand", "default:desert_sandstone", "default:desert_sandstone_block", "default:desert_sandstone_brick", "default:desert_stone", "default:desert_stone_block", "default:desert_stonebrick", "default:diamondblock", "default:dirt", "default:glass", "default:goldblock", "default:gravel", "default:ice", "default:junglegrass", "default:junglesapling", "default:jungletree", "default:junglewood", "default:ladder_steel", "default:ladder_wood", "default:large_cactus_seedling", "default:mese", "default:mese_post_light", "default:meselamp", "default:mossycobble", "default:obsidian", "default:obsidian_block", "default:obsidian_glass", "default:obsidianbrick", "default:papyrus", "default:pine_sapling", "default:pine_tree", "default:pine_wood", "default:sand", "default:sandstone", "default:sandstone_block", "default:sandstonebrick", "default:sapling", "default:silver_sand", "default:silver_sandstone", "default:silver_sandstone_block", "default:silver_sandstone_brick", "default:snow", "default:snowblock", "default:steelblock", "default:stone", "default:stone_block", "default:stonebrick", "default:tinblock", "default:tree", "default:wood",} + +local usage_help = S("Right-click on this to open the market interface.") + +------------------------------------------------------------------------------ +-- King's Market + +if minetest.settings:get_bool("commoditymarket_enable_kings_market", true) then + +local kings_def = { + description = S("King's Market"), + long_description = S("The largest and most accessible market for the common man, the King's Market uses gold coins as its medium of exchange (or the equivalent in gold ingots - @1 coins to the ingot). However, as a respectable institution of the surface world, the King's Market operates only during the hours of daylight. The purchase and sale of swords and explosives is prohibited in the King's Market. Gold coins are represented by a '☼' symbol.", coins_per_ingot), + currency = { + ["default:gold_ingot"] = coins_per_ingot, + ["commoditymarket_fantasy:gold_coins"] = 1 + }, + currency_symbol = "☼", -- "\u{263C}" Alchemical symbol for gold + allow_item = function(item) + if item:sub(1,13) == "default:sword" or item:sub(1,4) == "tnt:" then + return false + end + return true + end, + inventory_limit = 100000, + --sell_limit =, -- no sell limit for the King's Market + initial_items = default_items, +} + +register_gold_coins() + +commoditymarket.register_market("kings", kings_def) + +local kings_protect = minetest.settings:get_bool("commoditymarket_protect_kings_market", true) +local on_blast +if kings_protect then + on_blast = function() end +end + +minetest.register_node("commoditymarket_fantasy:kings_market", { + description = kings_def.description, + _doc_items_longdesc = kings_def.long_description, + _doc_items_usagehelp = usage_help, + tiles = {"default_chest_top.png","default_chest_top.png", + "default_chest_side.png","default_chest_side.png", + "commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_crown.png",}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local timeofday = minetest.get_timeofday() + if timeofday > 0.2 and timeofday < 0.8 then + commoditymarket.show_market("kings", clicker:get_player_name()) + else + minetest.chat_send_player(clicker:get_player_name(), S("At this time of day the King's Market is closed.")) + minetest.sound_play({name = "commoditymarket_error", gain = 0.1}, {to_player=clicker:get_player_name()}) + end + end, + can_dig = function(pos, player) + return not kings_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) +end +------------------------------------------------------------------------------- +-- Night Market + +if minetest.settings:get_bool("commoditymarket_enable_night_market", true) then +local night_def = { + description = S("Night Market"), + long_description = S("When the sun sets and the stalls of the King's Market close, other vendors are just waking up to share their wares. The Night Market is not as voluminous as the King's Market but accepts a wider range of wares. It accepts the same gold coinage of the realm, @1 coins to the gold ingot.", coins_per_ingot), + currency = { + ["default:gold_ingot"] = coins_per_ingot, + ["commoditymarket_fantasy:gold_coins"] = 1 + }, + currency_symbol = "☼", --"\u{263C}" + inventory_limit = 10000, + --sell_limit =, -- no sell limit for the Night Market + initial_items = default_items, + anonymous = true, +} + +register_gold_coins() + +commoditymarket.register_market("night", night_def) + +local night_protect = minetest.settings:get_bool("commoditymarket_protect_night_market", true) +local on_blast +if night_protect then + on_blast = function() end +end + +minetest.register_node("commoditymarket_fantasy:night_market", { + description = night_def.description, + _doc_items_longdesc = night_def.long_description, + _doc_items_usagehelp = usage_help, + tiles = {"default_chest_top.png","default_chest_top.png", + "default_chest_side.png","default_chest_side.png", + "commoditymarket_empty_shelf.png","default_chest_side.png^commoditymarket_moon.png",}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local timeofday = minetest.get_timeofday() + if timeofday < 0.2 or timeofday > 0.8 then + commoditymarket.show_market("night", clicker:get_player_name()) + else + minetest.chat_send_player(clicker:get_player_name(), S("At this time of day the Night Market is closed.")) + minetest.sound_play({name = "commoditymarket_error", gain = 0.1}, {to_player=clicker:get_player_name()}) + end + end, + can_dig = function(pos, player) + return not night_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) +end + +------------------------------------------------------------------------------- +if minetest.settings:get_bool("commoditymarket_enable_caravan_market", true) then +-- "Trader's Caravan" - small-capacity market that players can summon + +local time_until_caravan = 120 -- caravan arrives in two minutes +local dwell_time = 600 -- caravan leaves ten minutes after last usage + +local caravan_def = { + description = S("Trader's Caravan"), + long_description = S("Unlike most markets that have well-known fixed locations that travelers congregate to, the network of Trader's Caravans is fluid and dynamic in their locations. A Trader's Caravan can show up anywhere, make modest trades, and then be gone the next time you visit them. These caravans accept gold and gold coins as a currency (one gold ingot to @1 gold coins exchange rate). Any reasonably-wealthy person can create a signpost marking a location where Trader's Caravans will make a stop.", coins_per_ingot), + currency = { + ["default:gold_ingot"] = coins_per_ingot, + ["commoditymarket_fantasy:gold_coins"] = 1 + }, + currency_symbol = "☼", --"\u{263C}" + inventory_limit = 1000, + sell_limit = 1000, + initial_items = default_items, +} + +register_gold_coins() + +minetest.register_craft({ + output = "commoditymarket_fantasy:caravan_post", + recipe = { + {'group:wood', 'group:wood', ''}, + {'group:wood', "default:gold_ingot", ''}, + {'group:wood', "default:chest_locked", ''}, + } +}) + +commoditymarket.register_market("caravan", caravan_def) + +local create_caravan_def = function(override_table) +local def = { + description = caravan_def.description, + _doc_items_longdesc = caravan_def.long_description, + _doc_items_usagehelp = usage_help, + drawtype = "mesh", + mesh = "commoditymarket_wagon.obj", + tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_wood.png", backface_culling = true }, -- base wood + { name = "default_fence_rail_wood.png", backface_culling = true }, -- wheel sides + { name = "default_coal_block.png", backface_culling = true }, -- wheel tyre + { name = "commoditymarket_shingles_wood.png", backface_culling = true }, -- roof + { name = "default_junglewood.png", backface_culling = true }, -- corner wood + }, + collision_box = { + type = "fixed", + fixed = { + -- Note: this nodebox should have a height of 1.5, but using 95/64 as a workaround for + -- https://github.com/minetest/minetest/issues/9322 + {-0.75, -0.5, -1.25, 0.75, 95/64, 1.25}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.75, -0.5, -1.25, 0.75, 95/64, 1.25}, + }, + }, + + paramtype2 = "facedir", + drop = "", + groups = {choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + commoditymarket.show_market("caravan", clicker:get_player_name()) + local timer = minetest.get_node_timer(pos) + timer:start(dwell_time) + end, + after_destruct = function(pos, oldnode) + local facedir = oldnode.param2 + local dir = minetest.facedir_to_dir(facedir) + local target = vector.add(pos, vector.multiply(dir,-3)) + local target_node = minetest.get_node(target) + if target_node.name == "commoditymarket_fantasy:caravan_post" then + local meta = minetest.get_meta(target) + meta:set_string("infotext", S("Right-click to summon a trader's caravan")) + end + end, + on_timer = function(pos, elapsed) + minetest.set_node(pos, {name="air"}) + minetest.sound_play("commoditymarket_register_closed", { + pos = pos, + gain = 1.0, -- default + max_hear_distance = 32, -- default, uses an euclidean metric + }) + end, + } + if override_table then + for k, v in pairs(override_table) do + def[k] = v + end + end + return def +end + +-- Create five caravans with different textures, randomly pick which one shows up. +minetest.register_node("commoditymarket_fantasy:caravan_market_1", create_caravan_def()) +minetest.register_node("commoditymarket_fantasy:caravan_market_2", create_caravan_def({ +tiles = { + { name = "commoditymarket_door_wood.png^[multiply:#CCCCFF", backface_culling = true }, -- door + { name = "default_acacia_wood.png", backface_culling = true }, -- base wood + { name = "default_fence_rail_wood.png", backface_culling = true }, -- wheel sides + { name = "default_copper_block.png", backface_culling = true }, -- wheel tyre + { name = "commoditymarket_shingles_wood.png^[multiply:#CC8888", backface_culling = true }, -- roof + { name = "default_wood.png", backface_culling = true }, -- corner wood +} +})) +minetest.register_node("commoditymarket_fantasy:caravan_market_3", create_caravan_def({ +tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_aspen_wood.png", backface_culling = true }, -- base wood + { name = "default_fence_aspen_wood.png", backface_culling = true }, -- wheel sides + { name = "default_cobble.png", backface_culling = true }, -- wheel tyre + { name = "default_stone_brick.png", backface_culling = true }, -- roof + { name = "default_pine_tree.png", backface_culling = true }, -- corner wood +} +})) +minetest.register_node("commoditymarket_fantasy:caravan_market_4", create_caravan_def({ +tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_junglewood.png", backface_culling = true }, -- base wood + { name = "default_fence_rail_junglewood.png", backface_culling = true }, -- wheel sides + { name = "default_obsidian.png", backface_culling = true }, -- wheel tyre + { name = "commoditymarket_shingles_wood.png^[multiply:#88FF88", backface_culling = true }, -- roof + { name = "default_tree.png", backface_culling = true }, -- corner wood +} +})) +minetest.register_node("commoditymarket_fantasy:caravan_market_5", create_caravan_def({ +tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_pine_wood.png", backface_culling = true }, -- base wood + { name = "default_chest_lock.png", backface_culling = true }, -- wheel sides + { name = "default_chest_top.png", backface_culling = true }, -- wheel tyre + { name = "default_furnace_top.png", backface_culling = true }, -- roof + { name = "default_wood.png", backface_culling = true }, -- corner wood +} +})) + +local caravan_protect = minetest.settings:get_bool("commoditymarket_protect_caravan_market", true) +local on_blast +if caravan_protect then + on_blast = function() end +end + +-- This one doesn't delete itself, server admins can place a permanent instance of it that way. Maybe inside towns next to bigger stationary markets. +minetest.register_node("commoditymarket_fantasy:caravan_market_permanent", { + description = caravan_def.description, + _doc_items_longdesc = caravan_def.long_description, + _doc_items_usagehelp = usage_help, + drawtype = "mesh", + mesh = "commoditymarket_wagon.obj", + light_source = 7, + tiles = { + { name = "commoditymarket_door_wood.png", backface_culling = true }, -- door + { name = "default_wood.png", backface_culling = true }, -- base wood + { name = "default_fence_rail_wood.png", backface_culling = true }, -- wheel sides + { name = "default_coal_block.png", backface_culling = true }, -- wheel tyre + { name = "commoditymarket_shingles_wood.png", backface_culling = true }, -- roof + { name = "default_junglewood.png", backface_culling = true }, -- corner wood + }, + collision_box = { + type = "fixed", + fixed = { + -- Note: this nodebox should have a height of 1.5, but using 95/64 as a workaround for + -- https://github.com/minetest/minetest/issues/9322 + {-0.75, -0.5, -1.25, 0.75, 95/64, 1.25}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.75, -0.5, -1.25, 0.75, 95/64, 1.25}, + }, + }, + + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + commoditymarket.show_market("caravan", clicker:get_player_name()) + end, + can_dig = function(pos, player) + return not caravan_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) + +-- is a 5x3 area centered around pos clear of obstruction and has usable ground? +local is_suitable_caravan_space = function(pos, facedir) + local x_dim = 2 + local z_dim = 2 + local dir = minetest.facedir_to_dir(facedir) + if dir.x ~= 0 then + z_dim = 1 + elseif dir.z ~= 0 then + x_dim = 1 + end + + -- walkable ground? + for x = pos.x - x_dim, pos.x + x_dim, 1 do + for z = pos.z - z_dim, pos.z + z_dim, 1 do + local node = minetest.get_node({x=x, y=pos.y-1, z=z}) + local node_def = minetest.registered_nodes[node.name] + if node_def == nil or node_def.walkable ~= true then return false end + end + end + -- buildable_to in the rest? + for y = pos.y, pos.y+2, 1 do + for x = pos.x - x_dim, pos.x + x_dim, 1 do + for z = pos.z - z_dim, pos.z + z_dim, 1 do + local node = minetest.get_node({x=x, y=y, z=z}) + local node_def = minetest.registered_nodes[node.name] + if node_def == nil or node_def.buildable_to ~= true then return false end + end + end + end + return true +end + +minetest.register_node("commoditymarket_fantasy:caravan_post", { + description = S("Trading Post"), + _long_items_longdesc = S("This post signals passing caravan traders that customers can be found here, and signals to customers that caravan traders can be found here. If no caravan is present, right-click to summon one."), + _doc_items_usagehelp = S("The trader's caravan requires a suitable open space next to the trading post for it to arrive, and takes some time to arrive after being summoned. The post gives a countdown to the caravan's arrival when moused over."), + tiles = {"commoditymarket_sign.png^[transformR90", "commoditymarket_sign.png^[transformR270", + "commoditymarket_sign.png^commoditymarket_caravan_sign.png", "commoditymarket_sign.png^commoditymarket_caravan_sign.png^[transformFX", + "commoditymarket_sign_post.png", "commoditymarket_sign_post.png"}, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + inventory_image = "commoditymarket_caravan_sign_inventory.png", + paramtype= "light", + paramtype2 = "facedir", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.125,-0.5,-0.5,0.125,2.0625,-0.25}, + {-0.0625,1.4375,-0.25,0.0625,2.0,0.5}, + }, + }, + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(1.0) + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local timer = minetest.get_node_timer(pos) + timer:start(1.0) + end, + on_timer = function(pos, elapsed) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + if node.name ~= "commoditymarket_fantasy:caravan_post" then + return -- the node was removed + end + local facedir = node.param2 + local dir = minetest.facedir_to_dir(facedir) + local target = vector.add(pos, vector.multiply(dir,3)) + + local target_node = minetest.get_node(target) + + if target_node.name:sub(1,string.len("commoditymarket_fantasy:caravan_market")) == "commoditymarket_fantasy:caravan_market" then + -- It's already here somehow, shut down timer. + meta:set_string("infotext", "") + meta:set_float("wait_time", 0) + return + end + + local is_suitable_space = is_suitable_caravan_space(target, facedir) + + if not is_suitable_space then + meta:set_string("infotext", S("Indicated parking area isn't suitable.\nA 5x3 open space with solid ground\nis required for a caravan.")) + meta:set_float("wait_time", 0) + local timer = minetest.get_node_timer(pos) + timer:start(1.0) + return + end + + local wait_time = (meta:get_float("wait_time") or 0) + elapsed + meta:set_float("wait_time", wait_time) + if wait_time < time_until_caravan then + meta:set_string("infotext", S("Caravan summoned\nETA: @1 seconds.", math.floor(time_until_caravan - wait_time))) + local timer = minetest.get_node_timer(pos) + timer:start(1.0) + return + end + + -- spawn the caravan. We've already established that the target pos is clear. + minetest.set_node(target, {name="commoditymarket_fantasy:caravan_market_"..math.random(1,5), param2=facedir}) + minetest.sound_play("commoditymarket_register_opened", { + pos = target, + gain = 1.0, -- default + max_hear_distance = 32, -- default, uses an euclidean metric + }) + local timer = minetest.get_node_timer(target) + timer:start(dwell_time) + meta:set_string("infotext", "") + meta:set_float("wait_time", 0) + end, +}) +end + +------------------------------------------------------------------------------- +-- "Goblin Exchange" +if minetest.settings:get_bool("commoditymarket_enable_goblin_market", true) then + +local goblin_def = { + description = S("Goblin Exchange"), + long_description = S("One does not usually associate Goblins with the sort of sophistication that running a market requires. Usually one just associates Goblins with savagery and violence. But they understand the principle of tit-for-tat exchange, and if approached correctly they actually respect the concepts of ownership and debt. However, for some peculiar reason they understand this concept in the context of coal lumps. Goblins deal in the standard coal lump as their form of currency, conceptually divided into 100 coal centilumps (though Goblin brokers prefer to \"keep the change\" when giving back actual coal lumps)."), + currency = { + ["default:coal_lump"] = 100 + }, + currency_symbol = "¢", --"\u{00A2}" cent symbol + inventory_limit = 1000, + --sell_limit =, -- no sell limit +} + +commoditymarket.register_market("goblin", goblin_def) + +local goblin_protect = minetest.settings:get_bool("commoditymarket_protect_goblin_market", true) +local on_blast +if goblin_protect then + on_blast = function() end +end + +minetest.register_node("commoditymarket_fantasy:goblin_market", { + description = goblin_def.description, + _doc_items_longdesc = goblin_def.long_description, + _doc_items_usagehelp = usage_help, + tiles = {"default_chest_top.png^(default_coal_block.png^[opacity:128)","default_chest_top.png^(default_coal_block.png^[opacity:128)", + "default_chest_side.png^(default_coal_block.png^[opacity:128)","default_chest_side.png^(default_coal_block.png^[opacity:128)", + "commoditymarket_empty_shelf.png^(default_coal_block.png^[opacity:128)","default_chest_side.png^(default_coal_block.png^[opacity:128)^commoditymarket_goblin.png",}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_wood_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + commoditymarket.show_market("goblin", clicker:get_player_name()) + end, + can_dig = function(pos, player) + return not goblin_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) +end +-------------------------------------------------------------------------------- + +if minetest.settings:get_bool("commoditymarket_enable_under_market", true) then +local undermarket_def = { + description = S("Undermarket"), + long_description = S("Deep in the bowels of the world, below even the goblin-infested warrens and ancient delvings of the dwarves, dark and mysterious beings once dwelt. A few still linger to this day, and facilitate barter for those brave souls willing to travel in their lost realms. The Undermarket uses Mese chips ('â‚¥') as a currency - twenty chips to the Mese fragment. Though traders are loathe to physically break Mese crystals up into units that small, as it renders it useless for other purposes."), + currency = { + ["default:mese"] = 9*9*20, + ["default:mese_crystal"] = 9*20, + ["default:mese_crystal_fragment"] = 20 + }, + currency_symbol = "â‚¥", --"\u{20A5}" mill sign + inventory_limit = 10000, + --sell_limit =, -- no sell limit +} + +commoditymarket.register_market("under", undermarket_def) + +local under_protect = minetest.settings:get_bool("commoditymarket_protect_under_market", true) +local on_blast +if under_protect then + on_blast = function() end +end + +minetest.register_node("commoditymarket_fantasy:under_market", { + description = undermarket_def.description, + _doc_items_longdesc = undermarket_def.long_description, + _doc_items_usagehelp = usage_help, + tiles = {"commoditymarket_under_top.png","commoditymarket_under_top.png", + "commoditymarket_under.png","commoditymarket_under.png","commoditymarket_under.png","commoditymarket_under.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 1,}, + sounds = default.node_sound_stone_defaults(), + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + commoditymarket.show_market("under", clicker:get_player_name()) + end, + can_dig = function(pos, player) + return not under_protect or minetest.check_player_privs(player, "protection_bypass") + end, + on_blast = on_blast, +}) +end +------------------------------------------------------------------ diff --git a/mods/commoditymarket_fantasy/intllib.lua b/mods/commoditymarket_fantasy/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/commoditymarket_fantasy/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/commoditymarket_fantasy/license.txt b/mods/commoditymarket_fantasy/license.txt new file mode 100644 index 0000000..33bee86 --- /dev/null +++ b/mods/commoditymarket_fantasy/license.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 FaceDeer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/commoditymarket_fantasy/locale/commoditymarket_fantasy.ru.tr b/mods/commoditymarket_fantasy/locale/commoditymarket_fantasy.ru.tr new file mode 100644 index 0000000..75a1aa2 --- /dev/null +++ b/mods/commoditymarket_fantasy/locale/commoditymarket_fantasy.ru.tr @@ -0,0 +1,42 @@ +# textdomain: commoditymarket_fantasy + + +### init.lua ### + +A gold ingot is far too valuable to use as a basic unit of value, so it has become common practice to divide the standard gold bar into @1 small disks to make trade easier.=Золотой Ñлиток Ñлишком ценен, чтобы иÑпользовать его в качеÑтве базовой единицы ÑтоимоÑти, поÑтому Ñтало общепринÑтой практикой делить Ñтандартный Ñлиток золота на маленькие диÑки @1, чтобы облегчить торговлю. + +At this time of day the King's Market is closed.=Ð’ Ñто Ð²Ñ€ÐµÐ¼Ñ Ð´Ð½Ñ ÐšÐ¾Ñ€Ð¾Ð»ÐµÐ²Ñкий рынок закрыт. +At this time of day the Night Market is closed.=Ð’ Ñто Ð²Ñ€ÐµÐ¼Ñ Ñуток Ðочной рынок закрыт. +Caravan summoned@nETA: @1 seconds.=Караван вызван! @nETA: @1 Ñек + +Deep in the bowels of the world, below even the goblin-infested warrens and ancient delvings of the dwarves, dark and mysterious beings once dwelt. A few still linger to this day, and facilitate barter for those brave souls willing to travel in their lost realms. The Undermarket uses Mese chips ('â‚¥') as a currency - twenty chips to the Mese fragment. Though traders are loathe to physically break Mese crystals up into units that small, as it renders it useless for other purposes.=Глубоко в недрах мира, еще ниже заражённых гоблинов и древними раÑкопками гномов, когда-то обитали темные и таинÑтвенные ÑущеÑтва. Ðемногие и по Ñей день живут, и предлагают обмен Ð´Ð»Ñ Ñ‚ÐµÑ… беÑÑтрашных храбрецов, которые готовы путешеÑтвовать в затерÑнных мирах. Подземный рынок иÑпользует криÑталл МеÑе в качеÑтве валюты за оÑколок криÑталла МеÑе дают 20 фрагментов МеÑе ('â‚¥'). Торговцы не любÑÑ‚ физичеÑки разбивать оÑколоки криÑталлов Mese на такие маленькие единицы, так как Ñто делает их беÑполезными Ð´Ð»Ñ Ð´Ñ€ÑƒÐ³Ð¸Ñ… целей. + +Goblin Exchange=ГоблинÑкий Обмен +Gold Coins=Золотые монеты + +Gold coins can be deposited and withdrawn from markets that accept them as currency. These markets can make change if you have @1 coins and would like them back in ingot form again.=Золотые монеты можно депонировать и выводить Ñ Ñ€Ñ‹Ð½ÐºÐ¾Ð², принимающих их в качеÑтве валюты. Эти рынки могут изменитьÑÑ, еÑли у Ð²Ð°Ñ ÐµÑÑ‚ÑŒ @1 монета и вы хотите, чтобы они Ñнова были в Ñлитке. + +Indicated parking area isn't suitable.@nA 5x3 open space with solid ground@nis required for a caravan.=Указанное меÑто не подходит! Ðеобходимо@nA 5x3 открытое проÑтранÑтво Ñ Ñ‚Ð²ÐµÑ€Ð´Ñ‹Ð¼ грунтом. + +King's Market=КоролевÑкий рынок +Night Market=Ðочной рынок + +One does not usually associate Goblins with the sort of sophistication that running a market requires. Usually one just associates Goblins with savagery and violence. But they understand the principle of tit-for-tat exchange, and if approached correctly they actually respect the concepts of ownership and debt. However, for some peculiar reason they understand this concept in the context of coal lumps. Goblins deal in the standard coal lump as their form of currency, conceptually divided into 100 coal centilumps (though Goblin brokers prefer to "keep the change" when giving back actual coal lumps).=Обычно Гоблинов не ÑвÑзывают Ñ Ñ‚Ð¾Ð¹ выÑокой тонкоÑтью, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð¿Ñ€Ð¸Ñуща рынку. Чаще вÑего Гоблинов отноÑÑÑ‚ к чиÑлу дикарей и первобытных людей. Ðо они понимают Ñуть обмена "око за око", еÑли к ним отноÑитьÑÑ Ñправедливо, то они реально уважают понÑÑ‚Ð¸Ñ ÑобÑтвенноÑти и долга. Однако по каким-то Ñвоеобразным причинам они понимают Ñто понÑтие в разрезе комочков углÑ. Гоблины имеют дело Ñо Ñтандартным углем как Ñо Ñвоей формой валюты, уÑловно разделенной на 100 коÑарей (правда ГоблинÑкие брокеры предпочитают держать Ñдачу у ÑебÑ, Ð¾Ñ‚Ð´Ð°Ð²Ð°Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ целыми чаÑÑ‚Ñми углÑ). + +Right-click on this to open the market interface.=Кликните правой кнопкой мыши на Ñто, чтобы открыть рыночный интерфейÑ. +Right-click to summon a trader's caravan=Клик правой кнопкой мыши, чтобы вызвать торговый караван + +The largest and most accessible market for the common man, the King's Market uses gold coins as its medium of exchange (or the equivalent in gold ingots - @1 coins to the ingot). However, as a respectable institution of the surface world, the King's Market operates only during the hours of daylight. The purchase and sale of swords and explosives is prohibited in the King's Market. Gold coins are represented by a '☼' symbol.=Крупнейший и наиболее доÑтупный Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñтого человека рынок, КоролевÑкий рынок иÑпользует золотые монеты в качеÑтве ÑредÑтва обмена (или Ñквивалент в золотых Ñлитках - @1 монета к Ñлитку). Однако, как реÑпектабельный инÑтитут поверхноÑтного мира, КоролевÑкий рынок работает только в чаÑÑ‹ дневного Ñвета. КуплÑ-продажа мечей и взрывчатых вещеÑтв на КоролевÑком рынке запрещена. Золотые монеты предÑтавлены Ñимволом "☼". + +The trader's caravan requires a suitable open space next to the trading post for it to arrive, and takes some time to arrive after being summoned. The post gives a countdown to the caravan's arrival when moused over.=Караван трейдера требует подходÑщего открытого проÑтранÑтва Ñ€Ñдом Ñ Ñ‚Ð¾Ñ€Ð³Ð¾Ð²Ñ‹Ð¼ поÑтом, чтобы он прибыл, и занимает некоторое времÑ, чтобы прибыть поÑле вызова. ПоÑÑ‚ дает обратный отÑчет времени до Ð¿Ñ€Ð¸Ð±Ñ‹Ñ‚Ð¸Ñ ÐºÐ°Ñ€Ð°Ð²Ð°Ð½Ð°, когда он оказалÑÑ Ð² канаве. + +This post signals passing caravan traders that customers can be found here, and signals to customers that caravan traders can be found here. If no caravan is present, right-click to summon one.=Этот поÑÑ‚ Ñигнализирует проходÑщим трейдерам каравана, что клиенты могут быть найдены здеÑÑŒ, и Ñигналы Ð´Ð»Ñ ÐºÐ»Ð¸ÐµÐ½Ñ‚Ð¾Ð², что караванные трейдеры могут быть найдены здеÑÑŒ. ЕÑли каравана нет, кликните правой кнопкой мыши, чтобы вызвать караван. + +Trader's Caravan=Караван торговцев +Trading Post=Торговый поÑÑ‚ +Undermarket=Подземный рынок + +Unlike most markets that have well-known fixed locations that travelers congregate to, the network of Trader's Caravans is fluid and dynamic in their locations. A Trader's Caravan can show up anywhere, make modest trades, and then be gone the next time you visit them. These caravans accept gold and gold coins as a currency (one gold ingot to @1 gold coins exchange rate). Any reasonably-wealthy person can create a signpost marking a location where Trader's Caravans will make a stop.=Ð’ отличие от большинÑтва рынков, которые имеют хорошо извеÑтные фикÑированные меÑтоположениÑ, на которые ÑобираютÑÑ Ð¿ÑƒÑ‚ÐµÑˆÐµÑтвенники, Ñеть Караванов трейдеров ÑвлÑетÑÑ Ð³Ð¸Ð±ÐºÐ¾Ð¹ и динамичной в Ñвоем меÑтоположении. Караван трейдера может поÑвитьÑÑ Ð³Ð´Ðµ угодно, Ñовершить Ñкромные Ñделки, а затем уехать в Ñледующий раз, когда вы его поÑетите. Эти караваны принимают золото и золотые монеты в качеÑтве валюты (один Ñлиток золота на @1 обменный ÐºÑƒÑ€Ñ Ð·Ð¾Ð»Ð¾Ñ‚Ñ‹Ñ… монет). Любой доÑтаточно ÑоÑтоÑтельный человек может Ñоздать указатель, обозначающий меÑто, где Караваны трейдера Ñделают оÑтановку. + +When the sun sets and the stalls of the King's Market close, other vendors are just waking up to share their wares. The Night Market is not as voluminous as the King's Market but accepts a wider range of wares. It accepts the same gold coinage of the realm, @1 coins to the gold ingot.=Когда заходит Ñолнце и закрываютÑÑ Ð»Ð°Ñ€ÑŒÐºÐ¸ КоролевÑкого рынка, другие продавцы проÑто проÑыпаютÑÑ, чтобы поделитьÑÑ Ñвоими товарами. Ðочной рынок не такой объемный, как КоролевÑкий, но принимает более широкий аÑÑортимент товаров. Он принимает одну и ту же золотую монету королевÑтва, @1 монету к золотым Ñлиткам. + diff --git a/mods/commoditymarket_fantasy/locale/template.pot b/mods/commoditymarket_fantasy/locale/template.pot new file mode 100644 index 0000000..10af920 --- /dev/null +++ b/mods/commoditymarket_fantasy/locale/template.pot @@ -0,0 +1,155 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-02-13 22:14-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: commoditymarket_fantasy\init.lua:28 +msgid "Gold Coins" +msgstr "" + +#: commoditymarket_fantasy\init.lua:29 +msgid "" +"A gold ingot is far too valuable to use as a basic unit of value, so it has " +"become common practice to divide the standard gold bar into @1 small disks " +"to make trade easier." +msgstr "" + +#: commoditymarket_fantasy\init.lua:30 +msgid "" +"Gold coins can be deposited and withdrawn from markets that accept them as " +"currency. These markets can make change if you have @1 coins and would like " +"them back in ingot form again." +msgstr "" + +#: commoditymarket_fantasy\init.lua:40 +msgid "Right-click on this to open the market interface." +msgstr "" + +#: commoditymarket_fantasy\init.lua:48 +msgid "King's Market" +msgstr "" + +#: commoditymarket_fantasy\init.lua:49 +msgid "" +"The largest and most accessible market for the common man, the King's Market " +"uses gold coins as its medium of exchange (or the equivalent in gold ingots " +"- @1 coins to the ingot). However, as a respectable institution of the " +"surface world, the King's Market operates only during the hours of daylight. " +"The purchase and sale of swords and explosives is prohibited in the King's " +"Market. Gold coins are represented by a '☼' symbol." +msgstr "" + +#: commoditymarket_fantasy\init.lua:92 +msgid "At this time of day the King's Market is closed." +msgstr "" + +#: commoditymarket_fantasy\init.lua:107 +msgid "Night Market" +msgstr "" + +#: commoditymarket_fantasy\init.lua:108 +msgid "" +"When the sun sets and the stalls of the King's Market close, other vendors " +"are just waking up to share their wares. The Night Market is not as " +"voluminous as the King's Market but accepts a wider range of wares. It " +"accepts the same gold coinage of the realm, @1 coins to the gold ingot." +msgstr "" + +#: commoditymarket_fantasy\init.lua:146 +msgid "At this time of day the Night Market is closed." +msgstr "" + +#: commoditymarket_fantasy\init.lua:165 +msgid "Trader's Caravan" +msgstr "" + +#: commoditymarket_fantasy\init.lua:166 +msgid "" +"Unlike most markets that have well-known fixed locations that travelers " +"congregate to, the network of Trader's Caravans is fluid and dynamic in " +"their locations. A Trader's Caravan can show up anywhere, make modest " +"trades, and then be gone the next time you visit them. These caravans accept " +"gold and gold coins as a currency (one gold ingot to @1 gold coins exchange " +"rate). Any reasonably-wealthy person can create a signpost marking a " +"location where Trader's Caravans will make a stop." +msgstr "" + +#: commoditymarket_fantasy\init.lua:236 +msgid "Right-click to summon a trader's caravan" +msgstr "" + +#: commoditymarket_fantasy\init.lua:379 +msgid "Trading Post" +msgstr "" + +#: commoditymarket_fantasy\init.lua:380 +msgid "" +"This post signals passing caravan traders that customers can be found here, " +"and signals to customers that caravan traders can be found here. If no " +"caravan is present, right-click to summon one." +msgstr "" + +#: commoditymarket_fantasy\init.lua:381 +msgid "" +"The trader's caravan requires a suitable open space next to the trading post " +"for it to arrive, and takes some time to arrive after being summoned. The " +"post gives a countdown to the caravan's arrival when moused over." +msgstr "" + +#: commoditymarket_fantasy\init.lua:428 +msgid "" +"Indicated parking area isn't suitable.\n" +"A 5x3 open space with solid ground\n" +"is required for a caravan." +msgstr "" + +#: commoditymarket_fantasy\init.lua:438 +msgid "" +"Caravan summoned\n" +"ETA: @1 seconds." +msgstr "" + +#: commoditymarket_fantasy\init.lua:464 +msgid "Goblin Exchange" +msgstr "" + +#: commoditymarket_fantasy\init.lua:465 +msgid "" +"One does not usually associate Goblins with the sort of sophistication that " +"running a market requires. Usually one just associates Goblins with savagery " +"and violence. But they understand the principle of tit-for-tat exchange, and " +"if approached correctly they actually respect the concepts of ownership and " +"debt. However, for some peculiar reason they understand this concept in the " +"context of coal lumps. Goblins deal in the standard coal lump as their form " +"of currency, conceptually divided into 100 coal centilumps (though Goblin " +"brokers prefer to \"keep the change\" when giving back actual coal lumps)." +msgstr "" + +#: commoditymarket_fantasy\init.lua:506 +msgid "Undermarket" +msgstr "" + +#: commoditymarket_fantasy\init.lua:507 +msgid "" +"Deep in the bowels of the world, below even the goblin-infested warrens and " +"ancient delvings of the dwarves, dark and mysterious beings once dwelled. A " +"few still linger to this day, and facilitate barter for those brave souls " +"willing to travel in their lost realms. The Undermarket uses Mese chips " +"('â‚¥') as a currency - twenty chips to the Mese fragment. Though traders are " +"loathe to physically break Mese crystals up into units that small, as it " +"renders it useless for other purposes." +msgstr "" diff --git a/mods/commoditymarket_fantasy/locale/template.txt b/mods/commoditymarket_fantasy/locale/template.txt new file mode 100644 index 0000000..c7925c2 --- /dev/null +++ b/mods/commoditymarket_fantasy/locale/template.txt @@ -0,0 +1,42 @@ +# textdomain: commoditymarket_fantasy + + +### init.lua ### + +A gold ingot is far too valuable to use as a basic unit of value, so it has become common practice to divide the standard gold bar into @1 small disks to make trade easier.= + +At this time of day the King's Market is closed.= +At this time of day the Night Market is closed.= +Caravan summoned@nETA: @1 seconds.= + +Deep in the bowels of the world, below even the goblin-infested warrens and ancient delvings of the dwarves, dark and mysterious beings once dwelt. A few still linger to this day, and facilitate barter for those brave souls willing to travel in their lost realms. The Undermarket uses Mese chips ('â‚¥') as a currency - twenty chips to the Mese fragment. Though traders are loathe to physically break Mese crystals up into units that small, as it renders it useless for other purposes.= + +Goblin Exchange= +Gold Coins= + +Gold coins can be deposited and withdrawn from markets that accept them as currency. These markets can make change if you have @1 coins and would like them back in ingot form again.= + +Indicated parking area isn't suitable.@nA 5x3 open space with solid ground@nis required for a caravan.= + +King's Market= +Night Market= + +One does not usually associate Goblins with the sort of sophistication that running a market requires. Usually one just associates Goblins with savagery and violence. But they understand the principle of tit-for-tat exchange, and if approached correctly they actually respect the concepts of ownership and debt. However, for some peculiar reason they understand this concept in the context of coal lumps. Goblins deal in the standard coal lump as their form of currency, conceptually divided into 100 coal centilumps (though Goblin brokers prefer to "keep the change" when giving back actual coal lumps).= + +Right-click on this to open the market interface.= +Right-click to summon a trader's caravan= + +The largest and most accessible market for the common man, the King's Market uses gold coins as its medium of exchange (or the equivalent in gold ingots - @1 coins to the ingot). However, as a respectable institution of the surface world, the King's Market operates only during the hours of daylight. The purchase and sale of swords and explosives is prohibited in the King's Market. Gold coins are represented by a '☼' symbol.= + +The trader's caravan requires a suitable open space next to the trading post for it to arrive, and takes some time to arrive after being summoned. The post gives a countdown to the caravan's arrival when moused over.= + +This post signals passing caravan traders that customers can be found here, and signals to customers that caravan traders can be found here. If no caravan is present, right-click to summon one.= + +Trader's Caravan= +Trading Post= +Undermarket= + +Unlike most markets that have well-known fixed locations that travelers congregate to, the network of Trader's Caravans is fluid and dynamic in their locations. A Trader's Caravan can show up anywhere, make modest trades, and then be gone the next time you visit them. These caravans accept gold and gold coins as a currency (one gold ingot to @1 gold coins exchange rate). Any reasonably-wealthy person can create a signpost marking a location where Trader's Caravans will make a stop.= + +When the sun sets and the stalls of the King's Market close, other vendors are just waking up to share their wares. The Night Market is not as voluminous as the King's Market but accepts a wider range of wares. It accepts the same gold coinage of the realm, @1 coins to the gold ingot.= + diff --git a/mods/commoditymarket_fantasy/locale/update.bat b/mods/commoditymarket_fantasy/locale/update.bat new file mode 100644 index 0000000..e87d44c --- /dev/null +++ b/mods/commoditymarket_fantasy/locale/update.bat @@ -0,0 +1,6 @@ +@echo off +setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION +cd .. +set LIST= +for /r %%X in (*.lua) do set LIST=!LIST! %%X +..\intllib\tools\xgettext.bat %LIST% \ No newline at end of file diff --git a/mods/commoditymarket_fantasy/mapgen_dungeon_markets.lua b/mods/commoditymarket_fantasy/mapgen_dungeon_markets.lua new file mode 100644 index 0000000..fb766f2 --- /dev/null +++ b/mods/commoditymarket_fantasy/mapgen_dungeon_markets.lua @@ -0,0 +1,153 @@ +local goblin_enabled = minetest.settings:get_bool("commoditymarket_enable_goblin_market") +local under_enabled = minetest.settings:get_bool("commoditymarket_enable_under_market") +local goblin_prob = tonumber(minetest.settings:get("commoditymarket_goblin_market_dungeon_prob")) or 0.25 +local under_prob = tonumber(minetest.settings:get("commoditymarket_under_market_dungeon_prob")) or 0.1 + +local goblin_max = tonumber(minetest.settings:get("commoditymarket_goblin_market_dungeon_max")) or 100 +local goblin_min = tonumber(minetest.settings:get("commoditymarket_goblin_market_dungeon_min")) or -400 +local under_max = tonumber(minetest.settings:get("commoditymarket_under_market_dungeon_max")) or -500 +local under_min = tonumber(minetest.settings:get("commoditymarket_under_market_dungeon_min")) or -31000 + +local bad_goblin_range = goblin_min >= goblin_max +local bad_under_range = under_min >= under_max + +if bad_goblin_range then + minetest.log("error", "[commoditymarket] Goblin market dungeon generation range has a higher minimum y than maximum y") +end +if bad_under_range then + minetest.log("error", "[commoditymarket] Undermarket dungeon generation range has a higher minimum y than maximum y") +end + +local gen_goblin = goblin_enabled and goblin_prob > 0 and not bad_goblin_range +local gen_under = under_enabled and under_prob > 0 and not bad_under_range + +if not (gen_goblin or gen_under) then + return +end + + +------------------------------------------------------- +-- The following is shamelessly copied from dungeon_loot and tweaked for placing markets instead of chests +--Licensed under the MIT License (MIT) Copyright (C) 2017 sfan5 + +minetest.set_gen_notify({dungeon = true, temple = true}) + +local function noise3d_integer(noise, pos) + return math.abs(math.floor(noise:get_3d(pos) * 0x7fffffff)) +end + +local is_wall = function(node) + return node.name ~= "air" and node.name ~= "ignore" +end + +local function find_walls(cpos) + local dirs = {{x=1, z=0}, {x=-1, z=0}, {x=0, z=1}, {x=0, z=-1}} + local get_node = minetest.get_node + + local ret = {} + local mindist = {x=0, z=0} + local min = function(a, b) return a ~= 0 and math.min(a, b) or b end + for _, dir in ipairs(dirs) do + for i = 1, 9 do -- 9 = max room size / 2 + local pos = vector.add(cpos, {x=dir.x*i, y=0, z=dir.z*i}) + + -- continue in that direction until we find a wall-like node + local node = get_node(pos) + if is_wall(node) then + local front_below = vector.subtract(pos, {x=dir.x, y=1, z=dir.z}) + local above = vector.add(pos, {x=0, y=1, z=0}) + + -- check that it: + --- is at least 2 nodes high (not a staircase) + --- has a floor + if is_wall(get_node(front_below)) and is_wall(get_node(above)) then + pos = vector.subtract(pos, {x=dir.x, y=0, z=dir.z}) -- move goblin markets one node away from the wall + table.insert(ret, {pos = pos, facing = {x=-dir.x, y=0, z=-dir.z}}) + if dir.z == 0 then + mindist.x = min(mindist.x, i-1) + else + mindist.z = min(mindist.z, i-1) + end + end + -- abort even if it wasn't a wall cause something is in the way + break + end + end + end + + return { + walls = ret, + size = {x=mindist.x*2, z=mindist.z*2}, + cpos = cpos, + } +end + +minetest.register_on_generated(function(minp, maxp, blockseed) + local min_y = minp.y + local max_y = maxp.y + + local gen_goblin_range = gen_goblin and not (min_y > goblin_max or max_y < goblin_min) + local gen_under_range = gen_under and not (min_y > under_max or max_y < under_min) + + if not (gen_goblin_range or gen_under_range) then + -- out of both ranges + return + end + + local gennotify = minetest.get_mapgen_object("gennotify") + local poslist = gennotify["dungeon"] or {} + for _, entry in ipairs(gennotify["temple"] or {}) do + table.insert(poslist, entry) + end + if #poslist == 0 then return end + + local noise = minetest.get_perlin(151994, 4, 0.5, 1) + local rand = PcgRandom(noise3d_integer(noise, poslist[1])) + + local rooms = {} + -- process at most 8 rooms to keep runtime of this predictable + local num_process = math.min(#poslist, 8) + for i = 1, num_process do + local room = find_walls(poslist[i]) + -- skip small rooms and everything that doesn't at least have 3 walls + if math.min(room.size.x, room.size.z) >= 4 and #room.walls >= 3 then + table.insert(rooms, room) + end + end + if #rooms == 0 then return end + + if gen_under_range and rand:next(0, 2147483647)/2147483647 < under_prob then + -- choose a random room + local room = rooms[rand:next(1, #rooms)] + local under_loc = room.cpos + + -- put undermarkets in the center of the room + if minetest.get_node(under_loc).name == "air" + and is_wall(vector.subtract(under_loc, {x=0, y=1, z=0})) then + minetest.add_node(under_loc, {name="commoditymarket:under_market"}) + end + end + + if gen_goblin_range and rand:next(0, 2147483647)/2147483647 < goblin_prob then + -- choose a random room + local room = rooms[rand:next(1, #rooms)] + + -- choose place somewhere in front of any of the walls + local wall = room.walls[rand:next(1, #room.walls)] + local v, vi -- vector / axis that runs alongside the wall + if wall.facing.x ~= 0 then + v, vi = {x=0, y=0, z=1}, "z" + else + v, vi = {x=1, y=0, z=0}, "x" + end + local marketpos = vector.add(wall.pos, wall.facing) + local off = rand:next(-room.size[vi]/2 + 1, room.size[vi]/2 - 1) + marketpos = vector.add(marketpos, vector.multiply(v, off)) + + if minetest.get_node(marketpos).name == "air" then + -- make it face inwards to the room + local facedir = minetest.dir_to_facedir(vector.multiply(wall.facing, -1)) + minetest.add_node(marketpos, {name = "commoditymarket:goblin_market", param2 = facedir}) + end + end +end) \ No newline at end of file diff --git a/mods/commoditymarket_fantasy/mod.conf b/mods/commoditymarket_fantasy/mod.conf new file mode 100644 index 0000000..76ad58d --- /dev/null +++ b/mods/commoditymarket_fantasy/mod.conf @@ -0,0 +1,4 @@ +name = commoditymarket_fantasy +description = Adds a number of fantasy-themed marketplaces +depends = commoditymarket, default +optional_depends = doc \ No newline at end of file diff --git a/mods/commoditymarket_fantasy/models/commoditymarket_wagon.obj b/mods/commoditymarket_fantasy/models/commoditymarket_wagon.obj new file mode 100644 index 0000000..333924f --- /dev/null +++ b/mods/commoditymarket_fantasy/models/commoditymarket_wagon.obj @@ -0,0 +1,852 @@ +# Blender v2.79 (sub 0) OBJ File: 'wagon.blend' +# www.blender.org +g Cube.004_Cube.012 +v 0.234629 1.147573 -1.166732 +v -0.234629 1.147573 -1.166732 +v 0.234629 0.678315 -1.166732 +v -0.234629 0.678315 -1.166732 +v 0.731823 1.147573 -0.234629 +v 0.731823 1.147573 0.234629 +v 0.731823 0.678315 -0.234629 +v 0.731823 0.678315 0.234629 +v -0.731823 1.147573 0.234629 +v -0.731823 1.147573 -0.234629 +v -0.731823 0.678315 0.234629 +v -0.731823 0.678315 -0.234629 +v -0.259667 0.016670 1.168107 +v 0.259668 0.016670 1.168107 +v -0.259667 1.170112 1.168107 +v 0.259668 1.170112 1.168107 +vt 0.000000 0.533333 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.533333 +vt -0.000000 0.533333 +vt 1.000000 0.533333 +vt 1.000000 1.000000 +vt -0.000000 1.000000 +vt 0.000000 0.533333 +vt 1.000000 0.533333 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +s off +f 4/1/1 2/2/1 1/3/1 3/4/1 +f 8/5/2 7/6/2 5/7/2 6/8/2 +f 12/9/3 11/10/3 9/11/3 10/12/3 +f 13/13/4 14/14/4 16/15/4 15/16/4 +g Cube.003_Cube.011 +v -0.720902 -0.096672 1.153442 +v -0.720901 -0.096672 -1.153443 +v -0.720902 1.200951 1.153442 +v -0.720902 1.200951 -1.153443 +v -0.509754 1.608755 -1.153443 +v -0.509754 1.608755 1.153443 +v -0.792992 1.200951 -1.268787 +v -0.792992 1.200951 1.268787 +v -0.560730 1.649535 -1.268787 +v -0.560730 1.649535 1.268787 +v -0.726391 1.178882 -1.268787 +v -0.726391 1.178882 1.268787 +v -0.509756 1.608756 -1.268787 +v -0.509756 1.608756 1.268787 +v -0.692620 0.037741 -1.018928 +v -0.692620 0.163735 -1.089024 +v -0.692620 -0.523026 -2.026881 +v -0.692620 -0.397032 -2.096977 +v -0.512394 0.037741 -1.018928 +v -0.512394 0.163735 -1.089024 +v -0.512394 -0.523026 -2.026881 +v -0.512394 -0.397032 -2.096977 +v -0.324406 0.582331 -1.134006 +v -0.324406 0.654421 -1.134006 +v -0.324406 0.582331 -1.441803 +v -0.324406 0.654421 -1.441803 +v 0.720901 -0.096672 -1.153443 +v 0.720902 -0.096672 1.153442 +v -0.000000 1.200951 1.153443 +v 0.720902 1.200951 1.153442 +v -0.000000 1.200951 -1.153443 +v -0.000000 1.777673 -1.153443 +v -0.000000 1.777673 1.153443 +v 0.720902 1.200951 -1.153443 +v 0.509754 1.608755 -1.153443 +v 0.509754 1.608755 1.153443 +v -0.000000 1.835345 1.268787 +v -0.000000 1.835345 -1.268787 +v 0.792992 1.200951 -1.268787 +v 0.792992 1.200951 1.268787 +v 0.560730 1.649535 -1.268787 +v 0.560730 1.649535 1.268787 +v -0.000000 1.777673 1.268787 +v -0.000000 1.777673 -1.268787 +v 0.726391 1.178882 -1.268787 +v 0.726391 1.178882 1.268787 +v 0.509756 1.608756 -1.268787 +v 0.509756 1.608756 1.268787 +v 0.692620 0.037741 -1.018928 +v 0.692620 0.163735 -1.089024 +v 0.692620 -0.523026 -2.026881 +v 0.692620 -0.397032 -2.096977 +v 0.512394 0.037741 -1.018928 +v 0.512394 0.163735 -1.089024 +v 0.512394 -0.523026 -2.026881 +v 0.512394 -0.397032 -2.096977 +v 0.324406 0.582331 -1.134006 +v 0.324406 0.654421 -1.134006 +v 0.324406 0.582331 -1.441803 +v 0.324406 0.654421 -1.441803 +vt -1.425823 3.001615 +vt -1.425823 2.882734 +vt -0.355896 2.882734 +vt -0.355896 3.001615 +vt 0.375155 -3.373241 +vt 0.375155 -2.579424 +vt -3.809447 -2.579426 +vt -3.809447 -3.373241 +vt 0.375154 -1.693858 +vt -3.809447 -1.693859 +vt 0.381165 -0.154615 +vt 4.565710 -0.154608 +vt 4.565710 -0.038908 +vt 0.381165 -0.038908 +vt -0.235621 2.375158 +vt -0.235621 3.208172 +vt -0.341187 3.187105 +vt -0.349886 2.393338 +vt 2.764791 -0.422899 +vt 2.764791 -1.255914 +vt 2.879056 -1.237734 +vt 2.870357 -0.443966 +vt -1.425823 3.804063 +vt -0.451704 3.804062 +vt -0.481619 3.894339 +vt -1.367183 3.894337 +vt -0.451699 3.798052 +vt -1.425823 3.798051 +vt -1.367184 3.707779 +vt -0.481614 3.707775 +vt 2.764791 -2.832267 +vt 2.764791 -3.070028 +vt 4.666879 -3.070028 +vt 4.666879 -2.832265 +vt 2.885066 -1.553966 +vt 2.885066 -1.791727 +vt 3.182267 -1.791727 +vt 3.182267 -1.553966 +vt 4.666881 -2.826254 +vt 4.666881 -2.588493 +vt 2.764791 -2.588493 +vt 2.764791 -2.826255 +vt 3.182267 -1.547955 +vt 3.182267 -1.310194 +vt 2.885066 -1.310194 +vt 2.885066 -1.547955 +vt 1.902838 4.586475 +vt 1.902838 4.883677 +vt 0.000747 4.883678 +vt 0.000747 4.586475 +vt 1.902835 4.283262 +vt 1.902835 4.580463 +vt 0.000747 4.580466 +vt 0.000747 4.283262 +vt 2.764791 -0.298008 +vt 2.764791 -0.416888 +vt 3.272367 -0.416888 +vt 3.272367 -0.298008 +vt -1.425823 2.375158 +vt -0.355896 2.375158 +vt -0.355896 3.509191 +vt -1.425823 3.509191 +vt -3.809448 2.369149 +vt -3.809448 -0.008467 +vt -0.005263 -0.008466 +vt -0.005264 2.369148 +vt 0.375154 -0.014477 +vt -3.809448 -0.014477 +vt -3.809448 -0.808292 +vt 0.375154 -0.808291 +vt 0.381165 -0.160630 +vt 0.381165 -0.276331 +vt 4.565711 -0.276331 +vt 4.565711 -0.160625 +vt 2.764791 -2.094939 +vt 2.879056 -2.076759 +vt 2.870358 -1.282992 +vt 2.764791 -1.261924 +vt -0.115346 3.208172 +vt -0.220912 3.187105 +vt -0.229611 2.393338 +vt -0.115346 2.375158 +vt -0.451703 3.515201 +vt -0.510342 3.605475 +vt -1.395907 3.605478 +vt -1.425823 3.515201 +vt -1.425823 3.701766 +vt -1.395907 3.611488 +vt -0.510338 3.611492 +vt -0.451699 3.701765 +vt 2.764791 -2.338711 +vt 4.666883 -2.338711 +vt 4.666883 -2.100949 +vt 2.764791 -2.100949 +vt 3.122827 -2.094939 +vt 3.122827 -1.797738 +vt 2.885066 -1.797738 +vt 2.885066 -2.094939 +vt 4.666883 -2.344721 +vt 2.764791 -2.344721 +vt 2.764791 -2.582482 +vt 4.666883 -2.582483 +vt -0.349886 3.214182 +vt -0.052684 3.214182 +vt -0.052684 3.451943 +vt -0.349886 3.451943 +vt 4.666882 -3.076038 +vt 2.764791 -3.076038 +vt 2.764791 -3.373240 +vt 4.666883 -3.373241 +vt 3.810932 4.580466 +vt 1.908845 4.580463 +vt 1.908845 4.283263 +vt 3.810934 4.283262 +vt 2.885066 -1.304184 +vt 3.392642 -1.304184 +vt 3.392642 -1.185303 +vt 2.885066 -1.185303 +vt 0.061193 0.029274 +vt 2.438806 0.029274 +vt 2.438807 2.169126 +vt 1.250000 2.169127 +vt 0.061193 2.169127 +vt 2.438741 0.029448 +vt 2.438741 2.169301 +vt 6.242925 2.169302 +vt 6.242926 0.029448 +vt 2.090614 2.841618 +vt 1.250000 2.169127 +vt 0.409386 2.841618 +vt 0.061192 2.169127 +vt 1.250000 3.120173 +vt 1.250000 3.120173 +vt 2.438532 0.029230 +vt 6.242717 0.029228 +vt 6.242717 2.169081 +vt 2.438534 2.169083 +vt 0.409386 2.841618 +vt 2.438807 2.169127 +vt 2.090614 2.841617 +vt 0.061193 0.029273 +vt 2.438807 0.029273 +vn 0.0000 0.0000 -1.0000 +vn 0.8930 -0.4500 -0.0000 +vn 0.3145 -0.9492 0.0000 +vn -0.3145 -0.9492 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -0.4862 -0.8739 +vn 1.0000 -0.0000 0.0000 +vn 0.0000 0.4862 0.8739 +vn 0.0000 -0.8739 0.4862 +vn 0.0000 0.8739 -0.4862 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn -0.8930 -0.4500 -0.0000 +s off +f 41/17/5 42/18/5 76/19/5 75/20/5 +f 27/21/6 29/22/6 30/23/6 28/24/6 +f 29/22/7 60/25/7 59/26/7 30/23/7 +f 24/27/8 23/28/8 27/29/8 28/30/8 +f 23/31/5 25/32/5 29/33/5 27/34/5 +f 26/35/9 24/36/9 28/37/9 30/38/9 +f 25/39/5 54/40/5 60/41/5 29/42/5 +f 53/43/9 26/44/9 30/45/9 59/46/9 +f 31/47/10 32/48/10 34/49/10 33/50/10 +f 33/51/11 34/52/11 38/53/11 37/54/11 +f 37/55/12 38/56/12 36/57/12 35/58/12 +f 35/59/13 36/60/13 32/61/13 31/62/13 +f 33/63/14 37/64/14 35/65/14 31/66/14 +f 38/67/15 34/68/15 32/69/15 36/70/15 +f 39/71/10 40/72/10 42/73/10 41/74/10 +f 76/19/16 42/18/16 40/75/16 74/76/16 +f 41/17/17 75/20/17 73/77/17 39/78/17 +f 44/79/17 17/80/17 18/81/17 43/82/17 +f 61/83/18 62/84/18 64/85/18 63/86/18 +f 63/86/8 64/85/8 59/26/8 60/25/8 +f 56/87/7 62/88/7 61/89/7 55/90/7 +f 55/91/5 61/92/5 63/93/5 57/94/5 +f 58/95/9 64/96/9 62/97/9 56/98/9 +f 57/99/5 63/100/5 60/101/5 54/102/5 +f 53/103/9 59/104/9 64/105/9 58/106/9 +f 65/107/12 67/108/12 68/109/12 66/110/12 +f 67/111/11 71/112/11 72/113/11 68/114/11 +f 71/115/10 69/116/10 70/117/10 72/118/10 +f 69/119/13 65/120/13 66/121/13 70/122/13 +f 67/123/14 65/124/14 69/125/14 71/126/14 +f 72/127/15 70/128/15 66/129/15 68/130/15 +f 73/131/12 75/132/12 76/133/12 74/134/12 +f 43/135/5 18/136/5 20/137/5 47/138/5 50/139/5 +f 17/140/10 19/141/10 20/142/10 18/143/10 +f 47/138/5 20/137/5 21/144/5 +f 45/145/9 22/146/9 19/147/9 +f 47/138/5 21/144/5 48/148/5 +f 45/145/9 49/149/9 22/146/9 +f 44/150/12 43/151/12 50/152/12 46/153/12 +f 47/138/5 51/154/5 50/139/5 +f 45/145/9 46/155/9 52/156/9 +f 47/138/5 48/148/5 51/154/5 +f 45/145/9 52/156/9 49/149/9 +f 45/145/9 19/147/9 17/157/9 44/158/9 46/155/9 +g Cube.002_Cube.010 +v -0.901127 0.047509 -0.576721 +v -0.720902 0.047509 -0.576721 +v -0.901127 0.268210 -1.109542 +v -0.720902 0.268210 -1.109542 +v -0.901127 -0.173193 -1.109542 +v -0.720902 -0.173193 -1.109542 +v -0.901127 -0.485312 -0.797423 +v -0.720902 -0.485312 -0.797423 +v -0.901127 -0.485312 -0.356020 +v -0.720902 -0.485312 -0.356020 +v -0.901127 -0.173193 -0.043900 +v -0.720902 -0.173193 -0.043900 +v -0.901127 0.268210 -0.043900 +v -0.720902 0.268210 -0.043900 +v -0.901127 0.580330 -0.356020 +v -0.720902 0.580330 -0.356020 +v -0.901127 0.580330 -0.797423 +v -0.720902 0.580330 -0.797423 +v -0.901127 0.047509 0.576721 +v -0.720902 0.047509 0.576721 +v -0.901127 0.268210 0.043900 +v -0.720902 0.268210 0.043900 +v -0.901127 -0.173193 0.043900 +v -0.720902 -0.173193 0.043900 +v -0.901127 -0.485312 0.356020 +v -0.720902 -0.485312 0.356020 +v -0.901127 -0.485312 0.797423 +v -0.720902 -0.485312 0.797423 +v -0.901127 -0.173193 1.109542 +v -0.720902 -0.173193 1.109542 +v -0.901127 0.268210 1.109542 +v -0.720902 0.268210 1.109542 +v -0.901127 0.580330 0.797423 +v -0.720902 0.580330 0.797423 +v -0.901127 0.580330 0.356020 +v -0.720902 0.580330 0.356020 +v 0.901127 0.047509 -0.576721 +v 0.720902 0.047509 -0.576721 +v 0.901127 0.268210 -1.109542 +v 0.720902 0.268210 -1.109542 +v 0.901127 -0.173193 -1.109542 +v 0.720902 -0.173193 -1.109542 +v 0.901127 -0.485312 -0.797423 +v 0.720902 -0.485312 -0.797423 +v 0.901127 -0.485312 -0.356020 +v 0.720902 -0.485312 -0.356020 +v 0.901127 -0.173193 -0.043900 +v 0.720902 -0.173193 -0.043900 +v 0.901127 0.268210 -0.043900 +v 0.720902 0.268210 -0.043900 +v 0.901127 0.580330 -0.356020 +v 0.720902 0.580330 -0.356020 +v 0.901127 0.580330 -0.797423 +v 0.720902 0.580330 -0.797423 +v 0.901127 0.047509 0.576721 +v 0.720902 0.047509 0.576721 +v 0.901127 0.268210 0.043900 +v 0.720902 0.268210 0.043900 +v 0.901127 -0.173193 0.043900 +v 0.720902 -0.173193 0.043900 +v 0.901127 -0.485312 0.356020 +v 0.720902 -0.485312 0.356020 +v 0.901127 -0.485312 0.797423 +v 0.720902 -0.485312 0.797423 +v 0.901127 -0.173193 1.109542 +v 0.720902 -0.173193 1.109542 +v 0.901127 0.268210 1.109542 +v 0.720902 0.268210 1.109542 +v 0.901127 0.580330 0.797423 +v 0.720902 0.580330 0.797423 +v 0.901127 0.580330 0.356020 +v 0.720902 0.580330 0.356020 +vt 0.499873 0.992213 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.499873 0.992213 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.499873 0.992213 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.499873 0.992213 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.499873 0.992213 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.499873 0.992213 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.499873 0.992213 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.499873 0.992213 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vt 0.085485 -0.008208 +vt 0.914261 -0.008208 +vt 0.914261 -0.008208 +vt 0.085485 -0.008208 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 0.0000 +s off +f 77/159/19 79/160/19 81/161/19 +f 78/162/20 82/163/20 80/164/20 +f 77/159/19 81/165/19 83/166/19 +f 78/162/20 84/167/20 82/168/20 +f 77/159/19 83/169/19 85/170/19 +f 78/162/20 86/171/20 84/172/20 +f 77/159/19 85/173/19 87/174/19 +f 78/162/20 88/175/20 86/176/20 +f 77/159/19 87/177/19 89/178/19 +f 78/162/20 90/179/20 88/180/20 +f 77/159/19 89/181/19 91/182/19 +f 78/162/20 92/183/20 90/184/20 +f 77/159/19 91/185/19 93/186/19 +f 78/162/20 94/187/20 92/188/20 +f 77/159/19 93/189/19 79/190/19 +f 78/162/20 80/191/20 94/192/20 +f 95/193/19 97/194/19 99/195/19 +f 96/196/20 100/197/20 98/198/20 +f 95/193/19 99/199/19 101/200/19 +f 96/196/20 102/201/20 100/202/20 +f 95/193/19 101/203/19 103/204/19 +f 96/196/20 104/205/20 102/206/20 +f 95/193/19 103/207/19 105/208/19 +f 96/196/20 106/209/20 104/210/20 +f 95/193/19 105/211/19 107/212/19 +f 96/196/20 108/213/20 106/214/20 +f 95/193/19 107/215/19 109/216/19 +f 96/196/20 110/217/20 108/218/20 +f 95/193/19 109/219/19 111/220/19 +f 96/196/20 112/221/20 110/222/20 +f 95/193/19 111/223/19 97/224/19 +f 96/196/20 98/225/20 112/226/20 +f 113/227/20 117/228/20 115/229/20 +f 114/230/19 116/231/19 118/232/19 +f 113/227/20 119/233/20 117/234/20 +f 114/230/19 118/235/19 120/236/19 +f 113/227/20 121/237/20 119/238/20 +f 114/230/19 120/239/19 122/240/19 +f 113/227/20 123/241/20 121/242/20 +f 114/230/19 122/243/19 124/244/19 +f 113/227/20 125/245/20 123/246/20 +f 114/230/19 124/247/19 126/248/19 +f 113/227/20 127/249/20 125/250/20 +f 114/230/19 126/251/19 128/252/19 +f 113/227/20 129/253/20 127/254/20 +f 114/230/19 128/255/19 130/256/19 +f 113/227/20 115/257/20 129/258/20 +f 114/230/19 130/259/19 116/260/19 +f 131/261/20 135/262/20 133/263/20 +f 132/264/19 134/265/19 136/266/19 +f 131/261/20 137/267/20 135/268/20 +f 132/264/19 136/269/19 138/270/19 +f 131/261/20 139/271/20 137/272/20 +f 132/264/19 138/273/19 140/274/19 +f 131/261/20 141/275/20 139/276/20 +f 132/264/19 140/277/19 142/278/19 +f 131/261/20 143/279/20 141/280/20 +f 132/264/19 142/281/19 144/282/19 +f 131/261/20 145/283/20 143/284/20 +f 132/264/19 144/285/19 146/286/19 +f 131/261/20 147/287/20 145/288/20 +f 132/264/19 146/289/19 148/290/19 +f 131/261/20 133/291/20 147/292/20 +f 132/264/19 148/293/19 134/294/19 +g Cube.001_Cube.009 +v -0.901127 0.268210 -1.109542 +v -0.720902 0.268210 -1.109542 +v -0.901127 -0.173193 -1.109542 +v -0.720902 -0.173193 -1.109542 +v -0.901127 -0.485312 -0.797423 +v -0.720902 -0.485312 -0.797423 +v -0.901127 -0.485312 -0.356020 +v -0.720902 -0.485312 -0.356020 +v -0.901127 -0.173193 -0.043900 +v -0.720902 -0.173193 -0.043900 +v -0.901127 0.268210 -0.043900 +v -0.720902 0.268210 -0.043900 +v -0.901127 0.580330 -0.356020 +v -0.720902 0.580330 -0.356020 +v -0.901127 0.580330 -0.797423 +v -0.720902 0.580330 -0.797423 +v -0.901127 0.268210 0.043900 +v -0.720902 0.268210 0.043900 +v -0.901127 -0.173193 0.043900 +v -0.720902 -0.173193 0.043900 +v -0.901127 -0.485312 0.356020 +v -0.720902 -0.485312 0.356020 +v -0.901127 -0.485312 0.797423 +v -0.720902 -0.485312 0.797423 +v -0.901127 -0.173193 1.109542 +v -0.720902 -0.173193 1.109542 +v -0.901127 0.268210 1.109542 +v -0.720902 0.268210 1.109542 +v -0.901127 0.580330 0.797423 +v -0.720902 0.580330 0.797423 +v -0.901127 0.580330 0.356020 +v -0.720902 0.580330 0.356020 +v 0.901127 0.268210 -1.109542 +v 0.720902 0.268210 -1.109542 +v 0.901127 -0.173193 -1.109542 +v 0.720902 -0.173193 -1.109542 +v 0.901127 -0.485312 -0.797423 +v 0.720902 -0.485312 -0.797423 +v 0.901127 -0.485312 -0.356020 +v 0.720902 -0.485312 -0.356020 +v 0.901127 -0.173193 -0.043900 +v 0.720902 -0.173193 -0.043900 +v 0.901127 0.268210 -0.043900 +v 0.720902 0.268210 -0.043900 +v 0.901127 0.580330 -0.356020 +v 0.720902 0.580330 -0.356020 +v 0.901127 0.580330 -0.797423 +v 0.720902 0.580330 -0.797423 +v 0.901127 0.268210 0.043900 +v 0.720902 0.268210 0.043900 +v 0.901127 -0.173193 0.043900 +v 0.720902 -0.173193 0.043900 +v 0.901127 -0.485312 0.356020 +v 0.720902 -0.485312 0.356020 +v 0.901127 -0.485312 0.797423 +v 0.720902 -0.485312 0.797423 +v 0.901127 -0.173193 1.109542 +v 0.720902 -0.173193 1.109542 +v 0.901127 0.268210 1.109542 +v 0.720902 0.268210 1.109542 +v 0.901127 0.580330 0.797423 +v 0.720902 0.580330 0.797423 +v 0.901127 0.580330 0.356020 +v 0.720902 0.580330 0.356020 +vt 0.279164 0.493799 +vt 0.072560 0.493799 +vt 0.072560 -0.012210 +vt 0.279164 -0.012210 +vt 0.072559 -0.518219 +vt 0.279163 -0.518219 +vt 0.072559 -1.024229 +vt 0.279163 -1.024229 +vt 0.072559 -1.530238 +vt 0.279163 -1.530238 +vt 0.279165 2.517837 +vt 0.072561 2.517837 +vt 0.072561 2.011827 +vt 0.279165 2.011827 +vt 0.072561 1.505818 +vt 0.279165 1.505818 +vt 0.072560 0.999809 +vt 0.279165 0.999809 +vt 0.694571 2.011827 +vt 0.901175 2.011827 +vt 0.901175 2.517837 +vt 0.694571 2.517837 +vt 0.694571 -1.530238 +vt 0.901175 -1.530238 +vt 0.901175 -1.024228 +vt 0.694571 -1.024228 +vt 0.901175 -0.518219 +vt 0.694571 -0.518219 +vt 0.901175 -0.012210 +vt 0.694571 -0.012210 +vt 0.901174 0.493799 +vt 0.694570 0.493799 +vt 0.901174 0.999809 +vt 0.694570 0.999809 +vt 0.901175 1.505817 +vt 0.694570 1.505818 +vt 0.279897 0.493799 +vt 0.279898 -0.012210 +vt 0.486502 -0.012210 +vt 0.486501 0.493799 +vt 0.279898 -0.518219 +vt 0.486502 -0.518219 +vt 0.279898 -1.024228 +vt 0.486502 -1.024229 +vt 0.279898 -1.530238 +vt 0.486502 -1.530238 +vt 0.279897 2.517837 +vt 0.279897 2.011827 +vt 0.486501 2.011827 +vt 0.486501 2.517837 +vt 0.279897 1.505818 +vt 0.486501 1.505818 +vt 0.279897 0.999809 +vt 0.486501 0.999809 +vt 0.693838 2.011827 +vt 0.693838 2.517837 +vt 0.487234 2.517837 +vt 0.487234 2.011827 +vt 0.693839 -1.530238 +vt 0.693838 -1.024229 +vt 0.487234 -1.024229 +vt 0.487234 -1.530238 +vt 0.693838 -0.518220 +vt 0.487234 -0.518220 +vt 0.693838 -0.012210 +vt 0.487234 -0.012210 +vt 0.693838 0.493800 +vt 0.487234 0.493800 +vt 0.693838 0.999809 +vt 0.487234 0.999809 +vt 0.693838 1.505818 +vt 0.487234 1.505818 +vn 0.0000 0.0000 -1.0000 +vn -0.0000 -0.7071 -0.7071 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 -0.7071 0.7071 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.7071 0.7071 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.7071 -0.7071 +s off +f 149/295/21 150/296/21 152/297/21 151/298/21 +f 151/298/22 152/297/22 154/299/22 153/300/22 +f 153/300/23 154/299/23 156/301/23 155/302/23 +f 155/302/24 156/301/24 158/303/24 157/304/24 +f 157/305/25 158/306/25 160/307/25 159/308/25 +f 159/308/26 160/307/26 162/309/26 161/310/26 +f 161/310/27 162/309/27 164/311/27 163/312/27 +f 163/312/28 164/311/28 150/296/28 149/295/28 +f 165/313/21 166/314/21 168/315/21 167/316/21 +f 167/317/22 168/318/22 170/319/22 169/320/22 +f 169/320/23 170/319/23 172/321/23 171/322/23 +f 171/322/24 172/321/24 174/323/24 173/324/24 +f 173/324/25 174/323/25 176/325/25 175/326/25 +f 175/326/26 176/325/26 178/327/26 177/328/26 +f 177/328/27 178/327/27 180/329/27 179/330/27 +f 179/330/28 180/329/28 166/314/28 165/313/28 +f 181/331/21 183/332/21 184/333/21 182/334/21 +f 183/332/22 185/335/22 186/336/22 184/333/22 +f 185/335/23 187/337/23 188/338/23 186/336/23 +f 187/337/24 189/339/24 190/340/24 188/338/24 +f 189/341/25 191/342/25 192/343/25 190/344/25 +f 191/342/26 193/345/26 194/346/26 192/343/26 +f 193/345/27 195/347/27 196/348/27 194/346/27 +f 195/347/28 181/331/28 182/334/28 196/348/28 +f 197/349/21 199/350/21 200/351/21 198/352/21 +f 199/353/22 201/354/22 202/355/22 200/356/22 +f 201/354/23 203/357/23 204/358/23 202/355/23 +f 203/357/24 205/359/24 206/360/24 204/358/24 +f 205/359/25 207/361/25 208/362/25 206/360/25 +f 207/361/26 209/363/26 210/364/26 208/362/26 +f 209/363/27 211/365/27 212/366/27 210/364/27 +f 211/365/28 197/349/28 198/352/28 212/366/28 +g Cube.000_Cube.008 +v -0.792992 1.200951 -1.268787 +v -0.792992 1.200951 1.268787 +v -0.560730 1.649535 -1.268787 +v -0.560730 1.649535 1.268787 +v -0.000000 1.835345 1.268787 +v -0.000000 1.835345 -1.268787 +v 0.792992 1.200951 -1.268787 +v 0.792992 1.200951 1.268787 +v 0.560730 1.649535 -1.268787 +v 0.560730 1.649535 1.268787 +vt 3.173871 2.353881 +vt -2.391578 2.353881 +vt -2.391578 1.288979 +vt 3.173871 1.288979 +vt -2.391578 0.224077 +vt 3.173871 0.224077 +vt 3.173871 -1.905729 +vt 3.173871 -0.840826 +vt -2.391578 -0.840826 +vt -2.391578 -1.905728 +vn -0.8880 0.4598 0.0000 +vn -0.3146 0.9492 0.0000 +vn 0.8880 0.4598 0.0000 +vn 0.3146 0.9492 0.0000 +s off +f 213/367/29 214/368/29 216/369/29 215/370/29 +f 215/370/30 216/369/30 217/371/30 218/372/30 +f 219/373/31 221/374/31 222/375/31 220/376/31 +f 221/374/32 218/372/32 217/371/32 222/375/32 +g Cube.006_Cube.007 +v -0.722861 -0.094866 1.158711 +v -0.722861 1.240430 1.158711 +v -0.722861 -0.094866 1.059710 +v -0.722861 1.240430 1.059710 +v -0.623860 -0.094866 1.158711 +v -0.623860 1.240430 1.158711 +v -0.725927 -0.094866 -1.158643 +v -0.725927 1.240430 -1.158643 +v -0.725927 -0.094866 -1.059642 +v -0.725927 1.240430 -1.059642 +v -0.626926 -0.094866 -1.158643 +v -0.626926 1.240430 -1.158643 +v 0.722861 -0.094866 1.158711 +v 0.722861 1.240430 1.158711 +v 0.722861 -0.094866 1.059710 +v 0.722861 1.240430 1.059710 +v 0.623860 -0.094866 1.158711 +v 0.623860 1.240430 1.158711 +v 0.725927 -0.094866 -1.158643 +v 0.725927 1.240430 -1.158643 +v 0.725927 -0.094866 -1.059642 +v 0.725927 1.240430 -1.059642 +v 0.626926 -0.094866 -1.158643 +v 0.626926 1.240430 -1.158643 +vt -0.339657 0.628705 +vt 1.340090 0.628704 +vt 1.340090 0.753243 +vt -0.339657 0.753243 +vt -0.339658 0.504167 +vt 1.340090 0.504165 +vt -0.339657 0.129512 +vt -0.339657 0.004973 +vt 1.340090 0.004973 +vt 1.340090 0.129512 +vt -0.339657 0.254051 +vt 1.340090 0.254050 +vt -0.339658 0.878300 +vt -0.339658 0.753761 +vt 1.340090 0.753762 +vt 1.340090 0.878300 +vt -0.339657 1.002839 +vt 1.340090 1.002838 +vt -0.339657 0.379109 +vt 1.340090 0.379108 +vt 1.340090 0.503647 +vt -0.339657 0.503647 +vt -0.339658 0.254571 +vt 1.340090 0.254569 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +s off +f 223/377/33 224/378/33 226/379/33 225/380/33 +f 227/381/34 228/382/34 224/378/34 223/377/34 +f 229/383/33 231/384/33 232/385/33 230/386/33 +f 233/387/35 229/383/35 230/386/35 234/388/35 +f 235/389/36 237/390/36 238/391/36 236/392/36 +f 239/393/34 235/389/34 236/392/34 240/394/34 +f 241/395/36 242/396/36 244/397/36 243/398/36 +f 245/399/35 246/400/35 242/396/35 241/395/35 diff --git a/mods/commoditymarket_fantasy/models/license.txt b/mods/commoditymarket_fantasy/models/license.txt new file mode 100644 index 0000000..4c4e9f7 --- /dev/null +++ b/mods/commoditymarket_fantasy/models/license.txt @@ -0,0 +1 @@ +commoditymarket_wagon.obj was created by FaceDeer and is released under the Creative Commons CC0 license. \ No newline at end of file diff --git a/mods/commoditymarket_fantasy/readme.md b/mods/commoditymarket_fantasy/readme.md new file mode 100644 index 0000000..8d4d68a --- /dev/null +++ b/mods/commoditymarket_fantasy/readme.md @@ -0,0 +1,15 @@ +This mod depends on [commoditymarket](https://github.com/FaceDeer/commoditymarket). It implements a number of fantasy-themed marketplaces where players can post buy and sell offers for various items, allowing for organic market forces to determine the relative values of the resources in a world. + +* King's Market - a basic sort of "commoner's marketplace", only open during the day +* Night Market - the shadier side of commerce, only open during the night +* Trader's Caravan - a type of market that players can build and place themselves, with a small inventory capacity. +* Goblin Exchange - a strange marketplace that uses coal as a currency +* Undermarket - where dark powers make their trades, using Mese as a currency + +![](screenshot.jpg) + +All of these except for the Trader's Caravan are intended to be placed in specific locations by server administrators, they don't have crafting recipes. + +An option exists to allow Goblin markets and Undermarkets to be automatically placed inside dungeons by world gen. + +The [settlements](https://github.com/FaceDeer/settlements) mod scatters small settlements around on the surface of the world that can contain King's Markets and Night Markets. diff --git a/mods/commoditymarket_fantasy/settingtypes.txt b/mods/commoditymarket_fantasy/settingtypes.txt new file mode 100644 index 0000000..8fb49e0 --- /dev/null +++ b/mods/commoditymarket_fantasy/settingtypes.txt @@ -0,0 +1,24 @@ +[Enable default markets] +commoditymarket_enable_kings_market (Enable King's Market) bool true +commoditymarket_enable_night_market (Enable Night Market) bool true +commoditymarket_enable_caravan_market (Enable Trader's Caravan) bool true +commoditymarket_enable_goblin_market (Enable Goblin Exchange) bool true +commoditymarket_enable_under_market (Enable Undermarket) bool true + +[Market node protection] +commoditymarket_protect_kings_market (Protect King's Market node) bool true +commoditymarket_protect_night_market (Protect Night Market node) bool true +commoditymarket_protect_caravan_market (Protect permanent Caravan node) bool true +commoditymarket_protect_goblin_market (Protect Goblin Market node) bool true +commoditymarket_protect_under_market (Protect Undermarket node) bool true + +[Currency denominations] +commoditymarket_coins_per_ingot (Coins per ingot) int 1000 + +[Dungeon market generation] +commoditymarket_goblin_market_dungeon_prob (Goblin market probability per dungeon mapblock) float 0.25 0 1 +commoditymarket_goblin_market_dungeon_max (Upper y limit of goblin markets) int 100 +commoditymarket_goblin_market_dungeon_min (Lower y limit of goblin markets) int -400 +commoditymarket_under_market_dungeon_prob (Undermarket probability per dungeon mapblock) float 0.1 0 1 +commoditymarket_under_market_dungeon_max (Upper y limit of undermarkets) int -500 +commoditymarket_under_market_dungeon_min (Lower y limit of undermarkets) int -31000 diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_caravan_sign.png b/mods/commoditymarket_fantasy/textures/commoditymarket_caravan_sign.png new file mode 100644 index 0000000..cbf3810 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_caravan_sign.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_caravan_sign_inventory.png b/mods/commoditymarket_fantasy/textures/commoditymarket_caravan_sign_inventory.png new file mode 100644 index 0000000..ba7db6a Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_caravan_sign_inventory.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_crown.png b/mods/commoditymarket_fantasy/textures/commoditymarket_crown.png new file mode 100644 index 0000000..2df1148 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_crown.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_door_wood.png b/mods/commoditymarket_fantasy/textures/commoditymarket_door_wood.png new file mode 100644 index 0000000..ae70bda Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_door_wood.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_empty_shelf.png b/mods/commoditymarket_fantasy/textures/commoditymarket_empty_shelf.png new file mode 100644 index 0000000..404fc8b Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_empty_shelf.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_goblin.png b/mods/commoditymarket_fantasy/textures/commoditymarket_goblin.png new file mode 100644 index 0000000..b167d22 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_goblin.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_gold_coins.png b/mods/commoditymarket_fantasy/textures/commoditymarket_gold_coins.png new file mode 100644 index 0000000..73f4e83 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_gold_coins.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_moon.png b/mods/commoditymarket_fantasy/textures/commoditymarket_moon.png new file mode 100644 index 0000000..7341050 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_moon.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_shingles_wood.png b/mods/commoditymarket_fantasy/textures/commoditymarket_shingles_wood.png new file mode 100644 index 0000000..ee59df8 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_shingles_wood.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_sign.png b/mods/commoditymarket_fantasy/textures/commoditymarket_sign.png new file mode 100644 index 0000000..fcdd409 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_sign.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_sign_post.png b/mods/commoditymarket_fantasy/textures/commoditymarket_sign_post.png new file mode 100644 index 0000000..7181397 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_sign_post.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_trade.png b/mods/commoditymarket_fantasy/textures/commoditymarket_trade.png new file mode 100644 index 0000000..b6401b0 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_trade.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_under.png b/mods/commoditymarket_fantasy/textures/commoditymarket_under.png new file mode 100644 index 0000000..007be31 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_under.png differ diff --git a/mods/commoditymarket_fantasy/textures/commoditymarket_under_top.png b/mods/commoditymarket_fantasy/textures/commoditymarket_under_top.png new file mode 100644 index 0000000..22a1bb1 Binary files /dev/null and b/mods/commoditymarket_fantasy/textures/commoditymarket_under_top.png differ diff --git a/mods/commoditymarket_fantasy/textures/license.txt b/mods/commoditymarket_fantasy/textures/license.txt new file mode 100644 index 0000000..fe40409 --- /dev/null +++ b/mods/commoditymarket_fantasy/textures/license.txt @@ -0,0 +1,11 @@ +commoditymarket_gold_coins.png - from https://commons.wikimedia.org/wiki/File:Farm-Fresh_coins.png, by FatCow under the CC-BY 3.0 license +commoditymarket_crown.png - from https://commons.wikimedia.org/wiki/File:Farm-Fresh_crown_gold.png by FatCow under the CC-BY 3.0 Unported license +commoditymarket_moon.png - from https://commons.wikimedia.org/wiki/File:Luneta08.svg by Arturo D. Castillo —Zoram.hakaan— under the CC-BY 3.0 Unported license +commoditymarket_goblin.png - cropped from the "goblins" mod, Copyright 2015 by Francisco "FreeLikeGNU" Athens Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +commoditymarket_empty_shelf.png - from the moreblocks mod's "moreblocks_empty_shelf", under the zlib license by Hugo Locurcio and contributors +commoditymarket_shingles_wood.png is cottages_homedecor_shingles_wood.png from the cottages mod by VanessaE (CC-by-SA 3.0) + +commoditymarket_trade.png, commoditymarket_trade_flag.png, commoditymarket_under.png, and commoditymarket_under_top were created by FaceDeer and released under the CC0 public domain license + +commoditymarket_sign_post.png and commoditymarket_sign.png are made from elements of default_tree.png and default_aspen_wood.png +commoditymarket_door_wood.png is doors_door_wood.png from the doors mod \ No newline at end of file diff --git a/mods/compost/README.md b/mods/compost/README.md new file mode 100644 index 0000000..7abf0e3 --- /dev/null +++ b/mods/compost/README.md @@ -0,0 +1,22 @@ +# Compost Mod +This mod allows you to compost grass, leaves, flowers... + +## License +see LICENSE.txt + +## Crafting +Wood barrel: + +| W | | W | +|---|---|---| +| W | | W | +| W | S | W | + +W : wood +S : wood slab + +## Bugs +Report bugs on the forum topic or open a issue on GitHub. + +## Created by +cdqwertz - cdqwertz.github.io diff --git a/mods/compost/init.lua b/mods/compost/init.lua new file mode 100644 index 0000000..f9456cd --- /dev/null +++ b/mods/compost/init.lua @@ -0,0 +1,233 @@ +compost = {} +compost.items = {} +compost.groups = {} + +function compost.register_item(name) + compost.items[name] = true +end + +function compost.register_group(name) + compost.groups[name] = true +end + +function compost.can_compost(name) + if compost.items[name] then + return true + else + for k, i in pairs(minetest.registered_items[name].groups) do + if i > 0 then + if compost.groups[tostring(k)] then + return true + end + end + end + + return false + end +end + +-- grass +compost.register_item("default:grass_1") +compost.register_item("default:junglegrass") + +-- leaves +compost.register_group("leaves") + +-- dirt +compost.register_item("default:dirt") +compost.register_item("default:dirt_with_grass") + +-- stick +compost.register_item("default:stick") + +-- flowers +compost.register_item("flowers:geranium") +compost.register_item("flowers:tulip") +compost.register_item("flowers:rose") +compost.register_item("flowers:dandelion_yellow") +compost.register_item("flowers:dandelion_white") + +-- food +compost.register_item("farming:bread") +compost.register_item("farming:wheat") + +-- groups +compost.register_group("plant") +compost.register_group("flower") + +minetest.register_node("compost:wood_barrel", { + description = "Wood Barrel", + tiles = {"default_wood.png"}, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/2, 1/2, -3/8, 1/2}, + {-1/2, -1/2, -1/2, -3/8, 1/2, 1/2}, + {3/8, -1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, 1/2, -3/8}, + {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}}, + }, + paramtype = "light", + is_ground_content = false, + groups = {choppy = 3}, + sounds = default.node_sound_wood_defaults(), + on_punch = function(pos, node, puncher, pointed_thing) + local wielded_item = puncher:get_wielded_item():get_name() + if compost.can_compost(wielded_item) then + minetest.set_node(pos, {name = "compost:wood_barrel_1"}) + local w = puncher:get_wielded_item() + if not(minetest.setting_getbool("creative_mode")) then + w:take_item(1) + puncher:set_wielded_item(w) + end + end + end +}) + +minetest.register_node("compost:wood_barrel_1", { + description = "Wood Barrel with compost", + tiles = {"default_wood.png^compost_compost_1.png", "default_wood.png"}, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/2, 1/2, -3/8, 1/2}, + {-1/2, -1/2, -1/2, -3/8, 1/2, 1/2}, + {3/8, -1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, 1/2, -3/8}, + {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + {-3/8, -1/2, -3/8, 3/8, 3/8, 3/8}}, + }, + paramtype = "light", + is_ground_content = false, + groups = {choppy = 3}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("compost:wood_barrel_2", { + description = "Wood Barrel with compost", + tiles = {"default_wood.png^compost_compost_2.png", "default_wood.png"}, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/2, 1/2, -3/8, 1/2}, + {-1/2, -1/2, -1/2, -3/8, 1/2, 1/2}, + {3/8, -1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, 1/2, -3/8}, + {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + {-3/8, -1/2, -3/8, 3/8, 3/8, 3/8}}, + }, + paramtype = "light", + is_ground_content = false, + groups = {choppy = 3}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("compost:wood_barrel_3", { + description = "Wood Barrel", + tiles = {"default_wood.png^compost_compost_3.png", "default_wood.png"}, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/2, 1/2, -3/8, 1/2}, + {-1/2, -1/2, -1/2, -3/8, 1/2, 1/2}, + {3/8, -1/2, -1/2, 1/2, 1/2, 1/2}, + {-1/2, -1/2, -1/2, 1/2, 1/2, -3/8}, + {-1/2, -1/2, 3/8, 1/2, 1/2, 1/2}, + {-3/8, -1/2, -3/8, 3/8, 3/8, 3/8}}, + }, + paramtype = "light", + is_ground_content = false, + groups = {choppy = 3}, + sounds = default.node_sound_wood_defaults(), + on_punch = function(pos, node, player, pointed_thing) + local p = {x = pos.x + math.random(0, 5)/5 - 0.5, y = pos.y+1, z = pos.z + math.random(0, 5)/5 - 0.5} + minetest.add_item(p, {name = "compost:compost"}) + minetest.set_node(pos, {name = "compost:wood_barrel"}) + end +}) + +minetest.register_abm({ + nodenames = {"compost:wood_barrel_1"}, + interval = 30, + chance = 5, + action = function(pos, node, active_object_count, active_object_count_wider) + minetest.set_node(pos, {name = "compost:wood_barrel_2"}) + end, +}) + +minetest.register_abm({ + nodenames = {"compost:wood_barrel_2"}, + interval = 30, + chance = 3, + action = function(pos, node, active_object_count, active_object_count_wider) + minetest.set_node(pos, {name = "compost:wood_barrel_3"}) + end, +}) + +minetest.register_craft({ + output = "compost:wood_barrel", + recipe = { + {"default:wood", "", "default:wood"}, + {"default:wood", "", "default:wood"}, + {"default:wood", "stairs:slab_wood", "default:wood"} + } +}) + +minetest.register_node("compost:compost", { + description = "Compost", + tiles = {"compost_compost.png"}, + groups = {crumbly = 3}, + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_node("compost:garden_soil", { + description = "Garden Soil", + tiles = {"compost_garden_soil.png"}, + groups = {crumbly = 3, soil=3, grassland = 1, wet = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_craft({ + output = "compost:garden_soil", + recipe = { + {"compost:compost", "compost:compost"}, + } +}) + +if minetest.get_modpath ("tubelib") and tubelib then + print ("[compost] found tubelib") + + -- Thanks to @joe7575 + tubelib.register_node ("compost:wood_barrel", { + "compost:wood_barrel_1", + "compost:wood_barrel_2", + "compost:wood_barrel_3" + }, { + on_push_item = function (pos, side, item, player_name) + local node = minetest.get_node (pos) + + if node.name == "compost:wood_barrel" and compost.can_compost(item:get_name()) then + minetest.set_node(pos, {name = "compost:wood_barrel_1"}) + return true + else + return false + end + end, + + on_unpull_item = function (pos, side, item, player_name) + minetest.set_node(pos, {name = "compost:wood_barrel_3"}) + return true + end, + + on_pull_item = function (pos, side, player_name) + local node = minetest.get_node (pos) + + if node.name == "compost:wood_barrel_3" then + minetest.set_node(pos, {name = "compost:wood_barrel"}) + return ItemStack("compost:compost") + end + + return nil + end, + }) +end diff --git a/mods/compost/license.txt b/mods/compost/license.txt new file mode 100644 index 0000000..ed285c3 --- /dev/null +++ b/mods/compost/license.txt @@ -0,0 +1,18 @@ +License for Code +---------------- + +Copyright (C) 2016 cdqwertz + +This program 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. + +http://www.gnu.org/licenses/lgpl-2.1.html + +License for Media +----------------- + +CC-BY-SA 3.0 UNPORTED. Created by cdqwertz + +Note: screenshot.png contains textures from minetest_game. diff --git a/mods/compost/mod.conf b/mods/compost/mod.conf new file mode 100644 index 0000000..d83e024 --- /dev/null +++ b/mods/compost/mod.conf @@ -0,0 +1,5 @@ +name = compost +depends = default +optional_depends = tubelib +description = This mod allows you to compost grass, leaves, flowers. +author = cdqwertz diff --git a/mods/compost/textures/compost_compost.png b/mods/compost/textures/compost_compost.png new file mode 100644 index 0000000..dfe1768 Binary files /dev/null and b/mods/compost/textures/compost_compost.png differ diff --git a/mods/compost/textures/compost_compost_1.png b/mods/compost/textures/compost_compost_1.png new file mode 100644 index 0000000..4a8921e Binary files /dev/null and b/mods/compost/textures/compost_compost_1.png differ diff --git a/mods/compost/textures/compost_compost_2.png b/mods/compost/textures/compost_compost_2.png new file mode 100644 index 0000000..f5dcbff Binary files /dev/null and b/mods/compost/textures/compost_compost_2.png differ diff --git a/mods/compost/textures/compost_compost_3.png b/mods/compost/textures/compost_compost_3.png new file mode 100644 index 0000000..6a70b03 Binary files /dev/null and b/mods/compost/textures/compost_compost_3.png differ diff --git a/mods/compost/textures/compost_garden_soil.png b/mods/compost/textures/compost_garden_soil.png new file mode 100644 index 0000000..55409b8 Binary files /dev/null and b/mods/compost/textures/compost_garden_soil.png differ diff --git a/mods/crafting_bench/README.txt b/mods/crafting_bench/README.txt new file mode 100644 index 0000000..54045a2 --- /dev/null +++ b/mods/crafting_bench/README.txt @@ -0,0 +1,18 @@ +=-=-=-=-=-=-=-=-=-= + +Crafting Bench +by: Philipbenr And DanDuncombe + +=-=-=-=-=-=-=-=-=-= + +Licence: MIT + +see: LICENSE + +=-=-=-=-=-=-=-=-=-= + +An auto-crafting bench. Place raw materials into its inventory, define a crafting recipe in its main grid, and then every five seconds it will generate a crafted output. + +This mod is compatible with hoppers. + +The crafting rate can be modified in advanced settings. \ No newline at end of file diff --git a/mods/crafting_bench/init.lua b/mods/crafting_bench/init.lua new file mode 100644 index 0000000..d836213 --- /dev/null +++ b/mods/crafting_bench/init.lua @@ -0,0 +1,195 @@ +-- internationalization boilerplate +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") +local crafting_bench = {} + +minetest.register_alias("castle:workbench", "crafting_bench:workbench") + +local usage_help = S("The inventory on the left is for raw materials, the inventory on the right holds finished products. The crafting grid in the center defines what recipe this workbench will make use of; place raw materials into it in the crafting pattern corresponding to what you want to build.") + +if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then + usage_help = usage_help .. "\n\n" .. S("This workbench is compatible with hoppers. Hoppers will insert into the raw material inventory and remove items from the finished goods inventory.") +end + +local crafting_rate = minetest.settings:get("crafting_bench_crafting_rate") +if crafting_rate == nil then crafting_rate = 5 end + + + +minetest.register_node("crafting_bench:workbench",{ + description = S("Workbench"), + _doc_items_longdesc = string.format(S("A workbench that does work for you. Set a crafting recipe and provide raw materials and items will magically craft themselves once every %i seconds."), crafting_rate), + _doc_items_usagehelp = usage_help, + tiles = { + "crafting_bench_workbench_top.png", + "crafting_bench_workbench_bottom.png", + "crafting_bench_workbench_side.png", + "crafting_bench_workbench_side.png", + "crafting_bench_workbench_back.png", + "crafting_bench_workbench_front.png" + }, + paramtype2 = "facedir", + paramtype = "light", + groups = {choppy=2,oddly_breakable_by_hand=2,flammable=2}, + sounds = default.node_sound_wood_defaults(), + drawtype = "normal", + on_construct = function ( pos ) + local meta = minetest.get_meta( pos ) + meta:set_string( 'formspec', + 'size[10,10;]' .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + 'label[1,0;'..S('Source Material')..']' .. + 'list[context;src;1,1;2,4;]' .. + 'label[4,0;'..S('Recipe to Use')..']' .. + 'list[context;rec;4,1;3,3;]' .. + 'label[7.5,0;'..S('Craft Output')..']' .. + 'list[context;dst;8,1;1,4;]' .. + 'list[current_player;main;1,6;8,4;]'.. + 'listring[current_player;main]'.. + 'listring[context;src]'.. + 'listring[current_player;main]'.. + 'listring[context;rec]'.. + 'listring[current_player;main]'.. + 'listring[context;dst]') + meta:set_string( 'infotext', S('Workbench')) + local inv = meta:get_inventory() + inv:set_size( 'src', 2 * 4 ) + inv:set_size( 'rec', 3 * 3 ) + inv:set_size( 'dst', 1 * 4 ) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", S("@1 moves stuff in workbench at @2", player:get_player_name(), minetest.pos_to_string(pos))) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", S("@1 moves stuff to workbench at @2", player:get_player_name(), minetest.pos_to_string(pos))) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", S("@1 takes stuff from workbench at @2", player:get_player_name(), minetest.pos_to_string(pos))) + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return (to_list == 'src' or to_list == 'rec' or to_list == 'dst' and from_list == 'src' or from_list == 'rec' or from_list == 'dst') and count or 0 + end, +}) +local get_recipe = function ( inv ) + local result, needed, input + needed = inv:get_list( 'rec' ) + + result, input = minetest.get_craft_result( { + method = 'normal', + width = 3, + items = needed + }) + + local totalneed = {} + + if result.item:is_empty() then + result = nil + else + result = result.item + for _, item in ipairs( needed ) do + if item ~= nil and not item:is_empty() and not inv:contains_item( 'src', item ) then + result = nil + break + end + if item ~= nil and not item:is_empty() then + if totalneed[item:get_name()] == nil then + totalneed[item:get_name()] = 1 + else + totalneed[item:get_name()] = totalneed[item:get_name()] + 1 + end + end + end + for name, number in pairs( totalneed ) do + local totallist = inv:get_list( 'src' ) + for i, srcitem in pairs( totallist ) do + if srcitem:get_name() == name then + local taken = srcitem:take_item( number ) + number = number - taken:get_count() + totallist[i] = srcitem + end + if number <= 0 then + break + end + end + if number > 0 then + result = nil + break + end + end + end + + return needed, input, result +end + +minetest.register_abm( { + nodenames = { 'crafting_bench:workbench' }, + interval = crafting_rate, + chance = 1, + action = function ( pos, node ) + local meta = minetest.get_meta( pos ) + local inv = meta:get_inventory() + local result, newinput, needed + if not inv:is_empty( 'src' ) then + -- Check for a valid recipe and sufficient resources to craft it + needed, newinput, result = get_recipe( inv ) + if result ~= nil and inv:room_for_item( 'dst', result ) then + inv:add_item( 'dst', result ) + for i, item in pairs( needed ) do + if item ~= nil and item ~= '' then + inv:remove_item( 'src', ItemStack( item ) ) + end + if newinput[i] ~= nil and not newinput[i]:is_empty() then + inv:add_item( 'src', newinput[i] ) + end + end + end + end + end +} ) + +local function has_locked_chest_privilege(meta, player) + if player:get_player_name() ~= meta:get_string("owner") then + return false + end + return true +end + +minetest.register_craft({ + output = "crafting_bench:workbench", + recipe = { + {"default:steel_ingot","default:steel_ingot","default:steel_ingot"}, + {"default:wood", "default:wood","default:steel_ingot"}, + {"default:tree", "default:tree","default:steel_ingot"}, + } +}) + +-- Hopper compatibility +if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then + hopper:add_container({ + {"top", "crafting_bench:workbench", "dst"}, + {"side", "crafting_bench:workbench", "src"}, + {"bottom", "crafting_bench:workbench", "src"}, + }) +end diff --git a/mods/crafting_bench/intllib.lua b/mods/crafting_bench/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/crafting_bench/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/crafting_bench/license.txt b/mods/crafting_bench/license.txt new file mode 100644 index 0000000..456d091 --- /dev/null +++ b/mods/crafting_bench/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Minetest Mods Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/crafting_bench/locale/template.pot b/mods/crafting_bench/locale/template.pot new file mode 100644 index 0000000..7ac578e --- /dev/null +++ b/mods/crafting_bench/locale/template.pot @@ -0,0 +1,67 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-02-28 21:08-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: init.lua:7 +msgid "" +"The inventory on the left is for raw materials, the inventory on the right " +"holds finished products. The crafting grid in the center defines what recipe " +"this workbench will make use of; place raw materials into it in the crafting " +"pattern corresponding to what you want to build." +msgstr "" + +#: init.lua:10 +msgid "" +"This workbench is compatible with hoppers. Hoppers will insert into the raw " +"material inventory and remove items from the finished goods inventory." +msgstr "" + +#: init.lua:19 init.lua:49 +msgid "Workbench" +msgstr "" + +#: init.lua:20 +#, lua-format +msgid "" +"A workbench that does work for you. Set a crafting recipe and provide raw " +"materials and items will magically craft themselves once every %i seconds." +msgstr "" + +#: init.lua:42 +msgid "Source Material" +msgstr "" + +#: init.lua:44 +msgid "Recipe to Use" +msgstr "" + +#: init.lua:46 +msgid "Craft Output" +msgstr "" + +#: init.lua:61 +msgid "@1 moves stuff in workbench at @2" +msgstr "" + +#: init.lua:64 +msgid "@1 moves stuff to workbench at @2" +msgstr "" + +#: init.lua:67 +msgid "@1 takes stuff from workbench at @2" +msgstr "" diff --git a/mods/crafting_bench/mod.conf b/mods/crafting_bench/mod.conf new file mode 100644 index 0000000..118330c --- /dev/null +++ b/mods/crafting_bench/mod.conf @@ -0,0 +1,4 @@ +name = crafting_bench +depends = default +optional_depends = intllib, hopper, doc +description = An auto-crafting bench diff --git a/mods/crafting_bench/settingtypes.txt b/mods/crafting_bench/settingtypes.txt new file mode 100644 index 0000000..9276289 --- /dev/null +++ b/mods/crafting_bench/settingtypes.txt @@ -0,0 +1,2 @@ +# The number of seconds between each operation of the crafting bench. +crafting_bench_crafting_rate (Crafting rate) int 5 1 60 \ No newline at end of file diff --git a/mods/crafting_bench/textures/LICENSE.txt b/mods/crafting_bench/textures/LICENSE.txt new file mode 100644 index 0000000..bd7ca92 --- /dev/null +++ b/mods/crafting_bench/textures/LICENSE.txt @@ -0,0 +1,20 @@ +-------------------------------------------- + +License Textures: Philipner - CC-BY-SA 3.0 + +-crafting_bench_workbench_back.png +-crafting_bench_workbench_front.png +-crafting_bench_workbench_side.png +-crafting_bench_workbench_top.png + + +-------------------------------------------- + +16 px textures based on crafting_bench mod +original textures by Philipner + +License Textures: Napiophelios - CC-BY-SA 3.0 + +-crafting_bench_workbench_bottom.png + +-------------------------------------------- diff --git a/mods/crafting_bench/textures/crafting_bench_workbench_back.png b/mods/crafting_bench/textures/crafting_bench_workbench_back.png new file mode 100644 index 0000000..174d941 Binary files /dev/null and b/mods/crafting_bench/textures/crafting_bench_workbench_back.png differ diff --git a/mods/crafting_bench/textures/crafting_bench_workbench_bottom.png b/mods/crafting_bench/textures/crafting_bench_workbench_bottom.png new file mode 100644 index 0000000..f50a8f3 Binary files /dev/null and b/mods/crafting_bench/textures/crafting_bench_workbench_bottom.png differ diff --git a/mods/crafting_bench/textures/crafting_bench_workbench_front.png b/mods/crafting_bench/textures/crafting_bench_workbench_front.png new file mode 100644 index 0000000..27a1f1f Binary files /dev/null and b/mods/crafting_bench/textures/crafting_bench_workbench_front.png differ diff --git a/mods/crafting_bench/textures/crafting_bench_workbench_side.png b/mods/crafting_bench/textures/crafting_bench_workbench_side.png new file mode 100644 index 0000000..b6418ac Binary files /dev/null and b/mods/crafting_bench/textures/crafting_bench_workbench_side.png differ diff --git a/mods/crafting_bench/textures/crafting_bench_workbench_top.png b/mods/crafting_bench/textures/crafting_bench_workbench_top.png new file mode 100644 index 0000000..fef4827 Binary files /dev/null and b/mods/crafting_bench/textures/crafting_bench_workbench_top.png differ diff --git a/mods/creative/README.txt b/mods/creative/README.txt new file mode 100644 index 0000000..32e8d22 --- /dev/null +++ b/mods/creative/README.txt @@ -0,0 +1,17 @@ +Minetest Game mod: creative +=========================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (MIT) +Jean-Patrick G. (kilbith) (MIT) + +Author of media (textures) +-------------------------- +paramat (CC BY-SA 3.0): +* creative_prev_icon.png +* creative_next_icon.png +* creative_search_icon.png +* creative_clear_icon.png +* creative_trash_icon.png derived from a texture by kilbith (CC BY-SA 3.0) diff --git a/mods/creative/depends.txt b/mods/creative/depends.txt new file mode 100644 index 0000000..975e652 --- /dev/null +++ b/mods/creative/depends.txt @@ -0,0 +1,2 @@ +default +sfinv diff --git a/mods/creative/init.lua b/mods/creative/init.lua new file mode 100644 index 0000000..0f8d4db --- /dev/null +++ b/mods/creative/init.lua @@ -0,0 +1,85 @@ +creative = {} + +local function update_sfinv(name) + minetest.after(0, function() + local player = minetest.get_player_by_name(name) + if player then + if sfinv.get_page(player):sub(1, 9) == "creative:" then + sfinv.set_page(player, sfinv.get_homepage_name(player)) + else + sfinv.set_player_inventory_formspec(player) + end + end + end) +end + +minetest.register_privilege("creative", { + description = "Allow player to use creative inventory", + give_to_singleplayer = false, + give_to_admin = false, + on_grant = update_sfinv, + on_revoke = update_sfinv, +}) + +local creative_mode_cache = minetest.settings:get_bool("creative_mode") + +function creative.is_enabled_for(name) + return creative_mode_cache or + minetest.check_player_privs(name, {creative = true}) +end + +dofile(minetest.get_modpath("creative") .. "/inventory.lua") + +if creative_mode_cache then + -- Dig time is modified according to difference (leveldiff) between tool + -- 'maxlevel' and node 'level'. Digtime is divided by the larger of + -- leveldiff and 1. + -- To speed up digging in creative, hand 'maxlevel' and 'digtime' have been + -- increased such that nodes of differing levels have an insignificant + -- effect on digtime. + local digtime = 42 + local caps = {times = {digtime, digtime, digtime}, uses = 0, maxlevel = 256} + + minetest.register_item(":", { + type = "none", + wield_image = "wieldhand.png", + wield_scale = {x = 1, y = 1, z = 2.5}, + range = 10, + tool_capabilities = { + full_punch_interval = 0.5, + max_drop_level = 3, + groupcaps = { + crumbly = caps, + cracky = caps, + snappy = caps, + choppy = caps, + oddly_breakable_by_hand = caps, + }, + damage_groups = {fleshy = 10}, + } + }) +end + +-- Unlimited node placement +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + if placer and placer:is_player() then + return creative.is_enabled_for(placer:get_player_name()) + end +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() or + 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 + if not inv:contains_item("main", item, true) then + inv:add_item("main", item) + end + end + end +end diff --git a/mods/creative/inventory.lua b/mods/creative/inventory.lua new file mode 100644 index 0000000..6f485d5 --- /dev/null +++ b/mods/creative/inventory.lua @@ -0,0 +1,191 @@ +local player_inventory = {} +local inventory_cache = {} + +local function init_creative_cache(items) + inventory_cache[items] = {} + local i_cache = inventory_cache[items] + + for name, def in pairs(items) do + if def.groups.not_in_creative_inventory ~= 1 and + def.description and def.description ~= "" then + i_cache[name] = def + end + end + table.sort(i_cache) + return i_cache +end + +function creative.init_creative_inventory(player) + local player_name = player:get_player_name() + player_inventory[player_name] = { + size = 0, + filter = "", + start_i = 0 + } + + minetest.create_detached_inventory("creative_" .. player_name, { + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2) + local name = player2 and player2:get_player_name() or "" + if not creative.is_enabled_for(name) or + to_list == "main" then + return 0 + end + return count + end, + allow_put = function(inv, listname, index, stack, player2) + return 0 + end, + allow_take = function(inv, listname, index, stack, player2) + local name = player2 and player2:get_player_name() or "" + if not creative.is_enabled_for(name) then + return 0 + end + return -1 + end, + on_move = function(inv, from_list, from_index, to_list, to_index, count, player2) + end, + on_take = function(inv, listname, index, stack, player2) + if stack and stack:get_count() > 0 then + minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory") + end + end, + }, player_name) + + return player_inventory[player_name] +end + +function creative.update_creative_inventory(player_name, tab_content) + local creative_list = {} + local inv = player_inventory[player_name] or + creative.init_creative_inventory(minetest.get_player_by_name(player_name)) + local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name}) + + local items = inventory_cache[tab_content] or init_creative_cache(tab_content) + + for name, def in pairs(items) do + if def.name:find(inv.filter, 1, true) or + def.description:lower():find(inv.filter, 1, true) then + creative_list[#creative_list+1] = name + end + end + + table.sort(creative_list) + player_inv:set_size("main", #creative_list) + player_inv:set_list("main", creative_list) + inv.size = #creative_list +end + +-- Create the trash field +local trash = minetest.create_detached_inventory("creative_trash", { + -- Allow the stack to be placed and remove it in on_put() + -- This allows the creative inventory to restore the stack + allow_put = function(inv, listname, index, stack, player) + return stack:get_count() + end, + on_put = function(inv, listname) + inv:set_list(listname, {}) + end, +}) +trash:set_size("main", 1) + +creative.formspec_add = "" + +function creative.register_tab(name, title, items) + sfinv.register_page("creative:" .. name, { + title = title, + is_in_nav = function(self, player, context) + return creative.is_enabled_for(player:get_player_name()) + end, + get = function(self, player, context) + local player_name = player:get_player_name() + creative.update_creative_inventory(player_name, items) + local inv = player_inventory[player_name] + local start_i = inv.start_i or 0 + local pagenum = math.floor(start_i / (3*8) + 1) + local pagemax = math.ceil(inv.size / (3*8)) + return sfinv.make_formspec(player, context, + "label[6.2,3.35;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" .. + [[ + image[4.06,3.4;0.8,0.8;creative_trash_icon.png] + listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF] + list[current_player;main;0,4.7;8,1;] + list[current_player;main;0,5.85;8,3;8] + list[detached:creative_trash;main;4,3.3;1,1;] + listring[] + image_button[5.4,3.25;0.8,0.8;creative_prev_icon.png;creative_prev;] + image_button[7.2,3.25;0.8,0.8;creative_next_icon.png;creative_next;] + image_button[2.1,3.25;0.8,0.8;creative_search_icon.png;creative_search;] + image_button[2.75,3.25;0.8,0.8;creative_clear_icon.png;creative_clear;] + tooltip[creative_search;Search] + tooltip[creative_clear;Reset] + tooltip[creative_prev;Previous page] + tooltip[creative_next;Next page] + listring[current_player;main] + field_close_on_enter[creative_filter;false] + ]] .. + "field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" .. + "listring[detached:creative_" .. player_name .. ";main]" .. + "list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" .. + default.get_hotbar_bg(0,4.7) .. creative.formspec_add, false) + end, + on_enter = function(self, player, context) + local player_name = player:get_player_name() + local inv = player_inventory[player_name] + if inv then + inv.start_i = 0 + end + end, + on_player_receive_fields = function(self, player, context, fields) + local player_name = player:get_player_name() + local inv = player_inventory[player_name] + assert(inv) + + if fields.creative_clear then + inv.start_i = 0 + inv.filter = "" + creative.update_creative_inventory(player_name, items) + sfinv.set_player_inventory_formspec(player, context) + elseif fields.creative_search or + fields.key_enter_field == "creative_filter" then + inv.start_i = 0 + inv.filter = fields.creative_filter:lower() + creative.update_creative_inventory(player_name, items) + sfinv.set_player_inventory_formspec(player, context) + elseif not fields.quit then + local start_i = inv.start_i or 0 + + if fields.creative_prev then + start_i = start_i - 3*8 + if start_i < 0 then + start_i = inv.size - (inv.size % (3*8)) + if inv.size == start_i then + start_i = math.max(0, inv.size - (3*8)) + end + end + elseif fields.creative_next then + start_i = start_i + 3*8 + if start_i >= inv.size then + start_i = 0 + end + end + + inv.start_i = start_i + sfinv.set_player_inventory_formspec(player, context) + end + end + }) +end + +creative.register_tab("all", "All", minetest.registered_items) +creative.register_tab("nodes", "Nodes", minetest.registered_nodes) +creative.register_tab("tools", "Tools", minetest.registered_tools) +creative.register_tab("craftitems", "Items", minetest.registered_craftitems) + +local old_homepage_name = sfinv.get_homepage_name +function sfinv.get_homepage_name(player) + if creative.is_enabled_for(player:get_player_name()) then + return "creative:all" + else + return old_homepage_name(player) + end +end diff --git a/mods/creative/license.txt b/mods/creative/license.txt new file mode 100644 index 0000000..50ff9c7 --- /dev/null +++ b/mods/creative/license.txt @@ -0,0 +1,61 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2016 Jean-Patrick G. (kilbith) +Copyright (C) 2018 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/creative/textures/creative_clear_icon.png b/mods/creative/textures/creative_clear_icon.png new file mode 100644 index 0000000..6fdc744 Binary files /dev/null and b/mods/creative/textures/creative_clear_icon.png differ diff --git a/mods/creative/textures/creative_next_icon.png b/mods/creative/textures/creative_next_icon.png new file mode 100644 index 0000000..45af8c6 Binary files /dev/null and b/mods/creative/textures/creative_next_icon.png differ diff --git a/mods/creative/textures/creative_prev_icon.png b/mods/creative/textures/creative_prev_icon.png new file mode 100644 index 0000000..3f1824d Binary files /dev/null and b/mods/creative/textures/creative_prev_icon.png differ diff --git a/mods/creative/textures/creative_search_icon.png b/mods/creative/textures/creative_search_icon.png new file mode 100644 index 0000000..f066c0d Binary files /dev/null and b/mods/creative/textures/creative_search_icon.png differ diff --git a/mods/creative/textures/creative_trash_icon.png b/mods/creative/textures/creative_trash_icon.png new file mode 100644 index 0000000..a0021ca Binary files /dev/null and b/mods/creative/textures/creative_trash_icon.png differ diff --git a/mods/custom_skin/init.lua b/mods/custom_skin/init.lua new file mode 100644 index 0000000..9562538 --- /dev/null +++ b/mods/custom_skin/init.lua @@ -0,0 +1,16 @@ +custom_skin = {} +custom_skin.texture = {} + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + local filename = minetest.get_modpath('custom_skin')..'/textures/'..name..'.png' + local f = io.open(filename) + if f then + f:close() + default.player_set_textures(player, {name..'.png'}) + custom_skin.texture[name] = (name..'.png') + else + default.player_set_textures(player,{'no_skin.png'}) + custom_skin.texture[name] = ('no_skin.png') + end +end) diff --git a/mods/custom_skin/license.txt b/mods/custom_skin/license.txt new file mode 100644 index 0000000..44d25b6 --- /dev/null +++ b/mods/custom_skin/license.txt @@ -0,0 +1,6 @@ +Code is licensed MIT, +Copyright 2020 Nathan Salapat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/custom_skin/mod.conf b/mods/custom_skin/mod.conf new file mode 100644 index 0000000..2e6a8e8 --- /dev/null +++ b/mods/custom_skin/mod.conf @@ -0,0 +1,3 @@ +name = custom_skin +depends = default +author = Nathan Salapat diff --git a/mods/custom_skin/textures/no_skin.png b/mods/custom_skin/textures/no_skin.png new file mode 100644 index 0000000..b074f15 Binary files /dev/null and b/mods/custom_skin/textures/no_skin.png differ diff --git a/mods/darkage/building.lua b/mods/darkage/building.lua new file mode 100644 index 0000000..7d1f8bb --- /dev/null +++ b/mods/darkage/building.lua @@ -0,0 +1,171 @@ +--[[ + This function registers the nodes and craft rezieps for the reinforce stuff + * name: String which is used in description and as technical name (lower letters) + * craftItem: the Item where the reinforce is crafted out of + * nodedef: Nodedefinition table as used as in minetest.register_node() + + The Nodes are caled + :reinforced_ + :reinforced__slope + :reinforced__arrow + :reinforced__bars + + The modname is automatically the mod that currently calls this function. + e.g. if you call darkage.register_reinforce from the mod medieval modname will be medieval +]] +function darkage.register_reinforce(name, craftItem, nodedef) + assert(type(nodedef.tiles)=="table","ERRROR: nodedef.tiles have to be a table") + assert(nodedef.tiles[1], "ERROR: "..dump(nodedef.tiles).." requires at least 1 entry") + + if nodedef.groups then + nodedef.groups["not_cuttable"] = 1; + else + nodedef.groups = {}; + nodedef.groups["not_cuttable"] = 1; + end + + local modname = minetest.get_current_modname(); + local tname = string.gsub(name:lower()," ", "_"); -- Technical name + +-- Reinforced X + local reinforced = table.copy(nodedef); + local reinforced_tname = modname..":reinforced_"..tname + reinforced.description = "Reinforced "..name + for i,tile in ipairs(reinforced.tiles) do + reinforced.tiles[i] = tile .."^darkage_reinforce.png" + end + + minetest.register_node(reinforced_tname, reinforced) + + minetest.register_craft({ + output = reinforced_tname, + recipe = { + {"group:stick", craftItem, "group:stick"}, + {craftItem, "group:stick", craftItem}, + {"group:stick", craftItem, "group:stick"}, + } + }) + -- Recycling + minetest.register_craft({ + output = craftItem, + recipe = { + { reinforced_tname }, + } + }) + +-- Reinforced Slope + local slope = table.copy(nodedef); + local slope_tname = modname..":reinforced_"..tname.."_slope" + slope.description = "Reinforced "..name.." Slope\nHint: use the screwdriver to rotate." + slope.paramtype2 = "facedir"; + local slope_tile_extend = {"^darkage_reinforce_right.png" , "^darkage_reinforce_right.png" , --top ,down + "^darkage_reinforce_right.png" , "^darkage_reinforce_right.png" , --right, left + "^darkage_reinforce_left.png" , "^darkage_reinforce_left.png"} -- front, back + for i=1,6 do + local tile = slope.tiles[i] or nodedef.tiles[1]; -- There have to be at least one tile. + slope.tiles[i] = tile ..slope_tile_extend[i] + end + + minetest.register_node(slope_tname, slope) + + minetest.register_craft({ + output = slope_tname, + recipe = { + {craftItem, craftItem, "group:stick"}, + {craftItem, "group:stick", craftItem}, + {"group:stick", craftItem, craftItem}, + } + }) + -- Flipped recipe + minetest.register_craft({ + output = slope_tname, + recipe = { + {"group:stick", craftItem, craftItem}, + {craftItem, "group:stick", craftItem}, + {craftItem, craftItem, "group:stick"}, + } + }) + -- Recycling + minetest.register_craft({ + output = craftItem, + recipe = { + { slope_tname } + } + }) + + -- Alias to convert old nodes + minetest.register_alias(modname..":reinforced_"..tname.."_right", slope_tname) + minetest.register_alias(modname..":reinforced_"..tname.."_left", slope_tname) + +-- Arrow bar + local arrow = table.copy(nodedef) + local arrow_tname = modname..":reinforced_"..tname.."_arrow" + arrow.paramtype2 = "facedir"; + arrow.description = "Reinforced "..name.." Arrow \nHint: use the screwdriver to rotate." + local arrow_tile_extend = {"" , "" , --top ,down + "^(darkage_reinforce_arrow.png^[transformR90)" , "^(darkage_reinforce_arrow.png^[transformR270)" , --right, left + "^(darkage_reinforce_arrow.png^[transformR180)" , "^darkage_reinforce_arrow.png"} -- front, back + for i=1,6 do + local tile = arrow.tiles[i] or arrow.tiles[1]; -- There have to be at least one tile. + arrow.tiles[i] = tile .. arrow_tile_extend[i] + end + minetest.register_node(arrow_tname, arrow) + + minetest.register_craft({ + output = arrow_tname, + recipe = { + {craftItem, "group:stick", craftItem}, + {"group:stick", craftItem, "group:stick"}, + {"group:stick", craftItem, "group:stick"}, + } + }) + -- Recycling + minetest.register_craft({ + output = craftItem, + recipe = { + { arrow_tname } + } + }) + +-- Reinforced Bars + local bars = table.copy(nodedef) + local bars_tname = modname..":reinforced_"..tname.."_bars" + bars.description = name.." Bars" + for i,tile in ipairs(bars.tiles) do + bars.tiles[i] = tile .."^darkage_reinforce_bars.png" + end + minetest.register_node(bars_tname, bars) + + minetest.register_craft({ + output = bars_tname, + recipe = { + {"group:stick", craftItem, "group:stick"}, + {"group:stick", craftItem, "group:stick"}, + {"group:stick", craftItem, "group:stick"}, + } + }) + minetest.register_craft({ + output = craftItem, + recipe = { + { bars_tname } + } + }) +end + +darkage.register_reinforce("Chalk", "darkage:chalk_powder", { + tiles = {"darkage_chalk.png"}, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults() +}) + +darkage.register_reinforce("Wood", "default:wood", { + tiles = {"default_wood.png"}, + groups = {snappy=2, choppy=3, flammable=3}, + sounds = default.node_sound_wood_defaults() +}) + +darkage.register_reinforce("Chalked Bricks", "darkage:chalked_bricks", { + tiles = {"darkage_chalked_bricks.png"}, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults() +}) diff --git a/mods/darkage/furniture.lua b/mods/darkage/furniture.lua new file mode 100644 index 0000000..81a4a0f --- /dev/null +++ b/mods/darkage/furniture.lua @@ -0,0 +1,173 @@ +minetest.register_node("darkage:iron_bars", { + description = "Iron Bars", + drawtype = "glasslike", + tiles = {"darkage_iron_bars.png"}, + inventory_image = "darkage_iron_bars.png", + wield_image = "darkage_iron_bars.png", + is_ground_content = false, + paramtype = "light", + sunlight_propagates = true, + groups = {cracky=3 , not_cuttable=1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:lamp", { + description = "Lamp", + tiles = { "darkage_lamp.png" }, + paramtype = "light", + sunlight_propagates = true, + light_source = default.LIGHT_MAX-1, + groups = {snappy=2, cracky=3, oddly_breakable_by_hand=3, flammable=1 , not_cuttable=1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("darkage:iron_grille", { + description = "Iron Grille", + drawtype = "glasslike", + tiles = {"darkage_iron_grille.png"}, + inventory_image = "darkage_iron_grille.png", + wield_image = "darkage_iron_grille.png", + is_ground_content = false, + paramtype = "light", + sunlight_propagates = true, + groups = {cracky=3 , not_cuttable=1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:wood_bars", { + description = "Wooden Bars", + drawtype = "glasslike", + tiles = {"darkage_wood_bars.png"}, + inventory_image = "darkage_wood_bars.png", + wield_image = "darkage_wood_bars.png", + is_ground_content = false, + paramtype = "light", + sunlight_propagates = true, + groups = {snappy=1, choppy=2, not_cuttable=1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:wood_grille", { + description = "Wooden Grille", + drawtype = "glasslike", + tiles = {"darkage_wood_grille.png"}, + inventory_image = "darkage_wood_grille.png", + wield_image = "darkage_wood_grille.png", + is_ground_content = false, + paramtype = "light", + sunlight_propagates = true, + groups = {snappy=1, choppy=2, not_cuttable=1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:wood_frame", { + description = "Wooden Frame", + drawtype = "glasslike_framed", + tiles = {"darkage_wood_frame.png"}, + inventory_image = "darkage_wood_frame.png", + wield_image = "darkage_wood_frame.png", + is_ground_content = false, + paramtype = "light", + sunlight_propagates = true, + groups = {snappy=1, choppy=2, oddly_breakable_by_hand = 3, not_cuttable=1}, + sounds = default.node_sound_stone_defaults() +}) + +--------------- +-- Crafts Item +--------------- + + +---------- +-- Crafts +---------- + +minetest.register_craft({ + output = "darkage:box", + recipe = { + {"default:wood", "", "default:wood"}, + {"", "", ""}, + {"default:wood", "", "default:wood"}, + } +}) + +minetest.register_craft({ + output = "darkage:chain 2", + recipe = { + {"darkage:iron_stick"}, + {"darkage:iron_stick"}, + {"darkage:iron_stick"}, + } +}) + +minetest.register_craft({ + output = "darkage:iron_bars 2", + recipe = { + {"darkage:iron_stick", "", "darkage:iron_stick"}, + {"darkage:iron_stick", "", "darkage:iron_stick"}, + {"darkage:iron_stick", "", "darkage:iron_stick"}, + } +}) + +minetest.register_craft({ + output = "darkage:iron_grille 3", + recipe = { + {"", "darkage:iron_bars", ""}, + {"darkage:iron_bars", "", "darkage:iron_bars"}, + {"", "darkage:iron_bars", ""}, + } +}) + +minetest.register_craft({ + output = "darkage:lamp", + recipe = { + {"group:stick", "", "group:stick"}, + {"", "default:torch", ""}, + {"group:stick", "", "group:stick"}, + } +}) + +minetest.register_craft({ + output = "darkage:wood_bars 2", + recipe = { + {"group:stick", "", "group:stick"}, + {"group:stick", "", "group:stick"}, + {"group:stick", "", "group:stick"}, + } +}) + +minetest.register_craft({ + output = "darkage:wood_grille 3", + recipe = { + {"", "darkage:wood_bars", ""}, + {"darkage:wood_bars", "", "darkage:wood_bars"}, + {"", "darkage:wood_bars", ""}, + } +}) + +minetest.register_craft({ + output = "darkage:wood_shelves", + recipe = { + {"darkage:box"}, + {"darkage:box"}, + } +}) + +minetest.register_craft({ + output = "darkage:wood_frame", + recipe = { + {"group:stick", "", "group:stick"}, + {"", "default:glass", ""}, + {"group:stick", "", "group:stick"}, + } +}) + + +-- Cookings +minetest.register_craft({ + type = "cooking", + output = "default:glass", + recipe = "darkage:wood_frame", +}) + + diff --git a/mods/darkage/glass.lua b/mods/darkage/glass.lua new file mode 100644 index 0000000..d95f768 --- /dev/null +++ b/mods/darkage/glass.lua @@ -0,0 +1,293 @@ +--[[ + Medival glasses. + The glasses can be colorized using dye. + Colorization requires unifieddyes installed. + + Special thanks to Semmett9 for the glass textures. +]] + +--[[ Rhombus Glass ]] + +minetest.register_node("darkage:glass", { + description = "Clean Medieval Glass", + drawtype = "glasslike", + tiles = {"darkage_glass.png"}, + use_texture_alpha=false, + paramtype = "light", + sunlight_propagates = true, + groups = {cracky = 3, oddly_breakable_by_hand = 3, not_cuttable=1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_craft({ + output = "darkage:glass 8", + recipe = { + {"default:glass", "default:steel_ingot", "default:glass"}, + {"default:steel_ingot", "default:glass", "default:steel_ingot"}, + {"default:glass", "default:steel_ingot", "default:glass"}, + } +}) + +--[[ Round Glass By Semmett9 aka Infinatum ]] + +minetest.register_node("darkage:glass_round", { + description = "Round Glass", + drawtype = "glasslike", + tiles = { "darkage_glass_round.png" }, + paramtype = "light", + use_texture_alpha = true, + sunlight_propagates = true, + sounds = default.node_sound_glass_defaults(), + groups = {cracky=3,oddly_breakable_by_hand=3, not_cuttable=1}, +}) + +minetest.register_craft({ + output = "darkage:glass_round 8", + recipe = { + {"default:steel_ingot", "default:glass", "default:steel_ingot"}, + {"default:glass", "default:glass", "default:glass"}, + {"default:steel_ingot", "default:glass", "default:steel_ingot"}, + } +}) + +--[[ Square glass By Semmett9 aka Infinatum ]] + +minetest.register_node("darkage:glass_square", { + description = "Square Glass", + drawtype = "glasslike", + tiles = { "darkage_glass_square.png" }, + paramtype = "light", + use_texture_alpha = true, + sunlight_propagates = true, + sounds = default.node_sound_glass_defaults(), + groups = {cracky=3,oddly_breakable_by_hand=3, not_cuttable=1}, +}) + +minetest.register_craft({ + output = "darkage:glass_square 8", + recipe = { + {"default:glass", "default:steel_ingot", "default:glass"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:glass", "default:steel_ingot", "default:glass"}, + } +}) + +--[[ + Glowing Glass Variants + + ]] + +--[[ Rhombus Glow Glass ]] + +minetest.register_node("darkage:glow_glass", { + description = "Medieval Glow Glass", + drawtype = "glasslike", + tiles = {"darkage_glass.png"}, + use_texture_alpha=true, + paramtype = "light", + sunlight_propagates = true, + light_source = default.LIGHT_MAX-3, + groups = {cracky = 3, oddly_breakable_by_hand = 3, not_cuttable=1}, + sounds = default.node_sound_glass_defaults(), + inventory_image = minetest.inventorycube("darkage_glow_glass.png") +}) + +minetest.register_craft({ + output = "darkage:glow_glass 1", + type = "shaped", + recipe = { + {"darkage:glass"}, + {"default:torch"} + } +}) + +-- Recycling +minetest.register_craft({ + output = "darkage:glass 1", + type = "shaped", + recipe = {{"darkage:glow_glass"}}, +}) + +--[[ Round Glow Glass ]] + +minetest.register_node("darkage:glow_glass_round", { + description = "Medieval Round Glow Glass", + drawtype = "glasslike", + tiles = {"darkage_glass_round.png"}, + use_texture_alpha=true, + paramtype = "light", + sunlight_propagates = true, + light_source = default.LIGHT_MAX-3, + groups = {cracky = 3, oddly_breakable_by_hand = 3, not_cuttable=1}, + sounds = default.node_sound_glass_defaults(), + inventory_image = minetest.inventorycube("darkage_glow_glass_round.png") +}) + +minetest.register_craft({ + output = "darkage:glow_glass_round 1", + type = "shaped", + recipe = { + {"darkage:glass_round"}, + {"default:torch"} + } +}) + +-- Recycling +minetest.register_craft({ + output = "darkage:glass_round 1", + recipe = {{"darkage:glow_glass_round"}} +}) + +--]] Square Glow Glass ]] + +minetest.register_node("darkage:glow_glass_square", { + description = "Medieval Square Glow Glass", + drawtype = "glasslike", + tiles = {"darkage_glass_square.png"}, + use_texture_alpha=true, + paramtype = "light", + sunlight_propagates = true, + light_source = default.LIGHT_MAX-3, + groups = {cracky = 3, oddly_breakable_by_hand = 3, not_cuttable=1}, + sounds = default.node_sound_glass_defaults(), + inventory_image = minetest.inventorycube("darkage_glow_glass_square.png") +}) + +minetest.register_craft({ + output = "darkage:glow_glass_square 1", + type = "shaped", + recipe = { + {"darkage:glass_square"}, + {"default:torch"}, + } +}) + +--Recycling +minetest.register_craft({ + output = "darkage:glass_square 1", + recipe = {{"darkage:glow_glass_square"}} +}) + +--[[ + Colorizable Milk Glass Variants, depending on unifieddyes mod + + ]] + +if minetest.get_modpath("unifieddyes") then + + --[[ Rhombus Milk Glass ]] + + minetest.register_node("darkage:milk_glass", { + description = "Milky Medieval Glass (Good for colorization)", + drawtype = "glasslike", + tiles = {"darkage_milk_glass.png"}, + use_texture_alpha=true, + paramtype = "light", + paramtype2 = "color", + palette = "unifieddyes_palette_extended.png", + sunlight_propagates = true, + groups = {cracky = 3, oddly_breakable_by_hand = 3, not_cuttable=1, ud_param2_colorable = 1}, + sounds = default.node_sound_glass_defaults() + }) + + minetest.register_craft({ + output = "darkage:milk_glass", + type = "shapeless", + recipe = {"darkage:glass", "dye:white"} + }) + + unifieddyes.register_color_craft({ + output = "darkage:milk_glass", + palette = "extended", + type = "shapeless", + neutral_node = "", + recipe = { + "darkage:milk_glass", + "MAIN_DYE" + } + }) + + -- Recycling + minetest.register_craft({ + output = "darkage:glass 1", + recipe = {{"darkage:milk_glass"}} + }) + + --[[ Round Milk Glass ]] + + minetest.register_node("darkage:milk_glass_round", { + description = "Milky Medieval Round Glass (Good for colorization)", + drawtype = "glasslike", + tiles = {"darkage_milk_glass_round.png"}, + use_texture_alpha=true, + paramtype = "light", + paramtype2 = "color", + palette = "unifieddyes_palette_extended.png", + sunlight_propagates = true, + groups = {cracky = 3, oddly_breakable_by_hand = 3, not_cuttable=1, ud_param2_colorable = 1}, + sounds = default.node_sound_glass_defaults() + }) + -- Craft + minetest.register_craft({ + output = "darkage:milk_glass_round", + type = "shapeless", + recipe = {"darkage:glass_round", "dye:white"}, + }) + + unifieddyes.register_color_craft({ + output = "darkage:milk_glass_round", + palette = "extended", + type = "shapeless", + neutral_node = "", + recipe = { + "darkage:milk_glass_round", + "MAIN_DYE" + } + }) + + -- Recycling + minetest.register_craft({ + output = "darkage:glass_round 1", + recipe = {{"darkage:milk_glass_round"}} + }) + + --[[ Square Milk Glass ]] + + minetest.register_node("darkage:milk_glass_square", { + description = "Milky Medieval Square Glass (Good for colorization)", + drawtype = "glasslike", + tiles = {"darkage_milk_glass_square.png"}, + use_texture_alpha=true, + paramtype = "light", + paramtype2 = "color", + palette = "unifieddyes_palette_extended.png", + sunlight_propagates = true, + groups = {cracky = 3, oddly_breakable_by_hand = 3, not_cuttable=1, ud_param2_colorable = 1}, + sounds = default.node_sound_glass_defaults() + }) + + -- Craft + minetest.register_craft({ + output = "darkage:milk_glass_square", + type = "shapeless", + recipe = {"darkage:glass_square", "dye:white"}, + }) + + unifieddyes.register_color_craft({ + output = "darkage:milk_glass_square", + palette = "extended", + type = "shapeless", + neutral_node = "", + recipe = { + "darkage:stained_milk_glass_square", + "MAIN_DYE" + } + }) + + -- Recycling + minetest.register_craft({ + output = "darkage:glass_square", + recipe = {{"darkage:milk_glass_square"}} + }) + +end --unifieddyes condition diff --git a/mods/darkage/init.lua b/mods/darkage/init.lua new file mode 100644 index 0000000..793c15a --- /dev/null +++ b/mods/darkage/init.lua @@ -0,0 +1,360 @@ +minetest.log("action"," ---- Dark Age Version 1.3 is Loading! ---- ") + +darkage = {}; -- Create darkage namespace + +darkage.formbg = (default.gui_bg or "").. + (default.gui_bg_img or "").. + (default.gui_slots or "") + +local MODPATH = minetest.get_modpath("darkage")..DIR_DELIM + +dofile(MODPATH.."nodes.lua") +dofile(MODPATH.."glass.lua") +dofile(MODPATH.."mapgen.lua") +dofile(MODPATH.."building.lua") +dofile(MODPATH.."furniture.lua") +dofile(MODPATH.."walls.lua") + +dofile(MODPATH.."stairs_functions.lua") +dofile(MODPATH.."stairs.lua") + + +--------------- +-- Crafts Items +--------------- +minetest.register_craftitem("darkage:chalk_powder", { + description = "Chalk Powder", + inventory_image = "darkage_chalk_powder.png", +}) + +minetest.register_craftitem("darkage:mud_lump", { + description = "Mud Lump", + inventory_image = "darkage_mud_lump.png", +}) + +minetest.register_craftitem("darkage:silt_lump", { + description = "Silt Lump", + inventory_image = "darkage_silt_lump.png", +}) + +minetest.register_craftitem("darkage:iron_stick", { + description = "Iron Stick", + inventory_image = "darkage_iron_stick.png", +}) + + +---------- +-- Crafts +---------- + + +minetest.register_craft({ + type = "cooking", + output = "darkage:basalt", + recipe = "darkage:basalt_rubble", +}) + +minetest.register_craft({ + output = "darkage:basalt_rubble 4", + recipe = { + {"default:cobble", "default:cobble"}, + {"default:coal_lump", "default:coal_lump"}, + } +}) + +minetest.register_craft({ + output = "darkage:basalt_brick 4", + recipe = { + {"darkage:basalt", "darkage:basalt"}, + {"darkage:basalt", "darkage:basalt"}, + } +}) + +minetest.register_craft({ + output = "darkage:basalt_block 9", + recipe = { + {"darkage:basalt", "darkage:basalt", "darkage:basalt"}, + {"darkage:basalt", "darkage:basalt", "darkage:basalt"}, + {"darkage:basalt", "darkage:basalt", "darkage:basalt"}, + } +}) + +minetest.register_craft({ + output = "darkage:cobble_with_plaster 2", + recipe = { + {"default:cobble", "darkage:chalk_powder"}, + {"default:cobble", "darkage:chalk_powder"}, + } +}) + +minetest.register_craft({ + output = "darkage:cobble_with_plaster 2", + recipe = { + {"darkage:chalk_powder", "default:cobble"}, + {"darkage:chalk_powder", "default:cobble"}, + } +}) + +minetest.register_craft({ + output = "darkage:chalked_bricks_with_plaster 2", + recipe = { + {"darkage:chalked_bricks", "darkage:chalk_powder"}, + {"darkage:chalked_bricks", "darkage:chalk_powder"}, + } +}) + +minetest.register_craft({ + output = "darkage:chalked_bricks_with_plaster 2", + recipe = { + {"darkage:chalk_powder", "darkage:chalked_bricks"}, + {"darkage:chalk_powder", "darkage:chalked_bricks"}, + } +}) + +--[[ + Gneiss +]] +minetest.register_craft({ + type = "cooking", + output = "darkage:gneiss", + recipe = "darkage:schist", +}) + +minetest.register_craft({ + type = "cooking", + output = "darkage:gneiss", + recipe = "darkage:gneiss_rubble", +}) + +minetest.register_craft({ + output = "darkage:gneiss_brick 4", + recipe = { + {"darkage:gneiss", "darkage:gneiss"}, + {"darkage:gneiss", "darkage:gneiss"}, + } +}) + +minetest.register_craft({ + output = "darkage:gneiss_block 9", + recipe = { + {"darkage:gneiss", "darkage:gneiss", "darkage:gneiss"}, + {"darkage:gneiss", "darkage:gneiss", "darkage:gneiss"}, + {"darkage:gneiss", "darkage:gneiss", "darkage:gneiss"}, + } +}) + +minetest.register_craft({ + output = "darkage:mud 3", + recipe = { + {"default:dirt", "default:dirt"}, + {"default:clay_lump", "darkage:silt_lump"}, + } +}) + +minetest.register_craft({ + output = "darkage:mud", + recipe = { + {"darkage:mud_lump", "darkage:mud_lump"}, + {"darkage:mud_lump", "darkage:mud_lump"}, + } +}) + +minetest.register_craft({ + output = "darkage:marble_tile 2", + recipe = { + {"darkage:marble", "darkage:marble"}, + {"darkage:marble", "darkage:marble"}, + } +}) + +--[[ + Old Red Sandstone +]] + +minetest.register_craft({ + type = "cooking", + output = "darkage:ors", + recipe = "darkage:ors_rubble", +}) + +minetest.register_craft({ + output = "darkage:ors 4", + recipe = { + {"default:sandstone", "default:sandstone"}, + {"default:iron_lump", "default:sandstone"}, + } +}) +minetest.register_craft({ + output = "darkage:ors_brick 4", + recipe = { + {"darkage:ors", "darkage:ors"}, + {"darkage:ors", "darkage:ors"}, + } +}) + +minetest.register_craft({ + output = "darkage:ors_block 9", + recipe = { + {"darkage:ors", "darkage:ors", "darkage:ors"}, + {"darkage:ors", "darkage:ors", "darkage:ors"}, + {"darkage:ors", "darkage:ors", "darkage:ors"}, + } +}) + +minetest.register_craft({ + output = "darkage:silt 3", + recipe = { + {"default:sand", "default:sand"}, + {"default:clay_lump", "default:clay_lump"}, + } +}) + +minetest.register_craft({ + output = "darkage:silt", + recipe = { + {"darkage:silt_lump", "darkage:silt_lump"}, + {"darkage:silt_lump", "darkage:silt_lump"}, + } +}) + +--[[ + Slate +]] +minetest.register_craft({ + type = "cooking", + output = "darkage:slate", + recipe = "darkage:slate_rubble", +}) + +minetest.register_craft({ + output = "darkage:slate_brick 4", + recipe = { + {"darkage:slate", "darkage:slate"}, + {"darkage:slate", "darkage:slate"}, + } +}) + +minetest.register_craft({ + output = "darkage:slate_block 9", + recipe = { + {"darkage:slate", "darkage:slate", "darkage:slate"}, + {"darkage:slate", "darkage:slate", "darkage:slate"}, + {"darkage:slate", "darkage:slate", "darkage:slate"}, + } +}) + +minetest.register_craft({ + output = "darkage:slate_tile 2", + recipe = { + {"darkage:slate_brick", "darkage:slate_brick"}, + {"darkage:slate_brick", "darkage:slate_brick"}, + } +}) + +minetest.register_craft({ + output = "darkage:stone_brick", + recipe = { + {"default:stone_block"}, + } +}) + + +minetest.register_craft({ + output = "darkage:straw_bale", + recipe = { + {"farming:straw","farming:straw"}, + {"farming:straw","farming:straw"}, + } +}) + +minetest.register_craft({ + output = "darkage:iron_stick 4", + recipe = { + {"default:steel_ingot"}, + } +}) + +-- Cookings + +minetest.register_craft({ + type = "cooking", + output = "darkage:schist", + recipe = "darkage:slate", +}) + +minetest.register_craft({ + type = "cooking", + output = "darkage:shale", + recipe = "darkage:mud", +}) + +minetest.register_craft({ + type = "cooking", + output = "darkage:slate", + recipe = "darkage:shale", +}) + +minetest.register_craft({ + type = "cooking", + output = "darkage:slate", + recipe = "darkage:slate_rubble", +}) + +-- Desert +minetest.register_craft({ + type = "cooking", + output = "darkage:ors_brick", + recipe = "default:desert_stone", +}) + +-- Tuff +minetest.register_craft({ + output = "darkage:tuff 2", + recipe = { + {"darkage:gneiss", "default:stone"}, + {"default:stone", "darkage:gneiss"}, + } +}) + +minetest.register_craft({ + type = "cooking", + output = "darkage:tuff", + recipe = "darkage:tuff_rubble", +}) + +minetest.register_craft({ + type = "cooking", + output = "darkage:tuff", + recipe = "darkage:old_tuff_bricks", +}) + +minetest.register_craft({ + output = "darkage:tuff_bricks 4", + recipe = { + {"darkage:tuff", "darkage:tuff"}, + {"darkage:tuff", "darkage:tuff"}, + } +}) + +-- Rhyolitic Tuff +minetest.register_craft({ + output = "darkage:rhyolitic_tuff 2", + recipe = { + {"darkage:gneiss", "default:desert_stone"}, + {"default:desert_stone", "darkage:gneiss"}, + } +}) + +minetest.register_craft({ + type = "cooking", + output = "darkage:rhyolitic_tuff", + recipe = "darkage:rhyolitic_tuff_rubble", +}) + +minetest.register_craft({ + output = "darkage:rhyolitic_tuff_bricks 4", + recipe = { + {"darkage:rhyolitic_tuff", "darkage:rhyolitic_tuff"}, + {"darkage:rhyolitic_tuff", "darkage:rhyolitic_tuff"}, + } +}) diff --git a/mods/darkage/license.txt b/mods/darkage/license.txt new file mode 100644 index 0000000..ab0d3ad --- /dev/null +++ b/mods/darkage/license.txt @@ -0,0 +1 @@ +Code and graphics by MasterGollum, relicensed MIT from WTFPL diff --git a/mods/darkage/mapgen.lua b/mods/darkage/mapgen.lua new file mode 100644 index 0000000..c8ce24c --- /dev/null +++ b/mods/darkage/mapgen.lua @@ -0,0 +1,292 @@ + +-- Some local constants to use for mapgen +local c_air = minetest.CONTENT_AIR +local c_ignore = minetest.CONTENT_IGNORE + +local c_stone = minetest.get_content_id("default:stone") +local c_water = minetest.get_content_id("default:water_source") +local c_sand = minetest.get_content_id("default:sand") +local c_dirt = minetest.get_content_id("default:dirt") +local c_lawn = minetest.get_content_id("default:dirt_with_grass") + +local stone_and_air_assoc = {[c_stone]=true,[c_air]=true} --associative array + +--Makes a stratus of rocks +--name of the rock to generate +--c_wherein id of node to replace, for example minetest.get_content_id("default:stone") +--ca_ceilin associative array +--minp, maxp the corners of the map to be generated +--seed random seed +--stratus_chance inverse probability in a given radius 1:2, 1:3 etc +--radius horizontal radius of the stratus +--radius_y vertical radius of the stratus +--deep how deep can be from the ground +local function generate_stratus(data, area, name, c_wherein, ca_ceilin, minp, maxp, seed, stratus_chance, radius, radius_y, deep, y_min, y_max) + if maxp.y < y_min + or minp.y > y_max then + return + end + + local c_node = minetest.get_content_id(name) + + -- it will be only generate a stratus for every 100 m of area + local stratus_per_volume=1 + local area_size = 45 + local y_min = math.max(minp.y, y_min) + local y_max = math.min(maxp.y, y_max) + local volume = ((maxp.x-minp.x+1)/area_size)*((y_max-y_min+1)/area_size)*((maxp.z-minp.z+1)/area_size) + local pr = PseudoRandom(seed) + local blocks = math.floor(stratus_per_volume*volume) + minetest.log("info", " <<"..name..">>"); + if blocks == 0 then + blocks = 1 + end + minetest.log("info", string.format(" blocks: %d in vol: %d (%d,%d,%d)", + blocks, volume, maxp.x-minp.x+1, y_max-y_min+1, maxp.z-minp.z+1)) + for i = 1,blocks do + if pr:next(1,stratus_chance) == 1 then + -- TODO deep + local y0=y_max-radius_y+1 + if y0 < y_min then + y0=y_min + else + y0=pr:next(y_min, y0) + end + local x0 = maxp.x-radius+1 + if x0 < minp.x then + x0 = minp.x + else + x0 = pr:next(minp.x, x0) + end + local z0 = maxp.z-radius+1 + if z0 < minp.z then + x0 = minp.z + else + z0 = pr:next(minp.z, z0) + end + local n = data[area:index(x0, y0, z0)] + local i = 0 + + if ca_ceilin[n] then + -- search for the node to replace + --print(" Searching nodes to replace from "..dump(y0-1).." to "..dump(y_min)) + local vi = area:index(x0, y0-1, z0) + for y1 = y0-1,y_min,-1 do + if data[vi] == c_wherein then + y0 = math.max(y1-deep, y_min) + break + end + vi = vi - area.ystride + end + local rx=pr:next(radius/2,radius)+1 + local rz=pr:next(radius/2,radius)+1 + local ry=pr:next(radius_y/2,radius_y)+1 + --print(" area of generation ("..dump(rx)..","..dump(rz)..","..dump(ry)..")") + vi = area:index(x0, y0, z0) + for x1=0,rx do + local vi = vi + x1 + rz = math.max(rz + 3 - pr:next(1,6), 1) + for z1=pr:next(1,3),rz do + local vi = vi + z1 * area.zstride + for y1 = pr:next(1,3), ry + pr:next(1,3) do + local vi = vi + y1 * area.ystride + if data[vi] == c_wherein then + data[vi] = c_node + i = i + 1 + end + end + end + end + end + minetest.log("info", " generated "..i.." blocks in ("..x0..","..y0..","..z0..")") + end + end + --print("generate_ore done") +end + +local function generate_claylike(data, varea, name, minp, maxp, seed, chance, minh, maxh, needs_dirt) + if maxp.y >= maxh+1 and minp.y <= minh-1 then + local c_ore = minetest.get_content_id(name) + local pr = PseudoRandom(seed) + + local divlen = 4 + local divs = (maxp.x-minp.x)/divlen+1; + for yy=minh,maxh do + local x = pr:next(1,chance) + if x == 1 then + for divx=0+1,divs-1-1 do + for divz=0+1,divs-1-1 do + local cx = minp.x + math.floor((divx+0.5)*divlen) + local cz = minp.z + math.floor((divz+0.5)*divlen) + local up = data[varea:index(cx,yy,cz)] + local down = data[varea:index(cx,yy-1,cz)] + if ( up == c_water or up == c_air ) and ( down == c_sand or (needs_dirt and (down == c_dirt or down == c_lawn ))) then + local num_water_around = 0 + if data[varea:index(cx-divlen*2,yy,cz)] == c_water then + num_water_around = num_water_around + 1 + end + if data[varea:index(cx+divlen*2,yy,cz)] == c_water then + num_water_around = num_water_around + 1 + end + if data[varea:index(cx,yy,cz-divlen*2)] == c_water then + num_water_around = num_water_around + 1 + end + if data[varea:index(cx,yy,cz+divlen*2)] == c_water then + num_water_around = num_water_around + 1 + end + if num_water_around < 3 then + for x1=-divlen,divlen do + for z1=-divlen,divlen do + local i = varea:index(cx+x1,yy-1,cz+z1) + local down = data[i] + if down == c_sand or (needs_dirt and (down == c_dirt or down == c_lawn)) then + data[i] = c_ore + end + end + end + end + end + end + end + end + end + end +end + +local seed = minetest.get_mapgen_setting('seed') + +-- Generate chalk inside mountains +minetest.register_ore({ + ore_type = "sheet", + ore = "darkage:chalk", + wherein = {"default:stone"}, + column_height_max = 30, + column_height_min = 20, + y_min = -20, + y_max = 50, + noise_threshold = 0.45, + noise_params = { + offset = 0.35, + scale = 0.2, + spread = {x = 30, y = 30, z = 30}, + octaves = 1, + persistence = 0.6 + }, +}) + +minetest.register_ore({ + ore_type = "sheet", + ore = "darkage:tuff", + wherein = {"default:stone", "default:needs_dirt", "default:gravel", "default:stone_with_coal"}, + column_height_max = 20, + column_height_min = 15, + y_min = -200, + y_max = 200, + noise_threshold = 0.5, + noise_params = { + offset = 0.35, + scale = 0.19, + seed = seed+12, + spread = {x = 45, y = 45, z = 45}, + octaves = 1, + persistence = 0.6 + }, +}) + +minetest.register_ore({ + ore_type = "sheet", + ore = "darkage:rhyolitic_tuff", + wherein = {"default:stone", "default:needs_dirt", "default:gravel", "default:stone_with_coal"}, + column_height_max = 20, + column_height_min = 15, + y_min = -2000, + y_max = 200, + noise_threshold = 0.53, + noise_params = { + offset = 0.35, + scale = 0.2, + seed = seed+13, + spread = {x = 100, y = 100, z = 100}, + octaves = 1, + persistence = 0.6 + }, +}) + +--old red sandstone +minetest.register_ore({ + ore_type = "sheet", + ore = "darkage:ors", + wherein = {"default:stone", "default:dirt", "default:gravel", "default:stone_with_coal"}, + column_height_max = 8, + column_height_min = 6, + y_min = -200, + y_max = 500, + noise_threshold = 0.49, + noise_params = { + offset = 0.28, + scale = 0.3, + seed = seed+4, + spread = {x = 10, y = 10, z = 10}, + octaves = 1, + persistence = 0.6 + }, +}) + + +-- Generate strati +local dbuf = {} --for mapgen +local function generate_strati(minp, maxp, seed) + + local t1 = os.clock() + + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax}) + local data = vm:get_data(dbuf) + + + generate_claylike(data, area, "darkage:mud", minp, maxp, seed+1, 4, 0, 2, false) + generate_claylike(data, area, "darkage:silt", minp, maxp, seed+2, 4, -1, 1, true) + + -- TODO: Maybe realize the following stuff with register ore. somehow. + generate_stratus(data, area, "darkage:shale", + c_stone, + stone_and_air_assoc, + minp, maxp, seed+5, 4, 23, 7, 50, -50, 20) + + generate_stratus(data, area, "darkage:slate", + c_stone, + stone_and_air_assoc, + minp, maxp, seed+6, 6, 23, 5, 50, -500, 0) + + generate_stratus(data, area, "darkage:schist", + c_stone, + stone_and_air_assoc, + minp, maxp, seed+7, 6, 19, 6, 50, -31000, -10) + + generate_stratus(data, area, "darkage:basalt", + c_stone, + stone_and_air_assoc, + minp, maxp, seed+8, 5, 20, 5, 20, -31000, -50) + + generate_stratus(data, area, "darkage:marble", + c_stone, + stone_and_air_assoc, + minp, maxp, seed+9, 4, 25, 6, 50, -31000, -75) + + generate_stratus(data, area, "darkage:serpentine", + c_stone, + stone_and_air_assoc, + minp, maxp, seed+10, 4, 28, 8, 50, -31000, -350) + + generate_stratus(data, area, "darkage:gneiss", + c_stone, + stone_and_air_assoc, + minp, maxp, seed+11, 4, 15, 5, 50, -31000, -250) + + vm:set_data(data) + vm:write_to_map() + + minetest.log("info", string.format("[darkage] Generated Strati after %.2fs.", os.clock() - t1)) +end + +minetest.register_on_generated(generate_strati) diff --git a/mods/darkage/mod.conf b/mods/darkage/mod.conf new file mode 100644 index 0000000..3ef9df3 --- /dev/null +++ b/mods/darkage/mod.conf @@ -0,0 +1,5 @@ +name = darkage +author = MasterGollum +depends = default, farming +optional_depends = moreblocks, stairs, unifieddies +description = DarkAge adds several new nodes and crafts to create a pre industrial landscape. diff --git a/mods/darkage/nodes.lua b/mods/darkage/nodes.lua new file mode 100644 index 0000000..bb5e3d0 --- /dev/null +++ b/mods/darkage/nodes.lua @@ -0,0 +1,431 @@ +local function get_node_drops(fullRockNode, cobbleRockNode) + return { + max_items = 1, + items = { + { + -- drop the cobble variant with 1/3 chance + items = {cobbleRockNode}, + rarity = 3, + }, + { + -- drop the full node with 2/3 chance + items = {fullRockNode}, + } + } + } +end + +---------- +-- Nodes +---------- + +--[[ + Basalt +]] +minetest.register_node("darkage:basalt", { + description = "Basalt", + tiles = {"darkage_basalt.png"}, + is_ground_content = true, + drop = get_node_drops("darkage:basalt","darkage:basalt_rubble"), + groups = {cracky = 3, stone = 1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:basalt_rubble", { + description = "Basalt Rubble", + tiles = {"darkage_basalt_rubble.png"}, + is_ground_content = false, + groups = {cracky = 3, stone = 2}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:basalt_brick", { + description = "Basalt Brick", + tiles = {"darkage_basalt_brick.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:basalt_block", { + description = "Basalt Block", + tiles = {"darkage_basalt_block.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults() +}) + +--[[ + Chalk +]] +minetest.register_node("darkage:chalk", { + description = "Chalk", + tiles = {"darkage_chalk.png"}, + is_ground_content = true, + drop = 'darkage:chalk_powder 2', + groups = {crumbly=2, cracky=2, not_cuttable=1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:cobble_with_plaster", { + description = "Cobblestone with Plaster", + tiles = {"darkage_chalk.png^(default_cobble.png^[mask:darkage_plaster_mask_D.png)", "darkage_chalk.png^(default_cobble.png^[mask:darkage_plaster_mask_B.png)", + "darkage_chalk.png^(default_cobble.png^[mask:darkage_plaster_mask_C.png)", "darkage_chalk.png^(default_cobble.png^[mask:darkage_plaster_mask_A.png)", + "default_cobble.png", "darkage_chalk.png"}, + is_ground_content = false, + paramtype2 = "facedir", + drop = 'default:cobble', + groups = {cracky=3, not_cuttable=1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("darkage:chalked_bricks_with_plaster", { + description = "Chalked Bricks with Plaster", + tiles = {"darkage_chalk.png^(darkage_chalked_bricks.png^[mask:darkage_plaster_mask_D.png)", "darkage_chalk.png^(darkage_chalked_bricks.png^[mask:darkage_plaster_mask_B.png)", + "darkage_chalk.png^(darkage_chalked_bricks.png^[mask:darkage_plaster_mask_C.png)", "darkage_chalk.png^(darkage_chalked_bricks.png^[mask:darkage_plaster_mask_A.png)", + "darkage_chalked_bricks.png", "darkage_chalk.png"}, + is_ground_content = false, + paramtype2 = "facedir", + drop = 'default:cobble', + groups = {cracky=3, not_cuttable=1}, + sounds = default.node_sound_stone_defaults(), +}) + +--lbm to convert the old cobble_with_plaster to the new chalked_bricks to keep texture consistent +minetest.register_lbm({ + name="darkage:convert_cobble_with_plaster", + nodenames= "darkage:cobble_with_plaster", + run_at_every_load = false, + action = function(pos,node) + node.name = "darkage:chalked_bricks_with_plaster" + minetest.swap_node(pos, node) + end +}) + +--[[ + Gneiss +]] +minetest.register_node("darkage:gneiss", { + description = "Gneiss", + tiles = {"darkage_gneiss.png"}, + is_ground_content = true, + groups = {cracky = 3, stone = 1}, + drop = get_node_drops("darkage:gneiss", "darkage:gneiss_rubble"), + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:gneiss_rubble", { + description = "Gneiss Rubble", + tiles = {"darkage_gneiss_rubble.png"}, + is_ground_content = false, + groups = {cracky = 3, stone = 2}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:gneiss_brick", { + description = "Gneiss Brick", + tiles = {"darkage_gneiss_brick.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:gneiss_block", { + description = "Gneiss Block", + tiles = {"darkage_gneiss_block.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults() +}) + +--[[ + Marble +]] +minetest.register_node("darkage:marble", { + description = "Marble", + tiles = {"darkage_marble.png"}, + is_ground_content = true, + groups = {cracky = 3, stone = 1}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:marble_tile", { + description = "Marble Tile", + tiles = {"darkage_marble_tile.png"}, + is_ground_content = false, + groups = {cracky=2}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:mud", { + description = "Mud", + tiles = {"darkage_mud_up.png","darkage_mud.png"}, + is_ground_content = true, + groups = {crumbly=3}, + drop = 'darkage:mud_lump 4', + sounds = default.node_sound_dirt_defaults({ + footstep = "", + }), +}) + +--[[ + Old Red Sandstone +]] +minetest.register_node("darkage:ors", { + description = "Old Red Sandstone", + tiles = {"darkage_ors.png"}, + is_ground_content = true, + drop = "darkage:ors_rubble", + groups = {cracky=2}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:ors_rubble", { + description = "Old Red Sandstone Rubble", + tiles = {"darkage_ors_rubble.png"}, + is_ground_content = true, + groups = {cracky = 3, crumbly=2, stone = 2}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:ors_brick", { + description = "Old Red Sandstone Brick", + tiles = {"darkage_ors_brick.png"}, + is_ground_content = false, + groups = {cracky = 3, stone = 2}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:ors_block", { + description = "Old Red Sandstone Block", + tiles = {"darkage_ors_block.png"}, + is_ground_content = false, + groups = {cracky = 3, stone = 2}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:serpentine", { + description = "Serpentine", + tiles = {"darkage_serpentine.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:shale", { + description = "Shale", + tiles = {"darkage_shale.png","darkage_shale.png","darkage_shale_side.png"}, + is_ground_content = true, + groups = {crumbly=2,cracky=2}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:schist", { + description = "Schist", + tiles = {"darkage_schist.png"}, + is_ground_content = true, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:silt", { + description = "Silt", + tiles = {"darkage_silt.png"}, + is_ground_content = true, + groups = {crumbly=3}, + drop = 'darkage:silt_lump 4', + sounds = default.node_sound_dirt_defaults({ + footstep = "", + }), +}) + +--[[ + Slate +]] +minetest.register_node("darkage:slate", { + description = "Slate", + tiles = {"darkage_slate.png","darkage_slate.png","darkage_slate_side.png"}, + is_ground_content = true, + drop = 'darkage:slate_rubble', + groups = {cracky=2, level=4}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:slate_rubble", { + description = "Slate Rubble", + tiles = {"darkage_slate_rubble.png"}, + is_ground_content = false, + groups = {cracky=2, level=4}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:slate_tile", { + description = "Slate Tile", + tiles = {"darkage_slate_tile.png"}, + is_ground_content = false, + groups = {cracky=2, level=4}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:slate_block", { + description = "Slate Block", + tiles = {"darkage_slate_block.png"}, + is_ground_content = false, + groups = {cracky=2, level=4}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:slate_brick", { + description = "Slate Brick", + tiles = {"darkage_slate_brick.png"}, + is_ground_content = false, + groups = {cracky=2, level=4}, + sounds = default.node_sound_stone_defaults() +}) + +-- Removed straw, because its in minetest game. Registering alias for compatibility reasons +minetest.register_alias("darkage:straw", "farming:straw") + +minetest.register_node("darkage:stone_brick", { + description = "Stone Brick", + tiles = {"darkage_stone_brick.png"}, + is_ground_content = false, + groups = {cracky=3}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:straw_bale", { + description = "Straw Bale", + tiles = {"darkage_straw_bale.png"}, + is_ground_content = false, + drop = 'farming:straw 4', + groups = {snappy=2, flammable=2}, + sounds = default.node_sound_leaves_defaults(), +}) + +--[[ + Tuff +]] +minetest.register_node("darkage:tuff", { + description = "Tuff", + tiles = {"darkage_tuff.png"}, + is_ground_content = true, + legacy_mineral = true, + groups = {cracky = 3, stone = 1, level=4}, + drop = { + max_items = 1, + items = { + { + -- player get tuff node if he is lucky :) + items = {'darkage:tuff'}, + rarity = 3, + }, + { + -- player will get rubble with 2/3 chance + items = {'darkage:tuff_rubble'}, + } + + } + }, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:tuff_bricks", { + description = "Tuff Bricks", + tiles = {"darkage_tuff_bricks.png"}, + is_ground_content = false, + groups = {cracky=2, level=4}, + sounds = default.node_sound_stone_defaults() +}) + +-- abm to turn Tuff bricks to old Tuff bricks if water is nearby +minetest.register_abm({ + nodenames = {"darkage:tuff_bricks"}, + neighbors = {"group:water"}, + interval = 16, + chance = 200, + catch_up = false, + action = function(pos, node) + minetest.set_node(pos, {name = "darkage:old_tuff_bricks"}) + end +}) + +minetest.register_node("darkage:tuff_rubble", { + description = "Tuff Rubble", + tiles = {"darkage_tuff_rubble.png"}, + groups = {crumbly = 2, cracky = 2, falling_node = 1, level=4}, + sounds = default.node_sound_gravel_defaults(), +}) +--[[ + Rhyolitic Tuff +]] +minetest.register_node("darkage:rhyolitic_tuff", { + description = "Rhyolitic Tuff", + tiles = {"darkage_rhyolitic_tuff.png"}, + is_ground_content = true, + legacy_mineral = true, + groups = {cracky = 3, stone = 1, level=4}, + drop = { + max_items = 1, + items = { + { + -- player get tuff node if he is lucky :) + items = {'darkage:rhyolitic_tuff'}, + rarity = 3, + }, + { + -- player will get rubble with 2/3 chance + items = {'darkage:rhyolitic_tuff_rubble'}, + } + + } + }, + sounds = default.node_sound_stone_defaults() +}) + + + +minetest.register_node("darkage:rhyolitic_tuff_bricks", { + description = "Rhyolitic Tuff Bricks", + tiles = {"darkage_rhyolitic_tuff_bricks.png"}, + is_ground_content = false, + groups = {cracky=2, level=4}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:old_tuff_bricks", { + description = "Old Tuff Bricks", + tiles = {"darkage_old_tuff_bricks.png"}, + is_ground_content = false, + groups = {cracky=3, level=4}, + sounds = default.node_sound_stone_defaults() +}) + +minetest.register_node("darkage:rhyolitic_tuff_rubble", { + description = "Rhyolitic Tuff Rubble", + tiles = {"darkage_rhyolitic_tuff_rubble.png"}, + groups = {crumbly = 2, falling_node = 1, level=4}, + sounds = default.node_sound_gravel_defaults(), +}) + + +--[[ + add a node using the cobble texture that was introduced in minetest 0.4.dev-20120408 and got removed in 0.4.7 + It has a nice contrast together the stone bricks, so I think it could get usefull. +]] +minetest.register_node("darkage:chalked_bricks", { + description = "Chalked Brick", + tiles = {"darkage_chalked_bricks.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "darkage:chalked_bricks 4", + recipe = { + {"default:stone", "default:stone", "darkage:chalk_powder"}, + {"darkage:chalk_powder", "darkage:chalk_powder", "darkage:chalk_powder"}, + {"default:stone", "darkage:chalk_powder", "default:stone"}, + } +}) diff --git a/mods/darkage/stairs.lua b/mods/darkage/stairs.lua new file mode 100644 index 0000000..1f2e988 --- /dev/null +++ b/mods/darkage/stairs.lua @@ -0,0 +1,29 @@ + +-- Registration of Stairs (Alphabetical order) +darkage.register_stairs("darkage:basalt") +darkage.register_stairs("darkage:basalt_brick") +darkage.register_stairs("darkage:basalt_rubble") +darkage.register_stairs("darkage:chalked_bricks") +darkage.register_stairs("darkage:gneiss") +darkage.register_stairs("darkage:gneiss_brick") +darkage.register_stairs("darkage:gneiss_rubble") +darkage.register_stairs("darkage:marble") +darkage.register_stairs("darkage:marble_tile") +darkage.register_stairs("darkage:old_tuff_bricks") +darkage.register_stairs("darkage:ors") +darkage.register_stairs("darkage:ors_brick") +darkage.register_stairs("darkage:ors_rubble") +darkage.register_stairs("darkage:rhyolitic_tuff") +darkage.register_stairs("darkage:rhyolitic_tuff_bricks") +darkage.register_stairs("darkage:schist") +darkage.register_stairs("darkage:serpentine") +darkage.register_stairs("darkage:shale") +darkage.register_stairs("darkage:slate") +darkage.register_stairs("darkage:slate_brick") +darkage.register_stairs("darkage:slate_rubble") +darkage.register_stairs("darkage:slate_tile") +darkage.register_stairs("darkage:stone_brick") +darkage.register_stairs("darkage:straw_bale") +darkage.register_stairs("darkage:tuff") +darkage.register_stairs("darkage:tuff_bricks") + diff --git a/mods/darkage/stairs_functions.lua b/mods/darkage/stairs_functions.lua new file mode 100644 index 0000000..947b252 --- /dev/null +++ b/mods/darkage/stairs_functions.lua @@ -0,0 +1,39 @@ +if minetest.get_modpath("moreblocks") then + function darkage.register_stairs(nodeName) + local ndef = assert(minetest.registered_nodes[nodeName], "Error: "..nodeName.." is not registered") + + local mod = "darkage" + local node = nodeName:split(":")[2] + + local def = table.copy(ndef) + def.drop = nil + + stairsplus:register_all(mod, node, nodeName, def) + end +elseif minetest.get_modpath("stairs") then + function darkage.register_stairs(nodeName) + local ndef = assert(minetest.registered_nodes[nodeName], "Error: "..nodeName.." is not registered") + + local node = nodeName:split(":")[2] + + -- The stairs api does not allow to use the darkage modname, so we have to call the nodes stairs:stair_darkage_ + -- and creating an alias + local subname = "darkage_".. node; + stairs.register_stair_and_slab(subname, nodeName, + ndef.groups, ndef.tiles, + ndef.description.." Stair", ndef.description.." Slab", + ndef.sounds) + + --stairs.register_stair_and_slab(subname, recipeitem, + -- groups, images, + -- desc_stair, desc_slab, sounds) + minetest.register_alias("darkage:stair_"..node, "stairs:stair_darkage_"..node) + minetest.register_alias("darkage:slab_"..node, "stairs:slab_darkage_"..node) + end +else + -- No compatible stairs mod found. + minetest.log("error", "[darkage] Darkage requires at least moreblocks or stairs to be installed. Its not possible to register stairs.") + function darkage.register_stairs(nodeName) + minetest.log("warning", "could not create stair of type "..nodeName .." because no compatible stairs mod is installed.") + end +end diff --git a/mods/darkage/textures/darkage_adobe.png b/mods/darkage/textures/darkage_adobe.png new file mode 100644 index 0000000..90767d7 Binary files /dev/null and b/mods/darkage/textures/darkage_adobe.png differ diff --git a/mods/darkage/textures/darkage_basalt.png b/mods/darkage/textures/darkage_basalt.png new file mode 100644 index 0000000..cdbe977 Binary files /dev/null and b/mods/darkage/textures/darkage_basalt.png differ diff --git a/mods/darkage/textures/darkage_basalt_block.png b/mods/darkage/textures/darkage_basalt_block.png new file mode 100644 index 0000000..27a4459 Binary files /dev/null and b/mods/darkage/textures/darkage_basalt_block.png differ diff --git a/mods/darkage/textures/darkage_basalt_brick.png b/mods/darkage/textures/darkage_basalt_brick.png new file mode 100644 index 0000000..f54b078 Binary files /dev/null and b/mods/darkage/textures/darkage_basalt_brick.png differ diff --git a/mods/darkage/textures/darkage_basalt_rubble.png b/mods/darkage/textures/darkage_basalt_rubble.png new file mode 100644 index 0000000..334f5bf Binary files /dev/null and b/mods/darkage/textures/darkage_basalt_rubble.png differ diff --git a/mods/darkage/textures/darkage_box.png b/mods/darkage/textures/darkage_box.png new file mode 100644 index 0000000..7bef3e2 Binary files /dev/null and b/mods/darkage/textures/darkage_box.png differ diff --git a/mods/darkage/textures/darkage_box_top.png b/mods/darkage/textures/darkage_box_top.png new file mode 100644 index 0000000..49c803e Binary files /dev/null and b/mods/darkage/textures/darkage_box_top.png differ diff --git a/mods/darkage/textures/darkage_chain.png b/mods/darkage/textures/darkage_chain.png new file mode 100644 index 0000000..c066ab6 Binary files /dev/null and b/mods/darkage/textures/darkage_chain.png differ diff --git a/mods/darkage/textures/darkage_chalk.png b/mods/darkage/textures/darkage_chalk.png new file mode 100644 index 0000000..0ed5faa Binary files /dev/null and b/mods/darkage/textures/darkage_chalk.png differ diff --git a/mods/darkage/textures/darkage_chalk_powder.png b/mods/darkage/textures/darkage_chalk_powder.png new file mode 100644 index 0000000..621bf99 Binary files /dev/null and b/mods/darkage/textures/darkage_chalk_powder.png differ diff --git a/mods/darkage/textures/darkage_chalked_bricks.png b/mods/darkage/textures/darkage_chalked_bricks.png new file mode 100644 index 0000000..32914bc Binary files /dev/null and b/mods/darkage/textures/darkage_chalked_bricks.png differ diff --git a/mods/darkage/textures/darkage_darkdirt.png b/mods/darkage/textures/darkage_darkdirt.png new file mode 100644 index 0000000..dd2b072 Binary files /dev/null and b/mods/darkage/textures/darkage_darkdirt.png differ diff --git a/mods/darkage/textures/darkage_dry_leaves.png b/mods/darkage/textures/darkage_dry_leaves.png new file mode 100644 index 0000000..cdac2aa Binary files /dev/null and b/mods/darkage/textures/darkage_dry_leaves.png differ diff --git a/mods/darkage/textures/darkage_glass.png b/mods/darkage/textures/darkage_glass.png new file mode 100644 index 0000000..874ac26 Binary files /dev/null and b/mods/darkage/textures/darkage_glass.png differ diff --git a/mods/darkage/textures/darkage_glass_round.png b/mods/darkage/textures/darkage_glass_round.png new file mode 100644 index 0000000..dceeb74 Binary files /dev/null and b/mods/darkage/textures/darkage_glass_round.png differ diff --git a/mods/darkage/textures/darkage_glass_square.png b/mods/darkage/textures/darkage_glass_square.png new file mode 100644 index 0000000..d72883d Binary files /dev/null and b/mods/darkage/textures/darkage_glass_square.png differ diff --git a/mods/darkage/textures/darkage_glow_glass.png b/mods/darkage/textures/darkage_glow_glass.png new file mode 100644 index 0000000..b7db572 Binary files /dev/null and b/mods/darkage/textures/darkage_glow_glass.png differ diff --git a/mods/darkage/textures/darkage_glow_glass_round.png b/mods/darkage/textures/darkage_glow_glass_round.png new file mode 100644 index 0000000..3923082 Binary files /dev/null and b/mods/darkage/textures/darkage_glow_glass_round.png differ diff --git a/mods/darkage/textures/darkage_glow_glass_square.png b/mods/darkage/textures/darkage_glow_glass_square.png new file mode 100644 index 0000000..ce5850e Binary files /dev/null and b/mods/darkage/textures/darkage_glow_glass_square.png differ diff --git a/mods/darkage/textures/darkage_gneiss.png b/mods/darkage/textures/darkage_gneiss.png new file mode 100644 index 0000000..d344a1f Binary files /dev/null and b/mods/darkage/textures/darkage_gneiss.png differ diff --git a/mods/darkage/textures/darkage_gneiss_block.png b/mods/darkage/textures/darkage_gneiss_block.png new file mode 100644 index 0000000..c21e03e Binary files /dev/null and b/mods/darkage/textures/darkage_gneiss_block.png differ diff --git a/mods/darkage/textures/darkage_gneiss_brick.png b/mods/darkage/textures/darkage_gneiss_brick.png new file mode 100644 index 0000000..6585e0c Binary files /dev/null and b/mods/darkage/textures/darkage_gneiss_brick.png differ diff --git a/mods/darkage/textures/darkage_gneiss_rubble.png b/mods/darkage/textures/darkage_gneiss_rubble.png new file mode 100644 index 0000000..adba739 Binary files /dev/null and b/mods/darkage/textures/darkage_gneiss_rubble.png differ diff --git a/mods/darkage/textures/darkage_iron_bars.png b/mods/darkage/textures/darkage_iron_bars.png new file mode 100644 index 0000000..98a6813 Binary files /dev/null and b/mods/darkage/textures/darkage_iron_bars.png differ diff --git a/mods/darkage/textures/darkage_iron_grille.png b/mods/darkage/textures/darkage_iron_grille.png new file mode 100644 index 0000000..14ce6a9 Binary files /dev/null and b/mods/darkage/textures/darkage_iron_grille.png differ diff --git a/mods/darkage/textures/darkage_iron_stick.png b/mods/darkage/textures/darkage_iron_stick.png new file mode 100644 index 0000000..d248698 Binary files /dev/null and b/mods/darkage/textures/darkage_iron_stick.png differ diff --git a/mods/darkage/textures/darkage_lamp.png b/mods/darkage/textures/darkage_lamp.png new file mode 100644 index 0000000..38abcd6 Binary files /dev/null and b/mods/darkage/textures/darkage_lamp.png differ diff --git a/mods/darkage/textures/darkage_marble.png b/mods/darkage/textures/darkage_marble.png new file mode 100644 index 0000000..c0032b8 Binary files /dev/null and b/mods/darkage/textures/darkage_marble.png differ diff --git a/mods/darkage/textures/darkage_marble_tile.png b/mods/darkage/textures/darkage_marble_tile.png new file mode 100644 index 0000000..a3553ef Binary files /dev/null and b/mods/darkage/textures/darkage_marble_tile.png differ diff --git a/mods/darkage/textures/darkage_milk_glass.png b/mods/darkage/textures/darkage_milk_glass.png new file mode 100644 index 0000000..c16b9ef Binary files /dev/null and b/mods/darkage/textures/darkage_milk_glass.png differ diff --git a/mods/darkage/textures/darkage_milk_glass_round.png b/mods/darkage/textures/darkage_milk_glass_round.png new file mode 100644 index 0000000..b2cffe2 Binary files /dev/null and b/mods/darkage/textures/darkage_milk_glass_round.png differ diff --git a/mods/darkage/textures/darkage_milk_glass_square.png b/mods/darkage/textures/darkage_milk_glass_square.png new file mode 100644 index 0000000..c54cfad Binary files /dev/null and b/mods/darkage/textures/darkage_milk_glass_square.png differ diff --git a/mods/darkage/textures/darkage_mud.png b/mods/darkage/textures/darkage_mud.png new file mode 100644 index 0000000..b0b08d2 Binary files /dev/null and b/mods/darkage/textures/darkage_mud.png differ diff --git a/mods/darkage/textures/darkage_mud_lump.png b/mods/darkage/textures/darkage_mud_lump.png new file mode 100644 index 0000000..1c3732c Binary files /dev/null and b/mods/darkage/textures/darkage_mud_lump.png differ diff --git a/mods/darkage/textures/darkage_mud_up.png b/mods/darkage/textures/darkage_mud_up.png new file mode 100644 index 0000000..54ec673 Binary files /dev/null and b/mods/darkage/textures/darkage_mud_up.png differ diff --git a/mods/darkage/textures/darkage_old_tuff_bricks.png b/mods/darkage/textures/darkage_old_tuff_bricks.png new file mode 100644 index 0000000..b93ee85 Binary files /dev/null and b/mods/darkage/textures/darkage_old_tuff_bricks.png differ diff --git a/mods/darkage/textures/darkage_ors.png b/mods/darkage/textures/darkage_ors.png new file mode 100644 index 0000000..f04886d Binary files /dev/null and b/mods/darkage/textures/darkage_ors.png differ diff --git a/mods/darkage/textures/darkage_ors_block.png b/mods/darkage/textures/darkage_ors_block.png new file mode 100644 index 0000000..d313bde Binary files /dev/null and b/mods/darkage/textures/darkage_ors_block.png differ diff --git a/mods/darkage/textures/darkage_ors_brick.png b/mods/darkage/textures/darkage_ors_brick.png new file mode 100644 index 0000000..9b7d674 Binary files /dev/null and b/mods/darkage/textures/darkage_ors_brick.png differ diff --git a/mods/darkage/textures/darkage_ors_rubble.png b/mods/darkage/textures/darkage_ors_rubble.png new file mode 100644 index 0000000..91585b9 Binary files /dev/null and b/mods/darkage/textures/darkage_ors_rubble.png differ diff --git a/mods/darkage/textures/darkage_plaster_mask_A.png b/mods/darkage/textures/darkage_plaster_mask_A.png new file mode 100644 index 0000000..5c7388d Binary files /dev/null and b/mods/darkage/textures/darkage_plaster_mask_A.png differ diff --git a/mods/darkage/textures/darkage_plaster_mask_B.png b/mods/darkage/textures/darkage_plaster_mask_B.png new file mode 100644 index 0000000..ae3028c Binary files /dev/null and b/mods/darkage/textures/darkage_plaster_mask_B.png differ diff --git a/mods/darkage/textures/darkage_plaster_mask_C.png b/mods/darkage/textures/darkage_plaster_mask_C.png new file mode 100644 index 0000000..ca84a7c Binary files /dev/null and b/mods/darkage/textures/darkage_plaster_mask_C.png differ diff --git a/mods/darkage/textures/darkage_plaster_mask_D.png b/mods/darkage/textures/darkage_plaster_mask_D.png new file mode 100644 index 0000000..05348fd Binary files /dev/null and b/mods/darkage/textures/darkage_plaster_mask_D.png differ diff --git a/mods/darkage/textures/darkage_reinforce.png b/mods/darkage/textures/darkage_reinforce.png new file mode 100644 index 0000000..8249931 Binary files /dev/null and b/mods/darkage/textures/darkage_reinforce.png differ diff --git a/mods/darkage/textures/darkage_reinforce_arrow.png b/mods/darkage/textures/darkage_reinforce_arrow.png new file mode 100644 index 0000000..6c23fa0 Binary files /dev/null and b/mods/darkage/textures/darkage_reinforce_arrow.png differ diff --git a/mods/darkage/textures/darkage_reinforce_bars.png b/mods/darkage/textures/darkage_reinforce_bars.png new file mode 100644 index 0000000..8fa8686 Binary files /dev/null and b/mods/darkage/textures/darkage_reinforce_bars.png differ diff --git a/mods/darkage/textures/darkage_reinforce_left.png b/mods/darkage/textures/darkage_reinforce_left.png new file mode 100644 index 0000000..2464e95 Binary files /dev/null and b/mods/darkage/textures/darkage_reinforce_left.png differ diff --git a/mods/darkage/textures/darkage_reinforce_right.png b/mods/darkage/textures/darkage_reinforce_right.png new file mode 100644 index 0000000..4900f50 Binary files /dev/null and b/mods/darkage/textures/darkage_reinforce_right.png differ diff --git a/mods/darkage/textures/darkage_rhyolitic_tuff.png b/mods/darkage/textures/darkage_rhyolitic_tuff.png new file mode 100644 index 0000000..ebe8a72 Binary files /dev/null and b/mods/darkage/textures/darkage_rhyolitic_tuff.png differ diff --git a/mods/darkage/textures/darkage_rhyolitic_tuff_bricks.png b/mods/darkage/textures/darkage_rhyolitic_tuff_bricks.png new file mode 100644 index 0000000..bc8a20c Binary files /dev/null and b/mods/darkage/textures/darkage_rhyolitic_tuff_bricks.png differ diff --git a/mods/darkage/textures/darkage_rhyolitic_tuff_rubble.png b/mods/darkage/textures/darkage_rhyolitic_tuff_rubble.png new file mode 100644 index 0000000..31605a0 Binary files /dev/null and b/mods/darkage/textures/darkage_rhyolitic_tuff_rubble.png differ diff --git a/mods/darkage/textures/darkage_schist.png b/mods/darkage/textures/darkage_schist.png new file mode 100644 index 0000000..e4396d9 Binary files /dev/null and b/mods/darkage/textures/darkage_schist.png differ diff --git a/mods/darkage/textures/darkage_serpentine.png b/mods/darkage/textures/darkage_serpentine.png new file mode 100644 index 0000000..8ba4d17 Binary files /dev/null and b/mods/darkage/textures/darkage_serpentine.png differ diff --git a/mods/darkage/textures/darkage_shale.png b/mods/darkage/textures/darkage_shale.png new file mode 100644 index 0000000..f98237b Binary files /dev/null and b/mods/darkage/textures/darkage_shale.png differ diff --git a/mods/darkage/textures/darkage_shale_side.png b/mods/darkage/textures/darkage_shale_side.png new file mode 100644 index 0000000..7d37804 Binary files /dev/null and b/mods/darkage/textures/darkage_shale_side.png differ diff --git a/mods/darkage/textures/darkage_shelves.png b/mods/darkage/textures/darkage_shelves.png new file mode 100644 index 0000000..0dbe4b9 Binary files /dev/null and b/mods/darkage/textures/darkage_shelves.png differ diff --git a/mods/darkage/textures/darkage_shelves_front.png b/mods/darkage/textures/darkage_shelves_front.png new file mode 100644 index 0000000..ca6abd6 Binary files /dev/null and b/mods/darkage/textures/darkage_shelves_front.png differ diff --git a/mods/darkage/textures/darkage_silt.png b/mods/darkage/textures/darkage_silt.png new file mode 100644 index 0000000..f0e0fc9 Binary files /dev/null and b/mods/darkage/textures/darkage_silt.png differ diff --git a/mods/darkage/textures/darkage_silt_lump.png b/mods/darkage/textures/darkage_silt_lump.png new file mode 100644 index 0000000..3bb5111 Binary files /dev/null and b/mods/darkage/textures/darkage_silt_lump.png differ diff --git a/mods/darkage/textures/darkage_slate.png b/mods/darkage/textures/darkage_slate.png new file mode 100644 index 0000000..aaf7d83 Binary files /dev/null and b/mods/darkage/textures/darkage_slate.png differ diff --git a/mods/darkage/textures/darkage_slate_block.png b/mods/darkage/textures/darkage_slate_block.png new file mode 100644 index 0000000..523eeea Binary files /dev/null and b/mods/darkage/textures/darkage_slate_block.png differ diff --git a/mods/darkage/textures/darkage_slate_brick.png b/mods/darkage/textures/darkage_slate_brick.png new file mode 100644 index 0000000..77df4ee Binary files /dev/null and b/mods/darkage/textures/darkage_slate_brick.png differ diff --git a/mods/darkage/textures/darkage_slate_rubble.png b/mods/darkage/textures/darkage_slate_rubble.png new file mode 100644 index 0000000..5bd1f73 Binary files /dev/null and b/mods/darkage/textures/darkage_slate_rubble.png differ diff --git a/mods/darkage/textures/darkage_slate_side.png b/mods/darkage/textures/darkage_slate_side.png new file mode 100644 index 0000000..da9e90f Binary files /dev/null and b/mods/darkage/textures/darkage_slate_side.png differ diff --git a/mods/darkage/textures/darkage_slate_tile.png b/mods/darkage/textures/darkage_slate_tile.png new file mode 100644 index 0000000..9599f45 Binary files /dev/null and b/mods/darkage/textures/darkage_slate_tile.png differ diff --git a/mods/darkage/textures/darkage_stone_brick.png b/mods/darkage/textures/darkage_stone_brick.png new file mode 100644 index 0000000..b0b79f9 Binary files /dev/null and b/mods/darkage/textures/darkage_stone_brick.png differ diff --git a/mods/darkage/textures/darkage_straw_bale.png b/mods/darkage/textures/darkage_straw_bale.png new file mode 100644 index 0000000..c8c1f0c Binary files /dev/null and b/mods/darkage/textures/darkage_straw_bale.png differ diff --git a/mods/darkage/textures/darkage_tuff.png b/mods/darkage/textures/darkage_tuff.png new file mode 100644 index 0000000..41abc6e Binary files /dev/null and b/mods/darkage/textures/darkage_tuff.png differ diff --git a/mods/darkage/textures/darkage_tuff_bricks.png b/mods/darkage/textures/darkage_tuff_bricks.png new file mode 100644 index 0000000..ce48da5 Binary files /dev/null and b/mods/darkage/textures/darkage_tuff_bricks.png differ diff --git a/mods/darkage/textures/darkage_tuff_rubble.png b/mods/darkage/textures/darkage_tuff_rubble.png new file mode 100644 index 0000000..7a61f0d Binary files /dev/null and b/mods/darkage/textures/darkage_tuff_rubble.png differ diff --git a/mods/darkage/textures/darkage_wood_bars.png b/mods/darkage/textures/darkage_wood_bars.png new file mode 100644 index 0000000..289d20b Binary files /dev/null and b/mods/darkage/textures/darkage_wood_bars.png differ diff --git a/mods/darkage/textures/darkage_wood_frame.png b/mods/darkage/textures/darkage_wood_frame.png new file mode 100644 index 0000000..65e29f3 Binary files /dev/null and b/mods/darkage/textures/darkage_wood_frame.png differ diff --git a/mods/darkage/textures/darkage_wood_grille.png b/mods/darkage/textures/darkage_wood_grille.png new file mode 100644 index 0000000..0346ce9 Binary files /dev/null and b/mods/darkage/textures/darkage_wood_grille.png differ diff --git a/mods/darkage/walls.lua b/mods/darkage/walls.lua new file mode 100644 index 0000000..66dd0f8 --- /dev/null +++ b/mods/darkage/walls.lua @@ -0,0 +1,49 @@ +local node_box = { + type = "connected", + fixed = {{-1/4, -1/2, -1/4, 1/4, 1/2, 1/4}}, + -- connect_bottom = + connect_front = {{-3/16, -1/2, -1/2, 3/16, 3/8, -1/4}}, + connect_left = {{-1/2, -1/2, -3/16, -1/4, 3/8, 3/16}}, + connect_back = {{-3/16, -1/2, 1/4, 3/16, 3/8, 1/2}}, + connect_right = {{ 1/4, -1/2, -3/16, 1/2, 3/8, 3/16}}, + } + +local register_wall = function(base_node) + + local name = base_node .. "_wall" + local ndef = minetest.registered_nodes[base_node] + local groups = ndef.groups + groups["wall"] = 1 + -- inventory node, and pole-type wall start item + minetest.register_node(name, { + description = ndef.description .. " Wall", + drawtype = "nodebox", + node_box = node_box, + connects_to = {base_node,"group:wall"}, + paramtype = "light", + is_ground_content = false, + tiles = ndef.tiles, + walkable = true, + groups = groups, + sounds = ndef.sounds, + }) + + -- crafting recipe + minetest.register_craft({ + output = name .. " 6", + recipe = { + { '', '', '' }, + { base_node, base_node, base_node}, + { base_node, base_node, base_node}, + } + }) + +end + +register_wall("darkage:basalt_rubble") +register_wall("darkage:ors_rubble") +register_wall("darkage:stone_brick") +register_wall("darkage:slate_rubble") +register_wall("darkage:tuff_bricks") +register_wall("darkage:old_tuff_bricks") +register_wall("darkage:rhyolitic_tuff_bricks") diff --git a/mods/datastorage/README.md b/mods/datastorage/README.md new file mode 100644 index 0000000..b15b07a --- /dev/null +++ b/mods/datastorage/README.md @@ -0,0 +1,22 @@ +datastorage +=========== + +Helper mod to manage players data. +All the mods can acces a single file (container) and easily have the data saved/loaded for them. + +Usage +----- + + local data = datastorage.get(id, ...) + +Returns a reference to a data container. The id is normally a player name. +Following arguments are keys to recurse into, normally only one, a string +describing the type of data, is used. If the container doesn't exist it will +be created, otherwise it will contain all previously stored data. The table +can store any data. Player's containers will be saved to disk when the player +leaves, and all references to the player's data should be dropped. All of the +containers will be saved on server shutdown. To forcibly save a container's +data use: + + datastorage.save(id) + diff --git a/mods/datastorage/init.lua b/mods/datastorage/init.lua new file mode 100644 index 0000000..30677fc --- /dev/null +++ b/mods/datastorage/init.lua @@ -0,0 +1,98 @@ +datastorage = {data = {}} + +local DIR_DELIM = DIR_DELIM or "/" +local data_path = minetest.get_worldpath()..DIR_DELIM.."datastorage"..DIR_DELIM + +function datastorage.save(id) + local data = datastorage.data[id] + -- Check if the container is empty + if not data or not next(data) then return end + for _, sub_data in pairs(data) do + if not next(sub_data) then return end + end + + local file = io.open(data_path..id, "w") + if not file then + -- Most likely the data directory doesn't exist, create it + -- and try again. + if minetest.mkdir then + minetest.mkdir(data_path) + else + -- Using os.execute like this is not very platform + -- independent or safe, but most platforms name their + -- directory creation utility mkdir, the data path is + -- unlikely to contain special characters, and the + -- data path is only mutable by the admin. + os.execute('mkdir "'..data_path..'"') + end + file = io.open(data_path..id, "w") + if not file then return end + end + + local datastr = minetest.serialize(data) + if not datastr then return end + + file:write(datastr) + file:close() + return true +end + +function datastorage.load(id) + local file = io.open(data_path..id, "r") + if not file then return end + + local data = minetest.deserialize(file:read("*all")) + datastorage.data[id] = data + + file:close() + return data +end + +-- Compatability +function datastorage.get_container(player, id) + return datastorage.get(player:get_player_name(), id) +end + +-- Retrieves a value from the data storage +function datastorage.get(id, ...) + local last = datastorage.data[id] + if last == nil then last = datastorage.load(id) end + if last == nil then + last = {} + datastorage.data[id] = last + end + local cur = last + for _, sub_id in ipairs({...}) do + last = cur + cur = cur[sub_id] + if cur == nil then + cur = {} + last[sub_id] = cur + end + end + return cur +end + +-- Saves a container and reomves it from memory +function datastorage.finish(id) + datastorage.save(id) + datastorage.data[id] = nil +end + +-- Compatability +function datastorage.save_container(player) + return datastorage.save(player:get_player_name()) +end + +minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + datastorage.save(player_name) + datastorage.data[player_name] = nil +end) + +minetest.register_on_shutdown(function() + for id in pairs(datastorage.data) do + datastorage.save(id) + end +end) + diff --git a/mods/datastorage/mod.conf b/mods/datastorage/mod.conf new file mode 100644 index 0000000..86aba6d --- /dev/null +++ b/mods/datastorage/mod.conf @@ -0,0 +1 @@ +name = datastorage diff --git a/mods/default/README.txt b/mods/default/README.txt new file mode 100644 index 0000000..be8cbf1 --- /dev/null +++ b/mods/default/README.txt @@ -0,0 +1,388 @@ +Minetest Game mod: default +========================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by celeron55, Perttu Ahola (LGPLv2.1+) +Various Minetest developers and contributors (LGPLv2.1+) + +The torch code was derived by sofar from the 'torches' mod by +BlockMen (LGPLv2.1+) + +Authors of media (textures, sounds, models and schematics) +---------------------------------------------------------- +Everything not listed in here: +celeron55, Perttu Ahola (CC BY-SA 3.0) + + +Textures +-------- +Cisoun's texture pack (CC BY-SA 3.0): + default_jungletree.png + default_lava.png + default_leaves.png + default_sapling.png + default_bush_sapling.png + default_stone.png + default_tree.png + default_tree_top.png + default_water.png + +RealBadAngel's animated water (CC BY-SA 3.0): + default_water_source_animated.png + default_water_flowing_animated.png + +VanessaE (CC BY-SA 3.0): + default_torch_animated.png + default_torch_on_ceiling_animated.png + default_torch_on_floor_animated.png + default_torch_on_floor.png + default_desert_sand.png + default_desert_stone.png + default_sand.png + default_mese_crystal.png + default_mese_crystal_fragment.png + +Calinou (CC BY-SA 3.0): + default_brick.png + default_papyrus.png + default_mineral_copper.png + +PilzAdam (CC BY-SA 3.0): + default_jungleleaves.png + default_junglesapling.png + default_obsidian_glass.png + default_obsidian_shard.png + default_mineral_gold.png + +jojoa1997 (CC BY-SA 3.0): + default_obsidian.png + +InfinityProject (CC BY-SA 3.0): + default_mineral_diamond.png + +Splizard (CC BY-SA 3.0): + default_pine_sapling.png + default_pine_needles.png + +Zeg9 (CC BY-SA 3.0): + default_coal_block.png + +paramat (CC BY-SA 3.0): + wieldhand.png -- Copied from character.png by Jordach (CC BY-SA 3.0) + default_pinetree.png + default_pinetree_top.png + default_pinewood.png + default_acacia_leaves.png + default_acacia_leaves_simple.png + default_acacia_sapling.png + default_acacia_bush_sapling.png + default_pine_bush_sapling.png + default_acacia_tree.png + default_acacia_tree_top.png + default_acacia_wood.png + default_acacia_bush_stem.png + default_bush_stem.png + default_pine_bush_stem.png + default_junglewood.png + default_jungletree_top.png + default_sandstone_brick.png + default_obsidian_brick.png + default_stone_brick.png + default_desert_stone_brick.png + default_sandstone_block.png + default_obsidian_block.png + default_stone_block.png + default_desert_stone_block.png + default_river_water.png + default_river_water_source_animated.png + default_river_water_flowing_animated.png + default_dry_grass.png + default_dry_grass_side.png + default_dry_grass_*.png + default_grass_side.png -- Derived from a texture by TumeniNodes (CC-BY-SA 3.0) + 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 + default_silver_sandstone.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0) + default_silver_sandstone_brick.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0) + default_silver_sandstone_block.png -- Derived from a texture by GreenXenith (CC-BY-SA 3.0) + default_bookshelf_slot.png -- Derived from a texture by Gambit (CC-BY-SA 3.0) + default_marram_grass_*.png -- Derived from textures by TumeniNodes (CC-BY-SA 3.0) + default_emergent_jungle_sapling.png + default_permafrost.png -- Derived from a texture by Neuromancer (CC BY-SA 3.0) + default_stones.png -- Derived from a texture by sofar (CC0 1.0) + default_stones_side.png -- Derived from a texture by sofar (CC0 1.0) + default_moss.png + default_moss_side.png + default_fence_rail_acacia_wood + default_fence_rail_aspen_wood -- Derived from a texture by sofar (CC BY-SA 3.0) + default_fence_rail_junglewood + default_fence_rail_pine_wood + default_fence_rail_wood -- Derived from a texture by BlockMen (CC BY-SA 3.0) + gui_hotbar.png + gui_hotbar_selected.png + +TumeniNodes (CC BY-SA 3.0): + default_desert_cobble.png -- Derived from a texture by brunob.santos (CC BY-SA 3.0) + default_coniferous_litter.png + default_coniferous_litter_side.png + default_grass.png + default_dry_dirt.png + +BlockMen (CC BY-SA 3.0): + default_aspen_leaves.png -- Derived from Sofar's texture + default_wood.png + default_clay_brick.png + default_iron_ingot.png + default_gold_ingot.png + default_tool_steelsword.png + default_diamond.png + default_tool_*.png + default_lava_source_animated.png + default_lava_flowing_animated.png + default_stick.png + default_chest_front.png + default_chest_lock.png + default_chest_side.png + default_chest_top.png + default_mineral_mese.png + default_meselamp.png + gui_formbg.png + gui_furnace_arrow_bg.png + gui_furnace_arrow_fg.png + gui_hb_bg.png + +sofar (CC BY-SA 3.0): + default_aspen_sapling + default_aspen_tree + default_aspen_tree_top, derived from default_pine_tree_top (by paramat) + default_aspen_wood, derived from default_pine_wood (by paramat) + default_chest_inside + +sofar (CC0 1.0): + default_gravel.png -- Derived from Gambit's PixelBOX texture pack light gravel + +Neuromancer (CC BY-SA 3.0): + default_cobble.png, based on texture by Brane praefect + default_mossycobble.png, based on texture by Brane praefect + default_furnace_*.png + +Gambit (CC BY-SA 3.0): + default_bronze_ingot.png + default_copper_ingot.png + default_copper_lump.png + default_iron_lump.png + default_gold_lump.png + default_clay_lump.png + default_coal.png + default_grass_*.png + default_paper.png + default_diamond_block.png + default_ladder_steel.png + default_sign_wall_wood.png + default_flint.png + default_snow.png + default_snow_side.png + default_snowball.png + default_key.png + default_key_skeleton.png + default_book.png + +asl97 (CC BY-SA 3.0): + default_ice.png + +Pithydon (CC BY-SA 3.0) + default_coral_brown.png + default_coral_orange.png + default_coral_skeleton.png + +Ferk (CC0 1.0): + default_item_smoke.png + +npx (CC BY-SA 3.0): + default_rainforest_litter.png + default_rainforest_litter_side.png + +kaeza (CC-BY-SA 3.0): + default_desert_sandstone.png + default_desert_sandstone_brick.png + default_desert_sandstone_block.png + +kilbith (CC BY-SA 3.0): + default_steel_block.png + default_copper_block.png + default_bronze_block.png + default_gold_block.png + default_tin_block.png + default_mineral_tin.png + default_tin_ingot.png + default_tin_lump.png + +tobyplowy (CC BY-SA 3.0): + default_kelp.png + +CloudyProton (CC BY-SA 3.0): + default_book_written.png, based on default_book.png by Gambit + +Mossmanikin (CC BY-SA 3.0): + default_fern_*.png + +random-geek (CC BY-SA 3.0): + default_blueberries.png + default_blueberry_overlay.png + default_blueberry_bush_leaves.png, derived from default_bush_leaves (by paramat) + default_blueberry_bush_sapling.png + default_dirt.png -- Derived from a texture by Neuromancer (CC BY-SA 3.0) + +Krock (CC0 1.0): + default_glass.png + default_glass_detail.png + +Topywo (CC BY-SA 3.0) + default_coral_cyan.png + default_coral_green.png + default_coral_pink.png + +Extex101 (CC BY-SA 3.0) + default_large_cactus_seedling.png + default_dry_shrub.png -- Derived from the original texture by celeron55 + +An0n3m0us (CC BY-SA 3.0): + heart.png -- Derived from a texture by KevDoy (CC BY-SA 3.0) + bubble.png -- Derived from a texture by BlockMen (CC BY-SA 3.0) + + +Sounds +------ +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/ + 3: http://www.freesound.org/people/lsprice/sounds/88808/ + +Mito551 (sounds) (CC BY-SA 3.0): + default_dig_choppy.ogg + default_dig_cracky.ogg + default_dig_crumbly.1.ogg + default_dig_crumbly.2.ogg + default_dig_dig_immediate.ogg + default_dig_oddly_breakable_by_hand.ogg + default_dug_node.1.ogg + default_dug_node.2.ogg + default_grass_footstep.1.ogg + default_grass_footstep.2.ogg + default_grass_footstep.3.ogg + default_gravel_footstep.1.ogg + default_gravel_footstep.2.ogg + default_gravel_footstep.3.ogg + default_gravel_footstep.4.ogg + default_grass_footstep.1.ogg + default_place_node.1.ogg + default_place_node.2.ogg + default_place_node.3.ogg + default_place_node_hard.1.ogg + default_place_node_hard.2.ogg + default_hard_footstep.1.ogg + default_hard_footstep.2.ogg + default_hard_footstep.3.ogg + default_sand_footstep.1.ogg + default_sand_footstep.2.ogg + default_wood_footstep.1.ogg + default_wood_footstep.2.ogg + default_dirt_footstep.1.ogg + default_dirt_footstep.2.ogg + default_glass_footstep.ogg + +Metal sounds: + default_dig_metal.ogg - yadronoff - CC-BY-3.0 + - https://www.freesound.org/people/yadronoff/sounds/320397/ + default_dug_metal.*.ogg - Iwan Gabovitch - qubodup - CC0 + - http://opengameart.org/users/qubodup + default_metal_footstep.*.ogg - Ottomaani138 - CC0 + - https://www.freesound.org/people/Ottomaani138/sounds/232692/ + default_place_node_metal.*.ogg - Ogrebane - CC0 + - http://opengameart.org/content/wood-and-metal-sound-effects-volume-2 + +Tool breaking sounds added by sofar: CC-BY-3.0 + default_tool_breaks.* - http://www.freesound.org/people/HerbertBoland/sounds/33206/ + +AGFX (CC BY 3.0): +https://www.freesound.org/people/AGFX/packs/1253/ + default_water_footstep.1.ogg + default_water_footstep.2.ogg + default_water_footstep.3.ogg +(default_water_footstep.4.ogg is silent) + +blukotek (CC0 1.0): +https://www.freesound.org/people/blukotek/sounds/251660/ + default_dig_snappy.ogg + +Chests sounds added by sofar, derived of several files mixed together: + default_chest_open.ogg + default_chest_close.ogg + - http://www.freesound.org/people/Sevin7/sounds/269722/ CC0 + - http://www.freesound.org/people/Percy%20Duke/sounds/23448/ CC-BY-3.0 + - http://www.freesound.org/people/kingsamas/sounds/135576/ CC-BY-3.0 + - http://www.freesound.org/people/bulbastre/sounds/126887/ CC-BY-3.0 + - http://www.freesound.org/people/Yoyodaman234/sounds/183541/ CC0 + +Ryding (CC0 1.0): +http://freesound.org/people/Ryding/sounds/94337/ + default_snow_footstep.*.ogg + +Ferk (CC0 1.0): + default_item_smoke.ogg, based on a sound by http://opengameart.org/users/bart + +sonictechtonic (CC BY 3.0): +https://www.freesound.org/people/sonictechtonic/sounds/241872/ + player_damage.ogg + + +Models +------ +sofar (CC BY-SA 3.0): + chest_open.obj + torch_ceiling.obj + torch_floor.obj + torch_wall.obj + + +Schematics +---------- +paramat (CC BY-SA 3.0): + acacia_bush.mts + acacia_tree.mts + acacia_tree_from_sapling.mts + apple_tree.mts + apple_tree_from_sapling.mts + aspen_tree.mts + aspen_tree_from_sapling.mts + bush.mts + emergent_jungle_tree.mts + emergent_jungle_tree_from_sapling.mts + jungle_tree.mts + jungle_tree_from_sapling.mts + large_cactus.mts + papyrus.mts + pine_tree.mts + pine_tree_from_sapling.mts + snowy_pine_tree_from_sapling.mts + small_pine_tree.mts + small_pine_tree_from_sapling.mts + snowy_small_pine_tree_from_sapling.mts + +Shara RedCat (CC BY-SA 3.0): + acacia_log.mts + apple_log.mts + aspen_log.mts + jungle_log.mts + pine_log.mts + +TumeniNodes (CC BY-SA 3.0): + pine_bush.mts + +random-geek (CC BY-SA 3.0): + blueberry_bush.mts diff --git a/mods/default/aliases.lua b/mods/default/aliases.lua new file mode 100644 index 0000000..6db3fc8 --- /dev/null +++ b/mods/default/aliases.lua @@ -0,0 +1,77 @@ +-- mods/default/aliases.lua + +-- Aliases to support loading worlds using nodes following the old naming convention +-- These can also be helpful when using chat commands, for example /giveme +minetest.register_alias("stone", "default:stone") +minetest.register_alias("stone_with_coal", "default:stone_with_coal") +minetest.register_alias("stone_with_iron", "default:stone_with_iron") +minetest.register_alias("dirt_with_grass", "default:dirt_with_grass") +minetest.register_alias("dirt_with_grass_footsteps", "default:dirt_with_grass_footsteps") +minetest.register_alias("dirt", "default:dirt") +minetest.register_alias("sand", "default:sand") +minetest.register_alias("gravel", "default:gravel") +minetest.register_alias("sandstone", "default:sandstone") +minetest.register_alias("clay", "default:clay") +minetest.register_alias("brick", "default:brick") +minetest.register_alias("tree", "default:tree") +minetest.register_alias("jungletree", "default:jungletree") +minetest.register_alias("junglegrass", "default:junglegrass") +minetest.register_alias("leaves", "default:leaves") +minetest.register_alias("cactus", "default:cactus") +minetest.register_alias("papyrus", "default:papyrus") +minetest.register_alias("bookshelf", "default:bookshelf") +minetest.register_alias("glass", "default:glass") +minetest.register_alias("wooden_fence", "default:fence_wood") +minetest.register_alias("rail", "carts:rail") +minetest.register_alias("ladder", "default:ladder_wood") +minetest.register_alias("wood", "default:wood") +minetest.register_alias("mese", "default:mese") +minetest.register_alias("cloud", "default:cloud") +minetest.register_alias("water_flowing", "default:water_flowing") +minetest.register_alias("water_source", "default:water_source") +minetest.register_alias("lava_flowing", "default:lava_flowing") +minetest.register_alias("lava_source", "default:lava_source") +minetest.register_alias("torch", "default:torch") +minetest.register_alias("sign_wall", "default:sign_wall_wood") +minetest.register_alias("furnace", "default:furnace") +minetest.register_alias("chest", "default:chest") +minetest.register_alias("locked_chest", "default:chest_locked") +minetest.register_alias("cobble", "default:cobble") +minetest.register_alias("mossycobble", "default:mossycobble") +minetest.register_alias("steelblock", "default:steelblock") +minetest.register_alias("sapling", "default:sapling") +minetest.register_alias("apple", "default:apple") + +minetest.register_alias("WPick", "default:pick_wood") +minetest.register_alias("STPick", "default:pick_stone") +minetest.register_alias("SteelPick", "default:pick_steel") +minetest.register_alias("MesePick", "default:pick_mese") +minetest.register_alias("WShovel", "default:shovel_wood") +minetest.register_alias("STShovel", "default:shovel_stone") +minetest.register_alias("SteelShovel", "default:shovel_steel") +minetest.register_alias("WAxe", "default:axe_wood") +minetest.register_alias("STAxe", "default:axe_stone") +minetest.register_alias("SteelAxe", "default:axe_steel") +minetest.register_alias("WSword", "default:sword_wood") +minetest.register_alias("STSword", "default:sword_stone") +minetest.register_alias("SteelSword", "default:sword_steel") + +minetest.register_alias("Stick", "default:stick") +minetest.register_alias("paper", "default:paper") +minetest.register_alias("book", "default:book") +minetest.register_alias("lump_of_coal", "default:coal_lump") +minetest.register_alias("lump_of_iron", "default:iron_lump") +minetest.register_alias("lump_of_clay", "default:clay_lump") +minetest.register_alias("steel_ingot", "default:steel_ingot") +minetest.register_alias("clay_brick", "default:clay_brick") +minetest.register_alias("snow", "default:snow") + +-- 'mese_block' was used for a while for the block form of mese +minetest.register_alias("default:mese_block", "default:mese") + +-- Aliases for corrected pine node names +minetest.register_alias("default:pinetree", "default:pine_tree") +minetest.register_alias("default:pinewood", "default:pine_wood") + +minetest.register_alias("default:ladder", "default:ladder_wood") +minetest.register_alias("default:sign_wall", "default:sign_wall_wood") diff --git a/mods/default/chests.lua b/mods/default/chests.lua new file mode 100644 index 0000000..f4462ae --- /dev/null +++ b/mods/default/chests.lua @@ -0,0 +1,360 @@ +default.chest = {} + +-- support for MT game translation. +local S = default.get_translator + +function default.chest.get_chest_formspec(pos) + local spos = pos.x .. "," .. pos.y .. "," .. pos.z + local formspec = + "size[8,9]" .. + "list[nodemeta:" .. spos .. ";main;0,0.3;8,4;]" .. + "list[current_player;main;0,4.85;8,1;]" .. + "list[current_player;main;0,6.08;8,3;8]" .. + "listring[nodemeta:" .. spos .. ";main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,4.85) + return formspec +end + +function default.chest.chest_lid_obstructed(pos) + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local def = minetest.registered_nodes[minetest.get_node(above).name] + -- allow ladders, signs, wallmounted things and torches to not obstruct + if def and + (def.drawtype == "airlike" or + def.drawtype == "signlike" or + def.drawtype == "torchlike" or + (def.drawtype == "nodebox" and def.paramtype2 == "wallmounted")) then + return false + end + return true +end + +function default.chest.chest_lid_close(pn) + local chest_open_info = default.chest.open_chests[pn] + local pos = chest_open_info.pos + local sound = chest_open_info.sound + local swap = chest_open_info.swap + + default.chest.open_chests[pn] = nil + for k, v in pairs(default.chest.open_chests) do + if v.pos.x == pos.x and v.pos.y == pos.y and v.pos.z == pos.z then + return true + end + end + + local node = minetest.get_node(pos) + minetest.after(0.2, minetest.swap_node, pos, { name = swap, + param2 = node.param2 }) + minetest.sound_play(sound, {gain = 0.3, pos = pos, + max_hear_distance = 10}, true) +end + +default.chest.open_chests = {} + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "default:chest" then + return + end + if not player or not fields.quit then + return + end + local pn = player:get_player_name() + + if not default.chest.open_chests[pn] then + return + end + + default.chest.chest_lid_close(pn) + return true +end) + +minetest.register_on_leaveplayer(function(player) + local pn = player:get_player_name() + if default.chest.open_chests[pn] then + default.chest.chest_lid_close(pn) + end +end) + +function default.chest.register_chest(prefixed_name, d) + local name = prefixed_name:sub(1,1) == ':' and prefixed_name:sub(2,-1) or prefixed_name + local def = table.copy(d) + def.drawtype = "mesh" + def.visual = "mesh" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.legacy_facedir_simple = true + def.is_ground_content = false + + if def.protected then + def.on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", S("Locked Chest")) + meta:set_string("owner", "") + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end + def.after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string("owner", placer:get_player_name() or "") + meta:set_string("infotext", S("Locked Chest (owned by @1)", meta:get_string("owner"))) + end + def.can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") and + default.can_interact_with_node(player, pos) + end + def.allow_metadata_inventory_move = function(pos, from_list, from_index, + to_list, to_index, count, player) + if not default.can_interact_with_node(player, pos) then + return 0 + end + return count + end + def.allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if not default.can_interact_with_node(player, pos) then + return 0 + end + return stack:get_count() + end + def.allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if not default.can_interact_with_node(player, pos) then + return 0 + end + return stack:get_count() + end + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if not default.can_interact_with_node(clicker, pos) then + return itemstack + end + + minetest.sound_play(def.sound_open, {gain = 0.3, + pos = pos, max_hear_distance = 10}, true) + if not default.chest.chest_lid_obstructed(pos) then + minetest.swap_node(pos, + { name = name .. "_open", + param2 = node.param2 }) + end + minetest.after(0.2, minetest.show_formspec, + clicker:get_player_name(), + "default:chest", default.chest.get_chest_formspec(pos)) + default.chest.open_chests[clicker:get_player_name()] = { pos = pos, + sound = def.sound_close, swap = name } + end + def.on_blast = function() end + def.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 = itemstack:get_meta() + + if itemstack:get_metadata() == "" then + return + end + + if key_meta:get_string("secret") == "" then + key_meta:set_string("secret", minetest.parse_json(itemstack:get_metadata()).secret) + itemstack:set_metadata("") + end + + if secret ~= key_meta:get_string("secret") then + return + end + + minetest.show_formspec( + player:get_player_name(), + "default:chest_locked", + default.chest.get_chest_formspec(pos) + ) + end + def.on_skeleton_key_use = function(pos, player, newsecret) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local pn = player:get_player_name() + + -- verify placer is owner of lockable chest + if owner ~= pn then + minetest.record_protection_violation(pos, pn) + minetest.chat_send_player(pn, S("You do not own this chest.")) + return nil + end + + local secret = meta:get_string("key_lock_secret") + if secret == "" then + secret = newsecret + meta:set_string("key_lock_secret", secret) + end + + return secret, S("a locked chest"), owner + end + else + def.on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", S("Chest")) + local inv = meta:get_inventory() + inv:set_size("main", 8*4) + end + def.can_dig = function(pos,player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("main") + end + def.on_rightclick = function(pos, node, clicker) + minetest.sound_play(def.sound_open, {gain = 0.3, pos = pos, + max_hear_distance = 10}, true) + if not default.chest.chest_lid_obstructed(pos) then + minetest.swap_node(pos, { + name = name .. "_open", + param2 = node.param2 }) + end + minetest.after(0.2, minetest.show_formspec, + clicker:get_player_name(), + "default:chest", default.chest.get_chest_formspec(pos)) + default.chest.open_chests[clicker:get_player_name()] = { pos = pos, + sound = def.sound_close, swap = name } + end + def.on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "main", drops) + drops[#drops+1] = name + minetest.remove_node(pos) + return drops + end + end + + def.on_metadata_inventory_move = function(pos, from_list, from_index, + to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in chest at " .. minetest.pos_to_string(pos)) + end + def.on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves " .. stack:get_name() .. + " to chest at " .. minetest.pos_to_string(pos)) + end + def.on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes " .. stack:get_name() .. + " from chest at " .. minetest.pos_to_string(pos)) + end + + local def_opened = table.copy(def) + local def_closed = table.copy(def) + + def_opened.mesh = "chest_open.obj" + for i = 1, #def_opened.tiles do + if type(def_opened.tiles[i]) == "string" then + def_opened.tiles[i] = {name = def_opened.tiles[i], backface_culling = true} + elseif def_opened.tiles[i].backface_culling == nil then + def_opened.tiles[i].backface_culling = true + end + end + def_opened.drop = name + def_opened.groups.not_in_creative_inventory = 1 + def_opened.selection_box = { + type = "fixed", + fixed = { -1/2, -1/2, -1/2, 1/2, 3/16, 1/2 }, + } + def_opened.can_dig = function() + return false + end + def_opened.on_blast = function() end + + def_closed.mesh = nil + def_closed.drawtype = nil + def_closed.tiles[6] = def.tiles[5] -- swap textures around for "normal" + def_closed.tiles[5] = def.tiles[3] -- drawtype to make them match the mesh + def_closed.tiles[3] = def.tiles[3].."^[transformFX" + + minetest.register_node(prefixed_name, def_closed) + minetest.register_node(prefixed_name .. "_open", def_opened) + + -- convert old chests to this new variant + if name == "default:chest" or name == "default:chest_locked" then + minetest.register_lbm({ + label = "update chests to opening chests", + name = "default:upgrade_" .. name:sub(9,-1) .. "_v2", + nodenames = {name}, + action = function(pos, node) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", nil) + local inv = meta:get_inventory() + local list = inv:get_list("default:chest") + if list then + inv:set_size("main", 8*4) + inv:set_list("main", list) + inv:set_list("default:chest", nil) + end + end + }) + end +end + +default.chest.register_chest("default:chest", { + description = S("Chest"), + tiles = { + "default_chest_top.png", + "default_chest_top.png", + "default_chest_side.png", + "default_chest_side.png", + "default_chest_front.png", + "default_chest_inside.png" + }, + sounds = default.node_sound_wood_defaults(), + sound_open = "default_chest_open", + sound_close = "default_chest_close", + groups = {choppy = 2, oddly_breakable_by_hand = 2}, +}) + +default.chest.register_chest("default:chest_locked", { + description = S("Locked Chest"), + tiles = { + "default_chest_top.png", + "default_chest_top.png", + "default_chest_side.png", + "default_chest_side.png", + "default_chest_lock.png", + "default_chest_inside.png" + }, + sounds = default.node_sound_wood_defaults(), + sound_open = "default_chest_open", + sound_close = "default_chest_close", + groups = {choppy = 2, oddly_breakable_by_hand = 2}, + protected = true, +}) + +minetest.register_craft({ + output = "default:chest", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"group:wood", "", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + } +}) + +minetest.register_craft({ + output = "default:chest_locked", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"group:wood", "default:steel_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + } +}) + +minetest.register_craft( { + type = "shapeless", + output = "default:chest_locked", + recipe = {"default:chest", "default:steel_ingot"}, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:chest", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:chest_locked", + burntime = 30, +}) diff --git a/mods/default/crafting.lua b/mods/default/crafting.lua new file mode 100644 index 0000000..bc436fc --- /dev/null +++ b/mods/default/crafting.lua @@ -0,0 +1,746 @@ +-- mods/default/crafting.lua + +minetest.register_craft({ + output = "default:wood 4", + recipe = { + {"default:tree"}, + } +}) + +minetest.register_craft({ + output = "default:junglewood 4", + recipe = { + {"default:jungletree"}, + } +}) + +minetest.register_craft({ + output = "default:pine_wood 4", + recipe = { + {"default:pine_tree"}, + } +}) + +minetest.register_craft({ + output = "default:acacia_wood 4", + recipe = { + {"default:acacia_tree"}, + } +}) + +minetest.register_craft({ + output = "default:aspen_wood 4", + recipe = { + {"default:aspen_tree"}, + } +}) + +minetest.register_craft({ + output = "default:wood", + recipe = { + {"default:bush_stem"}, + } +}) + +minetest.register_craft({ + output = "default:acacia_wood", + recipe = { + {"default:acacia_bush_stem"}, + } +}) + +minetest.register_craft({ + output = "default:pine_wood", + recipe = { + {"default:pine_bush_stem"}, + } +}) + +minetest.register_craft({ + output = "default:sign_wall_steel 3", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"", "group:stick", ""}, + } +}) + +minetest.register_craft({ + output = "default:sign_wall_wood 3", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + {"", "group:stick", ""}, + } +}) + +minetest.register_craft({ + output = "default:coalblock", + recipe = { + {"default:coal_lump", "default:coal_lump", "default:coal_lump"}, + {"default:coal_lump", "default:coal_lump", "default:coal_lump"}, + {"default:coal_lump", "default:coal_lump", "default:coal_lump"}, + } +}) + +minetest.register_craft({ + output = "default:steelblock", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + } +}) + +minetest.register_craft({ + output = "default:copperblock", + recipe = { + {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"}, + {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"}, + {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"}, + } +}) + +minetest.register_craft({ + output = "default:tinblock", + recipe = { + {"default:tin_ingot", "default:tin_ingot", "default:tin_ingot"}, + {"default:tin_ingot", "default:tin_ingot", "default:tin_ingot"}, + {"default:tin_ingot", "default:tin_ingot", "default:tin_ingot"}, + } +}) + +minetest.register_craft({ + output = "default:bronzeblock", + recipe = { + {"default:bronze_ingot", "default:bronze_ingot", "default:bronze_ingot"}, + {"default:bronze_ingot", "default:bronze_ingot", "default:bronze_ingot"}, + {"default:bronze_ingot", "default:bronze_ingot", "default:bronze_ingot"}, + } +}) + +minetest.register_craft({ + output = "default:bronze_ingot 9", + recipe = { + {"default:bronzeblock"}, + } +}) + +minetest.register_craft({ + output = "default:goldblock", + recipe = { + {"default:gold_ingot", "default:gold_ingot", "default:gold_ingot"}, + {"default:gold_ingot", "default:gold_ingot", "default:gold_ingot"}, + {"default:gold_ingot", "default:gold_ingot", "default:gold_ingot"}, + } +}) + +minetest.register_craft({ + output = "default:diamondblock", + recipe = { + {"default:diamond", "default:diamond", "default:diamond"}, + {"default:diamond", "default:diamond", "default:diamond"}, + {"default:diamond", "default:diamond", "default:diamond"}, + } +}) + +minetest.register_craft({ + output = "default:sandstone", + recipe = { + {"default:sand", "default:sand"}, + {"default:sand", "default:sand"}, + } +}) + +minetest.register_craft({ + output = "default:sand 4", + recipe = { + {"default:sandstone"}, + } +}) + +minetest.register_craft({ + output = "default:sandstonebrick 4", + recipe = { + {"default:sandstone", "default:sandstone"}, + {"default:sandstone", "default:sandstone"}, + } +}) + +minetest.register_craft({ + output = "default:sandstone_block 9", + recipe = { + {"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"}, + } +}) + +minetest.register_craft({ + output = "default:clay", + recipe = { + {"default:clay_lump", "default:clay_lump"}, + {"default:clay_lump", "default:clay_lump"}, + } +}) + +minetest.register_craft({ + output = "default:brick", + recipe = { + {"default:clay_brick", "default:clay_brick"}, + {"default:clay_brick", "default:clay_brick"}, + } +}) + +minetest.register_craft({ + output = "default:bookshelf", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"default:book", "default:book", "default:book"}, + {"group:wood", "group:wood", "group:wood"}, + } +}) + +minetest.register_craft({ + output = "default:ladder_wood 5", + recipe = { + {"group:stick", "", "group:stick"}, + {"group:stick", "group:stick", "group:stick"}, + {"group:stick", "", "group:stick"}, + } +}) + +minetest.register_craft({ + output = "default:ladder_steel 15", + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"}, + } +}) + +minetest.register_craft({ + output = "default:mese", + recipe = { + {"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"}, + {"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"}, + {"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"}, + } +}) + +minetest.register_craft({ + output = "default:meselamp", + recipe = { + {"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", ""}, + } +}) + +minetest.register_craft({ + output = "default:obsidian", + recipe = { + {"default:obsidian_shard", "default:obsidian_shard", "default:obsidian_shard"}, + {"default:obsidian_shard", "default:obsidian_shard", "default:obsidian_shard"}, + {"default:obsidian_shard", "default:obsidian_shard", "default:obsidian_shard"}, + } +}) + +minetest.register_craft({ + output = "default:obsidianbrick 4", + recipe = { + {"default:obsidian", "default:obsidian"}, + {"default:obsidian", "default:obsidian"} + } +}) + +minetest.register_craft({ + output = "default:obsidian_block 9", + recipe = { + {"default:obsidian", "default:obsidian", "default:obsidian"}, + {"default:obsidian", "default:obsidian", "default:obsidian"}, + {"default:obsidian", "default:obsidian", "default:obsidian"}, + } +}) + +minetest.register_craft({ + output = "default:stonebrick 4", + recipe = { + {"default:stone", "default:stone"}, + {"default:stone", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "default:stone_block 9", + recipe = { + {"default:stone", "default:stone", "default:stone"}, + {"default:stone", "default:stone", "default:stone"}, + {"default:stone", "default:stone", "default:stone"}, + } +}) + +minetest.register_craft({ + output = "default:desert_stonebrick 4", + recipe = { + {"default:desert_stone", "default:desert_stone"}, + {"default:desert_stone", "default:desert_stone"}, + } +}) + +minetest.register_craft({ + output = "default:desert_stone_block 9", + recipe = { + {"default:desert_stone", "default:desert_stone", "default:desert_stone"}, + {"default:desert_stone", "default:desert_stone", "default:desert_stone"}, + {"default:desert_stone", "default:desert_stone", "default:desert_stone"}, + } +}) + +minetest.register_craft({ + output = "default:snowblock", + recipe = { + {"default:snow", "default:snow", "default:snow"}, + {"default:snow", "default:snow", "default:snow"}, + {"default:snow", "default:snow", "default:snow"}, + } +}) + +minetest.register_craft({ + output = "default:snow 9", + recipe = { + {"default:snowblock"}, + } +}) + +minetest.register_craft({ + output = "default:emergent_jungle_sapling", + recipe = { + {"default:junglesapling", "default:junglesapling", "default:junglesapling"}, + {"default:junglesapling", "default:junglesapling", "default:junglesapling"}, + {"default:junglesapling", "default:junglesapling", "default:junglesapling"}, + } +}) + +minetest.register_craft({ + output = "default:large_cactus_seedling", + recipe = { + {"", "default:cactus", ""}, + {"default:cactus", "default:cactus", "default:cactus"}, + {"", "default:cactus", ""}, + } +}) + + +-- +-- Crafting (tool repair) +-- + +minetest.register_craft({ + type = "toolrepair", + additional_wear = -0.02, +}) + + +-- +-- Cooking recipes +-- + +minetest.register_craft({ + type = "cooking", + output = "default:glass", + recipe = "group:sand", +}) + +minetest.register_craft({ + type = "cooking", + output = "default:obsidian_glass", + recipe = "default:obsidian_shard", +}) + +minetest.register_craft({ + type = "cooking", + output = "default:stone", + recipe = "default:cobble", +}) + +minetest.register_craft({ + type = "cooking", + output = "default:stone", + recipe = "default:mossycobble", +}) + +minetest.register_craft({ + type = "cooking", + output = "default:desert_stone", + recipe = "default:desert_cobble", +}) + + +-- +-- Fuels +-- + +-- Support use of group:tree, includes default:tree which has the same burn time +minetest.register_craft({ + type = "fuel", + recipe = "group:tree", + burntime = 30, +}) + +-- Burn time for all woods are in order of wood density, +-- which is also the order of wood colour darkness: +-- aspen, pine, apple, acacia, jungle + +minetest.register_craft({ + type = "fuel", + recipe = "default:aspen_tree", + burntime = 22, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pine_tree", + burntime = 26, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_tree", + burntime = 34, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:jungletree", + burntime = 38, +}) + + +-- Support use of group:wood, includes default:wood which has the same burn time +minetest.register_craft({ + type = "fuel", + recipe = "group:wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:aspen_wood", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pine_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_wood", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:junglewood", + burntime = 9, +}) + + +-- Support use of group:sapling, includes default:sapling which has the same burn time +minetest.register_craft({ + type = "fuel", + recipe = "group:sapling", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:bush_sapling", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_bush_sapling", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pine_bush_sapling", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:aspen_sapling", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pine_sapling", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_sapling", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:junglesapling", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:emergent_jungle_sapling", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_aspen_wood", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_pine_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_acacia_wood", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_junglewood", + burntime = 9, +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_rail_aspen_wood", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_rail_pine_wood", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_rail_wood", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_rail_acacia_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fence_rail_junglewood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:bush_stem", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:acacia_bush_stem", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pine_bush_stem", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:junglegrass", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "group:leaves", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:cactus", + burntime = 15, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:large_cactus_seedling", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:papyrus", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:bookshelf", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:ladder_wood", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:lava_source", + burntime = 60, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:sign_wall_wood", + burntime = 10, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:coalblock", + burntime = 370, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:grass_1", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:dry_grass_1", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:fern_1", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:marram_grass_1", + burntime = 2, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:dry_shrub", + burntime = 2, +}) diff --git a/mods/default/craftitems.lua b/mods/default/craftitems.lua new file mode 100644 index 0000000..923d754 --- /dev/null +++ b/mods/default/craftitems.lua @@ -0,0 +1,538 @@ +-- mods/default/craftitems.lua + +-- support for MT game translation. +local S = default.get_translator + +local lpp = 14 -- Lines per book's page +local function book_on_use(itemstack, user) + local player_name = user:get_player_name() + local meta = itemstack:get_meta() + local title, text, owner = "", "", player_name + local page, page_max, lines, string = 1, 1, {}, "" + + -- 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 + + for str in (text .. "\n"):gmatch("([^\n]*)[\n]") do + lines[#lines+1] = str + end + + if data.page then + page = data.page + page_max = data.page_max + + for i = ((lpp * page) - lpp) + 1, lpp * page do + if not lines[i] then break end + string = string .. lines[i] .. "\n" + end + end + end + + local formspec + local esc = minetest.formspec_escape + if owner == player_name then + formspec = "size[8,8]" .. + "field[0.5,1;7.5,0;title;" .. esc(S("Title:")) .. ";" .. + esc(title) .. "]" .. + "textarea[0.5,1.5;7.5,7;text;" .. esc(S("Contents:")) .. ";" .. + esc(text) .. "]" .. + "button_exit[2.5,7.5;3,1;save;" .. esc(S("Save")) .. "]" + else + formspec = "size[8,8]" .. + "label[0.5,0.5;" .. esc(S("by @1", owner)) .. "]" .. + "tablecolumns[color;text]" .. + "tableoptions[background=#00000000;highlight=#00000000;border=false]" .. + "table[0.4,0;7,0.5;title;#FFFF00," .. esc(title) .. "]" .. + "textarea[0.5,1.5;7.5,7;;" .. + minetest.formspec_escape(string ~= "" and string or text) .. ";]" .. + "button[2.4,7.6;0.8,0.8;book_prev;<]" .. + "label[3.2,7.7;" .. esc(S("Page @1 of @2", page, page_max)) .. "]" .. + "button[4.9,7.6;0.8,0.8;book_next;>]" + end + + minetest.show_formspec(player_name, "default:book", formspec) + return itemstack +end + +local max_text_size = 10000 +local max_title_size = 80 +local short_title_size = 35 +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "default:book" then return end + local inv = player:get_inventory() + local stack = player:get_wielded_item() + + if fields.save and fields.title and fields.text + and fields.title ~= "" and fields.text ~= "" then + local new_stack, data + if stack:get_name() ~= "default:book_written" then + local count = stack:get_count() + if count == 1 then + stack:set_name("default:book_written") + else + stack:set_count(count - 1) + new_stack = ItemStack("default:book_written") + end + else + data = stack:get_meta():to_table().fields + end + + if data and data.owner and data.owner ~= player:get_player_name() then + return + end + + if not data then data = {} end + data.title = fields.title:sub(1, max_title_size) + data.owner = player:get_player_name() + local short_title = data.title + -- Don't bother triming the title if the trailing dots would make it longer + if #short_title > short_title_size + 3 then + short_title = short_title:sub(1, short_title_size) .. "..." + end + data.description = S("\"@1\" by @2", short_title, data.owner) + data.text = fields.text:sub(1, max_text_size) + data.text = data.text:gsub("\r\n", "\n"):gsub("\r", "\n") + data.page = 1 + data.page_max = math.ceil((#data.text:gsub("[^\n]", "") + 1) / lpp) + + if new_stack then + 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:get_pos(), new_stack) + end + else + stack:get_meta():from_table({ fields = data }) + end + + elseif fields.book_next or fields.book_prev then + 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 + data.page = 1 + end + else + data.page = data.page - 1 + if data.page == 0 then + data.page = data.page_max + end + end + + stack:get_meta():from_table({fields = data}) + stack = book_on_use(stack, player) + end + + -- Update stack + player:set_wielded_item(stack) +end) + +minetest.register_craftitem("default:skeleton_key", { + description = S("Skeleton Key"), + inventory_image = "default_key_skeleton.png", + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local pos = pointed_thing.under + local node = minetest.get_node(pos) + + if not node then + return itemstack + end + + local on_skeleton_key_use = minetest.registered_nodes[node.name].on_skeleton_key_use + if not on_skeleton_key_use then + return itemstack + end + + -- make a new key secret in case the node callback needs it + local random = math.random + local newsecret = string.format( + "%04x%04x%04x%04x", + random(2^16) - 1, random(2^16) - 1, + random(2^16) - 1, random(2^16) - 1) + + local secret, _, _ = on_skeleton_key_use(pos, user, newsecret) + + if secret then + local inv = minetest.get_inventory({type="player", name=user:get_player_name()}) + + -- update original itemstack + itemstack:take_item() + + -- finish and return the new key + local new_stack = ItemStack("default:key") + local meta = new_stack:get_meta() + meta:set_string("secret", secret) + meta:set_string("description", S("Key to @1's @2", user:get_player_name(), + minetest.registered_nodes[node.name].description)) + + if itemstack:get_count() == 0 then + itemstack = new_stack + else + if inv:add_item("main", new_stack):get_count() > 0 then + minetest.add_item(user:get_pos(), new_stack) + end -- else: added to inventory successfully + end + + return itemstack + end + end +}) + +-- +-- Craftitem registry +-- + +minetest.register_craftitem("default:blueberries", { + description = S("Blueberries"), + inventory_image = "default_blueberries.png", + groups = {food_blueberries = 1, food_berry = 1}, + on_use = minetest.item_eat(2), +}) + +minetest.register_craftitem("default:book", { + description = S("Book"), + inventory_image = "default_book.png", + groups = {book = 1, flammable = 3}, + on_use = book_on_use, +}) + +minetest.register_craftitem("default:book_written", { + description = S("Book with Text"), + inventory_image = "default_book_written.png", + groups = {book = 1, not_in_creative_inventory = 1, flammable = 3}, + stack_max = 1, + on_use = book_on_use, +}) + +minetest.register_craftitem("default:bronze_ingot", { + description = S("Bronze Ingot"), + inventory_image = "default_bronze_ingot.png" +}) + +minetest.register_craftitem("default:clay_brick", { + description = S("Clay Brick"), + inventory_image = "default_clay_brick.png", +}) + +minetest.register_craftitem("default:clay_lump", { + description = S("Clay Lump"), + inventory_image = "default_clay_lump.png", +}) + +minetest.register_craftitem("default:coal_lump", { + description = S("Coal Lump"), + inventory_image = "default_coal_lump.png", + groups = {coal = 1, flammable = 1} +}) + +minetest.register_craftitem("default:copper_ingot", { + description = S("Copper Ingot"), + inventory_image = "default_copper_ingot.png" +}) + +minetest.register_craftitem("default:copper_lump", { + description = S("Copper Lump"), + inventory_image = "default_copper_lump.png" +}) + +minetest.register_craftitem("default:diamond", { + description = S("Diamond"), + inventory_image = "default_diamond.png", +}) + +minetest.register_craftitem("default:flint", { + description = S("Flint"), + inventory_image = "default_flint.png" +}) + +minetest.register_craftitem("default:gold_ingot", { + description = S("Gold Ingot"), + inventory_image = "default_gold_ingot.png" +}) + +minetest.register_craftitem("default:gold_lump", { + description = S("Gold Lump"), + inventory_image = "default_gold_lump.png" +}) + +minetest.register_craftitem("default:iron_lump", { + description = S("Iron Lump"), + inventory_image = "default_iron_lump.png" +}) + +minetest.register_craftitem("default:mese_crystal", { + description = S("Mese Crystal"), + inventory_image = "default_mese_crystal.png", +}) + +minetest.register_craftitem("default:mese_crystal_fragment", { + description = S("Mese Crystal Fragment"), + inventory_image = "default_mese_crystal_fragment.png", +}) + +minetest.register_craftitem("default:obsidian_shard", { + description = S("Obsidian Shard"), + inventory_image = "default_obsidian_shard.png", +}) + +minetest.register_craftitem("default:paper", { + description = S("Paper"), + inventory_image = "default_paper.png", + groups = {flammable = 3}, +}) + +minetest.register_craftitem("default:steel_ingot", { + description = S("Steel Ingot"), + inventory_image = "default_steel_ingot.png" +}) + +minetest.register_craftitem("default:stick", { + description = S("Stick"), + inventory_image = "default_stick.png", + groups = {stick = 1, flammable = 2}, +}) + +minetest.register_craftitem("default:tin_ingot", { + description = S("Tin Ingot"), + inventory_image = "default_tin_ingot.png" +}) + +minetest.register_craftitem("default:tin_lump", { + description = S("Tin Lump"), + inventory_image = "default_tin_lump.png" +}) + +-- +-- Crafting recipes +-- + +minetest.register_craft({ + output = "default:book", + recipe = { + {"default:paper"}, + {"default:paper"}, + {"default:paper"}, + } +}) + +default.register_craft_metadata_copy("default:book", "default:book_written") + +minetest.register_craft({ + output = "default:bronze_ingot 9", + recipe = { + {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"}, + {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, + {"default:copper_ingot", "default:copper_ingot", "default:copper_ingot"}, + } +}) + +minetest.register_craft({ + output = "default:clay_brick 4", + recipe = { + {"default:brick"}, + } +}) + +minetest.register_craft({ + output = "default:clay_lump 4", + recipe = { + {"default:clay"}, + } +}) + +minetest.register_craft({ + output = "default:coal_lump 9", + recipe = { + {"default:coalblock"}, + } +}) + +minetest.register_craft({ + output = "default:copper_ingot 9", + recipe = { + {"default:copperblock"}, + } +}) + +minetest.register_craft({ + output = "default:diamond 9", + recipe = { + {"default:diamondblock"}, + } +}) + +minetest.register_craft({ + output = "default:gold_ingot 9", + recipe = { + {"default:goldblock"}, + } +}) + +minetest.register_craft({ + output = "default:mese_crystal", + recipe = { + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + {"default:mese_crystal_fragment", "default:mese_crystal_fragment", "default:mese_crystal_fragment"}, + } +}) + +minetest.register_craft({ + output = "default:mese_crystal 9", + recipe = { + {"default:mese"}, + } +}) + +minetest.register_craft({ + output = "default:mese_crystal_fragment 9", + recipe = { + {"default:mese_crystal"}, + } +}) + +minetest.register_craft({ + output = "default:obsidian_shard 9", + recipe = { + {"default:obsidian"} + } +}) + +minetest.register_craft({ + output = "default:paper", + recipe = { + {"default:papyrus", "default:papyrus", "default:papyrus"}, + } +}) + +minetest.register_craft({ + output = "default:skeleton_key", + recipe = { + {"default:gold_ingot"}, + } +}) + +minetest.register_craft({ + output = "default:steel_ingot 9", + recipe = { + {"default:steelblock"}, + } +}) + +minetest.register_craft({ + output = "default:stick 4", + recipe = { + {"group:wood"}, + } +}) + +minetest.register_craft({ + output = "default:tin_ingot 9", + recipe = { + {"default:tinblock"}, + } +}) + +-- +-- Cooking recipes +-- + +minetest.register_craft({ + type = "cooking", + output = "default:clay_brick", + recipe = "default:clay_lump", +}) + +minetest.register_craft({ + type = "cooking", + output = "default:copper_ingot", + recipe = "default:copper_lump", +}) + +minetest.register_craft({ + type = "cooking", + output = "default:gold_ingot", + recipe = "default:gold_lump", +}) + +minetest.register_craft({ + type = "cooking", + output = "default:gold_ingot", + recipe = "default:key", + cooktime = 5, +}) + +minetest.register_craft({ + type = "cooking", + output = "default:gold_ingot", + recipe = "default:skeleton_key", + cooktime = 5, +}) + +minetest.register_craft({ + type = "cooking", + output = "default:steel_ingot", + recipe = "default:iron_lump", +}) + +minetest.register_craft({ + type = "cooking", + output = "default:tin_ingot", + recipe = "default:tin_lump", +}) + +-- +-- Fuels +-- + +minetest.register_craft({ + type = "fuel", + recipe = "default:book", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:book_written", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:coal_lump", + burntime = 40, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:paper", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "group:stick", + burntime = 1, +}) diff --git a/mods/default/functions.lua b/mods/default/functions.lua new file mode 100644 index 0000000..f9ff77c --- /dev/null +++ b/mods/default/functions.lua @@ -0,0 +1,677 @@ +-- +-- Sounds +-- + +function default.node_sound_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "", gain = 1.0} + table.dug = table.dug or + {name = "default_dug_node", gain = 0.25} + table.place = table.place or + {name = "default_place_node_hard", gain = 1.0} + return table +end + +function default.node_sound_stone_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_hard_footstep", gain = 0.3} + table.dug = table.dug or + {name = "default_hard_footstep", gain = 1.0} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_dirt_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_dirt_footstep", gain = 0.4} + table.dug = table.dug or + {name = "default_dirt_footstep", gain = 1.0} + table.place = table.place or + {name = "default_place_node", gain = 1.0} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_sand_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_sand_footstep", gain = 0.12} + table.dug = table.dug or + {name = "default_sand_footstep", gain = 0.24} + table.place = table.place or + {name = "default_place_node", gain = 1.0} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_gravel_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_gravel_footstep", gain = 0.4} + table.dug = table.dug or + {name = "default_gravel_footstep", gain = 1.0} + table.place = table.place or + {name = "default_place_node", gain = 1.0} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_wood_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_wood_footstep", gain = 0.3} + table.dug = table.dug or + {name = "default_wood_footstep", gain = 1.0} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_leaves_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_grass_footstep", gain = 0.45} + table.dug = table.dug or + {name = "default_grass_footstep", gain = 0.7} + table.place = table.place or + {name = "default_place_node", gain = 1.0} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_glass_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_glass_footstep", gain = 0.3} + table.dig = table.dig or + {name = "default_glass_footstep", gain = 0.5} + table.dug = table.dug or + {name = "default_break_glass", gain = 1.0} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_metal_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_metal_footstep", gain = 0.4} + table.dig = table.dig or + {name = "default_dig_metal", gain = 0.5} + table.dug = table.dug or + {name = "default_dug_metal", gain = 0.5} + table.place = table.place or + {name = "default_place_node_metal", gain = 0.5} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_water_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_water_footstep", gain = 0.2} + default.node_sound_defaults(table) + return table +end + +function default.node_sound_snow_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name = "default_snow_footstep", gain = 0.2} + table.dig = table.dig or + {name = "default_snow_footstep", gain = 0.3} + table.dug = table.dug or + {name = "default_snow_footstep", gain = 0.3} + table.place = table.place or + {name = "default_place_node", gain = 1.0} + default.node_sound_defaults(table) + return table +end + + +-- +-- Lavacooling +-- + +default.cool_lava = function(pos, node) + if node.name == "default:lava_source" then + minetest.set_node(pos, {name = "default:obsidian"}) + else -- Lava flowing + minetest.set_node(pos, {name = "default:stone"}) + end + minetest.sound_play("default_cool_lava", + {pos = pos, max_hear_distance = 16, gain = 0.25}, true) +end + +if minetest.settings:get_bool("enable_lavacooling") ~= false then + minetest.register_abm({ + label = "Lava cooling", + nodenames = {"default:lava_source", "default:lava_flowing"}, + neighbors = {"group:cools_lava", "group:water"}, + interval = 2, + chance = 2, + catch_up = false, + action = function(...) + default.cool_lava(...) + end, + }) +end + + +-- +-- Optimized helper to put all items in an inventory into a drops list +-- + +function default.get_inventory_drops(pos, inventory, drops) + local inv = minetest.get_meta(pos):get_inventory() + local n = #drops + for i = 1, inv:get_size(inventory) do + local stack = inv:get_stack(inventory, i) + if stack:get_count() > 0 then + drops[n+1] = stack:to_table() + n = n + 1 + end + end +end + + +-- +-- Papyrus and cactus growing +-- + +-- Wrapping the functions in ABM action is necessary to make overriding them possible + +function default.grow_cactus(pos, node) + if node.param2 >= 4 then + return + end + pos.y = pos.y - 1 + if minetest.get_item_group(minetest.get_node(pos).name, "sand") == 0 then + return + end + pos.y = pos.y + 1 + local height = 0 + while node.name == "default:cactus" and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + 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 + +function default.grow_papyrus(pos, node) + pos.y = pos.y - 1 + local name = minetest.get_node(pos).name + if name ~= "default:dirt_with_grass" and name ~= "default:dirt" then + return + end + if not minetest.find_node_near(pos, 3, {"group:water"}) then + return + end + pos.y = pos.y + 1 + local height = 0 + while node.name == "default:papyrus" and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + 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 + +minetest.register_abm({ + label = "Grow cactus", + nodenames = {"default:cactus"}, + neighbors = {"group:sand"}, + interval = 12, + chance = 83, + action = function(...) + default.grow_cactus(...) + end +}) + +minetest.register_abm({ + label = "Grow papyrus", + nodenames = {"default:papyrus"}, + neighbors = {"default:dirt", "default:dirt_with_grass"}, + interval = 14, + chance = 71, + action = function(...) + default.grow_papyrus(...) + end +}) + + +-- +-- Dig upwards +-- + +function default.dig_up(pos, node, digger) + if digger == nil then return end + local np = {x = pos.x, y = pos.y + 1, z = pos.z} + local nn = minetest.get_node(np) + if nn.name == node.name then + minetest.node_dig(np, nn, digger) + end +end + + +-- +-- Fence registration helper +-- +local fence_collision_extra = minetest.settings:get_bool("enable_fence_tall") and 3/8 or 0 + +function default.register_fence(name, def) + minetest.register_craft({ + output = name .. " 4", + recipe = { + { def.material, 'group:stick', def.material }, + { def.material, 'group:stick', def.material }, + } + }) + + local fence_texture = "default_fence_overlay.png^" .. def.texture .. + "^default_fence_overlay.png^[makealpha:255,126,126" + -- Allow almost everything to be overridden + local default_fields = { + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}, + -- connect_top = + -- connect_bottom = + connect_front = {{-1/16, 3/16, -1/2, 1/16, 5/16, -1/8 }, + {-1/16, -5/16, -1/2, 1/16, -3/16, -1/8 }}, + connect_left = {{-1/2, 3/16, -1/16, -1/8, 5/16, 1/16}, + {-1/2, -5/16, -1/16, -1/8, -3/16, 1/16}}, + connect_back = {{-1/16, 3/16, 1/8, 1/16, 5/16, 1/2 }, + {-1/16, -5/16, 1/8, 1/16, -3/16, 1/2 }}, + connect_right = {{ 1/8, 3/16, -1/16, 1/2, 5/16, 1/16}, + { 1/8, -5/16, -1/16, 1/2, -3/16, 1/16}} + }, + collision_box = { + type = "connected", + fixed = {-1/8, -1/2, -1/8, 1/8, 1/2 + fence_collision_extra, 1/8}, + -- connect_top = + -- connect_bottom = + connect_front = {-1/8, -1/2, -1/2, 1/8, 1/2 + fence_collision_extra, -1/8}, + connect_left = {-1/2, -1/2, -1/8, -1/8, 1/2 + fence_collision_extra, 1/8}, + connect_back = {-1/8, -1/2, 1/8, 1/8, 1/2 + fence_collision_extra, 1/2}, + connect_right = { 1/8, -1/2, -1/8, 1/2, 1/2 + fence_collision_extra, 1/8} + }, + connects_to = {"group:fence", "group:wood", "group:tree", "group:wall"}, + inventory_image = fence_texture, + wield_image = fence_texture, + tiles = {def.texture}, + sunlight_propagates = true, + is_ground_content = false, + groups = {}, + } + for k, v in pairs(default_fields) do + if def[k] == nil then + def[k] = v + end + end + + -- Always add to the fence group, even if no group provided + def.groups.fence = 1 + + def.texture = nil + def.material = nil + + minetest.register_node(name, def) +end + + +-- +-- Fence rail registration helper +-- + +function default.register_fence_rail(name, def) + minetest.register_craft({ + output = name .. " 16", + recipe = { + { def.material, def.material }, + { "", ""}, + { def.material, def.material }, + } + }) + + local fence_rail_texture = "default_fence_rail_overlay.png^" .. def.texture .. + "^default_fence_rail_overlay.png^[makealpha:255,126,126" + -- Allow almost everything to be overridden + local default_fields = { + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-1/16, 3/16, -1/16, 1/16, 5/16, 1/16}, + {-1/16, -3/16, -1/16, 1/16, -5/16, 1/16}}, + -- connect_top = + -- connect_bottom = + connect_front = {{-1/16, 3/16, -1/2, 1/16, 5/16, -1/16}, + {-1/16, -5/16, -1/2, 1/16, -3/16, -1/16}}, + connect_left = {{-1/2, 3/16, -1/16, -1/16, 5/16, 1/16}, + {-1/2, -5/16, -1/16, -1/16, -3/16, 1/16}}, + connect_back = {{-1/16, 3/16, 1/16, 1/16, 5/16, 1/2 }, + {-1/16, -5/16, 1/16, 1/16, -3/16, 1/2 }}, + connect_right = {{ 1/16, 3/16, -1/16, 1/2, 5/16, 1/16}, + { 1/16, -5/16, -1/16, 1/2, -3/16, 1/16}} + }, + collision_box = { + type = "connected", + fixed = {-1/8, -1/2, -1/8, 1/8, 1/2 + fence_collision_extra, 1/8}, + -- connect_top = + -- connect_bottom = + connect_front = {-1/8, -1/2, -1/2, 1/8, 1/2 + fence_collision_extra, -1/8}, + connect_left = {-1/2, -1/2, -1/8, -1/8, 1/2 + fence_collision_extra, 1/8}, + connect_back = {-1/8, -1/2, 1/8, 1/8, 1/2 + fence_collision_extra, 1/2}, + connect_right = { 1/8, -1/2, -1/8, 1/2, 1/2 + fence_collision_extra, 1/8} + }, + connects_to = {"group:fence", "group:wall"}, + inventory_image = fence_rail_texture, + wield_image = fence_rail_texture, + tiles = {def.texture}, + sunlight_propagates = true, + is_ground_content = false, + groups = {}, + } + for k, v in pairs(default_fields) do + if def[k] == nil then + def[k] = v + end + end + + -- Always add to the fence group, even if no group provided + def.groups.fence = 1 + + def.texture = nil + def.material = nil + + minetest.register_node(name, def) +end + + +-- +-- Leafdecay +-- + +-- Prevent decay of placed leaves + +default.after_place_leaves = function(pos, placer, itemstack, pointed_thing) + if placer and placer:is_player() then + local node = minetest.get_node(pos) + node.param2 = 1 + minetest.set_node(pos, node) + end +end + +-- 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) + local timer = minetest.get_node_timer(v) + if node.param2 ~= 1 and not timer:is_started() then + timer:start(math.random(20, 120) / 10) + end + end +end + +local movement_gravity = tonumber( + minetest.settings:get("movement_gravity")) or 9.81 + +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 + 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) + + -- spawn a few particles for the removed node + minetest.add_particlespawner({ + amount = 8, + time = 0.001, + minpos = vector.subtract(pos, {x=0.5, y=0.5, z=0.5}), + maxpos = vector.add(pos, {x=0.5, y=0.5, z=0.5}), + minvel = vector.new(-0.5, -1, -0.5), + maxvel = vector.new(0.5, 0, 0.5), + minacc = vector.new(0, -movement_gravity, 0), + maxacc = vector.new(0, -movement_gravity, 0), + minsize = 0, + maxsize = 0, + node = node, + }) +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 +-- + +minetest.register_abm({ + label = "Grass spread", + nodenames = {"default:dirt"}, + neighbors = { + "air", + "group:grass", + "default:snow", + }, + interval = 6, + chance = 50, + catch_up = false, + action = function(pos, node) + -- Check for darkness: night, shadow or under a light-blocking node + -- Returns if ignore above + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + if (minetest.get_node_light(above) or 0) < 13 then + return + end + + -- Look for spreading dirt-type neighbours + local p2 = minetest.find_node_near(pos, 1, "group:spreading_dirt_type") + if p2 then + local n3 = minetest.get_node(p2) + minetest.set_node(pos, {name = n3.name}) + return + end + + -- Else, any seeding nodes on top? + local name = minetest.get_node(above).name + -- Snow check is cheapest, so comes first + if name == "default:snow" then + minetest.set_node(pos, {name = "default:dirt_with_snow"}) + elseif minetest.get_item_group(name, "grass") ~= 0 then + minetest.set_node(pos, {name = "default:dirt_with_grass"}) + end + end +}) + + +-- +-- Grass and dry grass removed in darkness +-- + +minetest.register_abm({ + label = "Grass covered", + nodenames = {"group:spreading_dirt_type", "default:dry_dirt_with_dry_grass"}, + interval = 8, + chance = 50, + catch_up = false, + action = function(pos, node) + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local name = minetest.get_node(above).name + local nodedef = minetest.registered_nodes[name] + if name ~= "ignore" and nodedef and not ((nodedef.sunlight_propagates or + nodedef.paramtype == "light") and + nodedef.liquidtype == "none") then + if node.name == "default:dry_dirt_with_dry_grass" then + minetest.set_node(pos, {name = "default:dry_dirt"}) + else + minetest.set_node(pos, {name = "default:dirt"}) + end + end + end +}) + + +-- +-- Moss growth on cobble near water +-- + +local moss_correspondences = { + ["default:cobble"] = "default:mossycobble", + ["stairs:slab_cobble"] = "stairs:slab_mossycobble", + ["stairs:stair_cobble"] = "stairs:stair_mossycobble", + ["stairs:stair_inner_cobble"] = "stairs:stair_inner_mossycobble", + ["stairs:stair_outer_cobble"] = "stairs:stair_outer_mossycobble", + ["walls:cobble"] = "walls:mossycobble", +} +minetest.register_abm({ + label = "Moss growth", + nodenames = {"default:cobble", "stairs:slab_cobble", "stairs:stair_cobble", + "stairs:stair_inner_cobble", "stairs:stair_outer_cobble", + "walls:cobble"}, + neighbors = {"group:water"}, + interval = 16, + chance = 200, + catch_up = false, + action = function(pos, node) + node.name = moss_correspondences[node.name] + if node.name then + minetest.set_node(pos, node) + end + end +}) + +-- +-- Register a craft to copy the metadata of items +-- + +function default.register_craft_metadata_copy(ingredient, result) + minetest.register_craft({ + type = "shapeless", + output = result, + recipe = {ingredient, result} + }) + + minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) + if itemstack:get_name() ~= result then + return + end + + local original + local index + for i = 1, #old_craft_grid do + if old_craft_grid[i]:get_name() == result then + original = old_craft_grid[i] + index = i + end + end + if not original then + return + end + local copymeta = original:get_meta():to_table() + itemstack:get_meta():from_table(copymeta) + -- put the book with metadata back in the craft grid + craft_inv:set_stack("craft", index, original) + end) +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 and player:is_player() then + if minetest.check_player_privs(player, "protection_bypass") then + return true + end + else + return false + end + + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + + if not owner or owner == "" or owner == player:get_player_name() then + return true + end + + -- Is player wielding the right key? + local item = player:get_wielded_item() + if minetest.get_item_group(item:get_name(), "key") == 1 then + local key_meta = item:get_meta() + + if key_meta:get_string("secret") == "" then + local key_oldmeta = item:get_metadata() + if key_oldmeta == "" or not minetest.parse_json(key_oldmeta) then + return false + end + + key_meta:set_string("secret", minetest.parse_json(key_oldmeta).secret) + item:set_metadata("") + end + + return meta:get_string("key_lock_secret") == key_meta:get_string("secret") + end + + return false +end diff --git a/mods/default/furnace.lua b/mods/default/furnace.lua new file mode 100644 index 0000000..3c4ac9c --- /dev/null +++ b/mods/default/furnace.lua @@ -0,0 +1,363 @@ +-- default/furnace.lua + +-- support for MT game translation. +local S = default.get_translator + +-- +-- Formspecs +-- + +function default.get_furnace_active_formspec(fuel_percent, item_percent) + return "size[8,8.5]".. + "list[context;src;2.75,0.5;1,1;]".. + "list[context;fuel;2.75,2.5;1,1;]".. + "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. + (fuel_percent)..":default_furnace_fire_fg.png]".. + "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:".. + (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. + "list[context;dst;4.75,0.96;2,2;]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "listring[context;dst]".. + "listring[current_player;main]".. + "listring[context;src]".. + "listring[current_player;main]".. + "listring[context;fuel]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) +end + +function default.get_furnace_inactive_formspec() + return "size[8,8.5]".. + "list[context;src;2.75,0.5;1,1;]".. + "list[context;fuel;2.75,2.5;1,1;]".. + "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. + "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "list[context;dst;4.75,0.96;2,2;]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "listring[context;dst]".. + "listring[current_player;main]".. + "listring[context;src]".. + "listring[current_player;main]".. + "listring[context;fuel]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) +end + +-- +-- Node callback functions that are the same for active and inactive furnace +-- + +local function can_dig(pos, player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src") +end + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if listname == "fuel" then + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + if inv:is_empty("src") then + meta:set_string("infotext", S("Furnace is empty")) + end + return stack:get_count() + else + return 0 + end + elseif listname == "src" then + return stack:get_count() + elseif listname == "dst" then + return 0 + end +end + +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() +end + +local function swap_node(pos, name) + local node = minetest.get_node(pos) + if node.name == name then + return + end + node.name = name + minetest.swap_node(pos, node) +end + +local function furnace_node_timer(pos, elapsed) + -- + -- Initialize metadata + -- + local meta = minetest.get_meta(pos) + local fuel_time = meta:get_float("fuel_time") or 0 + local src_time = meta:get_float("src_time") or 0 + local fuel_totaltime = meta:get_float("fuel_totaltime") or 0 + + local inv = meta:get_inventory() + local srclist, fuellist + local dst_full = false + + local cookable, cooked + local fuel + + local update = true + while elapsed > 0 and update do + update = false + + srclist = inv:get_list("src") + fuellist = inv:get_list("fuel") + + -- + -- Cooking + -- + + -- Check if we have cookable content + local aftercooked + cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cookable = cooked.time ~= 0 + + local el = math.min(elapsed, fuel_totaltime - fuel_time) + if cookable then -- fuel lasts long enough, adjust el to cooking duration + el = math.min(el, cooked.time - src_time) + end + + -- Check if we have enough fuel to burn + if fuel_time < fuel_totaltime then + -- The furnace is currently active and has enough fuel + fuel_time = fuel_time + el + -- If there is a cookable item then check if it is ready yet + if cookable then + src_time = src_time + el + if src_time >= cooked.time then + -- Place result in dst list if possible + if inv:room_for_item("dst", cooked.item) then + inv:add_item("dst", cooked.item) + inv:set_stack("src", 1, aftercooked.items[1]) + src_time = src_time - cooked.time + update = true + else + dst_full = true + end + else + -- Item could not be cooked: probably missing fuel + update = true + end + end + else + -- Furnace ran out of fuel + if cookable then + -- We need to get new fuel + 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 + fuel_totaltime = 0 + src_time = 0 + else + -- Take fuel from fuel list + inv:set_stack("fuel", 1, afterfuel.items[1]) + -- Put replacements in dst list or drop them on the furnace. + local replacements = fuel.replacements + if replacements[1] then + local leftover = inv:add_item("dst", replacements[1]) + if not leftover:is_empty() then + local above = vector.new(pos.x, pos.y + 1, pos.z) + local drop_pos = minetest.find_node_near(above, 1, {"air"}) or above + minetest.item_drop(replacements[1], nil, drop_pos) + end + end + update = true + fuel_totaltime = fuel.time + (fuel_totaltime - fuel_time) + end + else + -- We don't need to get new fuel since there is no cookable item + fuel_totaltime = 0 + src_time = 0 + end + fuel_time = 0 + end + + elapsed = elapsed - el + end + + if fuel and fuel_totaltime > fuel.time then + fuel_totaltime = fuel.time + end + if srclist and srclist[1]:is_empty() then + src_time = 0 + end + + -- + -- Update formspec, infotext and node + -- + local formspec + local item_state + local item_percent = 0 + if cookable then + item_percent = math.floor(src_time / cooked.time * 100) + if dst_full then + item_state = S("100% (output full)") + else + item_state = S("@1%", item_percent) + end + else + if srclist and not srclist[1]:is_empty() then + item_state = S("Not cookable") + else + item_state = S("Empty") + end + end + + local fuel_state = S("Empty") + local active = false + local result = false + + if fuel_totaltime ~= 0 then + active = true + local fuel_percent = 100 - math.floor(fuel_time / fuel_totaltime * 100) + fuel_state = S("@1%", fuel_percent) + formspec = default.get_furnace_active_formspec(fuel_percent, item_percent) + swap_node(pos, "default:furnace_active") + -- make sure timer restarts automatically + result = true + else + if fuellist and not fuellist[1]:is_empty() then + fuel_state = S("@1%", 0) + end + formspec = default.get_furnace_inactive_formspec() + swap_node(pos, "default:furnace") + -- stop timer on the inactive furnace + minetest.get_node_timer(pos):stop() + end + + + local infotext + if active then + infotext = S("Furnace active") + else + infotext = S("Furnace inactive") + end + infotext = infotext .. "\n" .. S("(Item: @1; Fuel: @2)", item_state, fuel_state) + + -- + -- Set meta values + -- + meta:set_float("fuel_totaltime", fuel_totaltime) + meta:set_float("fuel_time", fuel_time) + meta:set_float("src_time", src_time) + meta:set_string("formspec", formspec) + meta:set_string("infotext", infotext) + + return result +end + +-- +-- Node definitions +-- + +minetest.register_node("default:furnace", { + description = S("Furnace"), + tiles = { + "default_furnace_top.png", "default_furnace_bottom.png", + "default_furnace_side.png", "default_furnace_side.png", + "default_furnace_side.png", "default_furnace_front.png" + }, + paramtype2 = "facedir", + groups = {cracky=2}, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + + can_dig = can_dig, + + on_timer = furnace_node_timer, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('src', 1) + inv:set_size('fuel', 1) + inv:set_size('dst', 4) + furnace_node_timer(pos, 0) + end, + + on_metadata_inventory_move = function(pos) + minetest.get_node_timer(pos):start(1.0) + end, + on_metadata_inventory_put = function(pos) + -- start timer function, it will sort out whether furnace can burn or not. + minetest.get_node_timer(pos):start(1.0) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "src", drops) + default.get_inventory_drops(pos, "fuel", drops) + default.get_inventory_drops(pos, "dst", drops) + drops[#drops+1] = "default:furnace" + minetest.remove_node(pos) + return drops + end, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, +}) + +minetest.register_node("default:furnace_active", { + description = S("Furnace"), + tiles = { + "default_furnace_top.png", "default_furnace_bottom.png", + "default_furnace_side.png", "default_furnace_side.png", + "default_furnace_side.png", + { + image = "default_furnace_front_active.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.5 + }, + } + }, + paramtype2 = "facedir", + light_source = 8, + drop = "default:furnace", + groups = {cracky=2, not_in_creative_inventory=1}, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + on_timer = furnace_node_timer, + + can_dig = can_dig, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, +}) + +minetest.register_craft({ + output = "default:furnace", + recipe = { + {"group:stone", "group:stone", "group:stone"}, + {"group:stone", "", "group:stone"}, + {"group:stone", "group:stone", "group:stone"}, + } +}) diff --git a/mods/default/init.lua b/mods/default/init.lua new file mode 100644 index 0000000..d4388e5 --- /dev/null +++ b/mods/default/init.lua @@ -0,0 +1,68 @@ +-- Minetest 0.4 mod: default +-- See README.txt for licensing and other information. + +-- The API documentation in here was moved into game_api.txt + +-- Load support for MT game translation. +local S = minetest.get_translator("default") + +-- Definitions made by this mod that other mods can use too +default = {} + +default.LIGHT_MAX = 14 +default.get_translator = S + +-- GUI related stuff +minetest.register_on_joinplayer(function(player) + -- Set formspec prepend + local formspec = [[ + bgcolor[#080808BB;true] + listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF] ]] + local name = player:get_player_name() + local info = minetest.get_player_information(name) + if info.formspec_version > 1 then + formspec = formspec .. "background9[5,5;1,1;gui_formbg.png;true;10]" + else + formspec = formspec .. "background[5,5;1,1;gui_formbg.png;true]" + end + player:set_formspec_prepend(formspec) + + -- Set hotbar textures + player:hud_set_hotbar_image("gui_hotbar.png") + player:hud_set_hotbar_selected_image("gui_hotbar_selected.png") +end) + +function default.get_hotbar_bg(x,y) + local out = "" + for i=0,7,1 do + out = out .."image["..x+i..","..y..";1,1;gui_hb_bg.png]" + end + return out +end + +default.gui_survival_form = "size[8,8.5]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "list[current_player;craft;1.75,0.5;3,3;]".. + "list[current_player;craftpreview;5.75,1.5;1,1;]".. + "image[4.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "listring[current_player;main]".. + "listring[current_player;craft]".. + default.get_hotbar_bg(0,4.25) + +-- Load files +local default_path = minetest.get_modpath("default") + +dofile(default_path.."/functions.lua") +dofile(default_path.."/trees.lua") +dofile(default_path.."/nodes.lua") +dofile(default_path.."/chests.lua") +dofile(default_path.."/furnace.lua") +dofile(default_path.."/torch.lua") +dofile(default_path.."/tools.lua") +dofile(default_path.."/item_entity.lua") +dofile(default_path.."/craftitems.lua") +dofile(default_path.."/crafting.lua") +dofile(default_path.."/mapgen.lua") +dofile(default_path.."/aliases.lua") +dofile(default_path.."/legacy.lua") diff --git a/mods/default/item_entity.lua b/mods/default/item_entity.lua new file mode 100644 index 0000000..d9bf7b1 --- /dev/null +++ b/mods/default/item_entity.lua @@ -0,0 +1,78 @@ +-- mods/default/item_entity.lua + +local builtin_item = minetest.registered_entities["__builtin:item"] + +local item = { + set_item = function(self, itemstring) + builtin_item.set_item(self, itemstring) + + local stack = ItemStack(itemstring) + local itemdef = minetest.registered_items[stack:get_name()] + if itemdef and itemdef.groups.flammable ~= 0 then + self.flammable = itemdef.groups.flammable + end + end, + + burn_up = function(self) + -- disappear in a smoke puff + local p = self.object:get_pos() + self.object:remove() + minetest.sound_play("default_item_smoke", { + pos = p, + max_hear_distance = 8, + }, true) + minetest.add_particlespawner({ + amount = 3, + time = 0.1, + minpos = {x = p.x - 0.1, y = p.y + 0.1, z = p.z - 0.1 }, + maxpos = {x = p.x + 0.1, y = p.y + 0.2, z = p.z + 0.1 }, + minvel = {x = 0, y = 2.5, z = 0}, + maxvel = {x = 0, y = 2.5, z = 0}, + minacc = {x = -0.15, y = -0.02, z = -0.15}, + maxacc = {x = 0.15, y = -0.01, z = 0.15}, + minexptime = 4, + maxexptime = 6, + minsize = 5, + maxsize = 5, + collisiondetection = true, + texture = "default_item_smoke.png" + }) + end, + + on_step = function(self, dtime, ...) + builtin_item.on_step(self, dtime, ...) + + if self.flammable then + -- flammable, check for igniters every 10 s + self.ignite_timer = (self.ignite_timer or 0) + dtime + if self.ignite_timer > 10 then + self.ignite_timer = 0 + + local pos = self.object:get_pos() + if pos == nil then + return -- object already deleted + end + local node = minetest.get_node_or_nil(pos) + if not node then + return + end + + -- Immediately burn up flammable items in lava + if minetest.get_item_group(node.name, "lava") > 0 then + self:burn_up() + else + -- otherwise there'll be a chance based on its igniter value + local burn_chance = self.flammable + * minetest.get_item_group(node.name, "igniter") + if burn_chance > 0 and math.random(0, burn_chance) ~= 0 then + self:burn_up() + end + end + end + end + end, +} + +-- set defined item as new __builtin:item, with the old one as fallback table +setmetatable(item, builtin_item) +minetest.register_entity(":__builtin:item", item) diff --git a/mods/default/legacy.lua b/mods/default/legacy.lua new file mode 100644 index 0000000..a2d812d --- /dev/null +++ b/mods/default/legacy.lua @@ -0,0 +1,49 @@ +-- mods/default/legacy.lua + +-- Horrible stuff to support old code registering falling nodes +-- Don't use this and never do what this does, it's completely wrong! +-- (More specifically, the client and the C++ code doesn't get the group) +function default.register_falling_node(nodename, texture) + minetest.log("error", debug.traceback()) + minetest.log('error', "WARNING: default.register_falling_node is deprecated") + if minetest.registered_nodes[nodename] then + minetest.registered_nodes[nodename].groups.falling_node = 1 + end +end + +function default.spawn_falling_node(p, nodename) + spawn_falling_node(p, nodename) +end + +-- Liquids +WATER_ALPHA = minetest.registered_nodes["default:water_source"].alpha +WATER_VISC = minetest.registered_nodes["default:water_source"].liquid_viscosity +LAVA_VISC = minetest.registered_nodes["default:lava_source"].liquid_viscosity +LIGHT_MAX = default.LIGHT_MAX + +-- Formspecs +default.gui_suvival_form = default.gui_survival_form +default.gui_bg = "" +default.gui_bg_img = "" +default.gui_slots = "" + +-- Players +if minetest.get_modpath("player_api") then + default.registered_player_models = player_api.registered_models + default.player_register_model = player_api.register_model + default.player_attached = player_api.player_attached + default.player_get_animation = player_api.get_animation + default.player_set_model = player_api.set_model + default.player_set_textures = player_api.set_textures + default.player_set_animation = player_api.set_animation +end + +-- Chests +default.register_chest = default.chest.register_chest + +-- Check for a volume intersecting protection +function default.intersects_protection(minp, maxp, player_name, interval) + minetest.log("warning", "default.intersects_protection() is " .. + "deprecated, use minetest.is_area_protected() instead.") + return minetest.is_area_protected(minp, maxp, player_name, interval) +end diff --git a/mods/default/license.txt b/mods/default/license.txt new file mode 100644 index 0000000..3c95c1b --- /dev/null +++ b/mods/default/license.txt @@ -0,0 +1,157 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2011-2018 celeron55, Perttu Ahola +Copyright (C) 2011-2018 Various Minetest developers and contributors + +This program 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 program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures, models and sounds) +----------------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2010-2018: + + celeron55, Perttu Ahola + Cisoun + G4JC + VanessaE + RealBadAngel + Calinou + MirceaKitsune + Jordach + PilzAdam + jojoa1997 + InfinityProject + Splizard + Zeg9 + paramat + BlockMen + sofar + Neuromancer + Gambit + asl97 + KevDoy + Mito551 + GreenXenith + kaeza + kilbith + tobyplowy + CloudyProton + TumeniNodes + Mossmanikin + random-geek + Extex101 + An0n3m0us + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ + +----------------------- + +Attribution 3.0 Unported (CC BY 3.0) + +Copyright (C) 2009 cmusounddesign +Copyright (C) 2010 Tomlija +Copyright (C) 2010 lsprice +Copyright (C) 2014 sonictechtonic +Copyright (C) 2015 yadronoff +Copyright (C) 2007 HerbertBoland +Copyright (C) 2006 AGFX + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by/3.0/ + +----------------------- + +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication + +Iwan Gabovitch +Ottomaani138 +Ogrebane +blukotek +Sevin7 +Yoyodaman234 +Ryding + +No Copyright + +The person who associated a work with this deed has dedicated the work to the +public domain by waiving all of his or her rights to the work worldwide under +copyright law, including all related and neighboring rights, to the extent +allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial +purposes, all without asking permission. See Other Information below. + +Other Information: + +In no way are the patent or trademark rights of any person affected by CC0, nor +are the rights that other persons may have in the work or in how the work is +used, such as publicity or privacy rights. + +Unless expressly stated otherwise, the person who associated a work with this +deed makes no warranties about the work, and disclaims liability for all uses +of the work, to the fullest extent permitted by applicable law. + +When using or citing the work, you should not imply endorsement by the author +or the affirmer. + +For more details: +https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/mods/default/locale/default.de.tr b/mods/default/locale/default.de.tr new file mode 100644 index 0000000..c842b85 --- /dev/null +++ b/mods/default/locale/default.de.tr @@ -0,0 +1,211 @@ +# textdomain: default +Locked Chest=Abgeschlossene Truhe +Locked Chest (owned by @1)=Abgeschlossene Truhe (Eigentum von @1) +You do not own this chest.=Ihnen gehört diese Truhe nicht. +a locked chest=eine abgeschlossene Truhe +Chest=Truhe +Stick=Stock +Paper=Papier +"@1" by @2=„@1“ von @2 +Book=Buch +Book with Text=Buch mit Text +Skeleton Key=Skelettschlüssel +Key to @1's @2=Schlüssel für @2 von @1 +Coal Lump=Kohleklumpen +Iron Lump=Eisenklumpen +Copper Lump=Kupferklumpen +Tin Lump=Zinnklumpen +Mese Crystal=Mesekristall +Gold Lump=Goldklumpen +Diamond=Diamant +Clay Lump=Tonklumpen +Steel Ingot=Stahlbarren +Copper Ingot=Kupferbarren +Tin Ingot=Zinnbarren +Bronze Ingot=Bronzebarren +Gold Ingot=Goldbarren +Mese Crystal Fragment=Mesekristallfragment +Clay Brick=Tonziegel +Obsidian Shard=Obsidianscherbe +Flint=Feuerstein +Blueberries=Blaubeeren +Furnace is empty=Ofen ist leer +100% (output full)=100% (Ausgabe voll) +@1%=@1% +Empty=Leer +Not cookable=Nicht kochbar +Furnace active=Ofen aktiv +Furnace inactive=Ofen inaktiv +(Item: @1; Fuel: @2)=(Gegenstand: @1; Brennstoff: @2) +Furnace=Ofen +Stone=Stein +Cobblestone=Kopfsteinpflaster +Stone Brick=Steinziegel +Stone Block=Steinblock +Mossy Cobblestone=Mosiges Kopfsteinpflaster +Desert Stone=Wüstenstein +Desert Cobblestone=Wüstenkopfsteinpflaster +Desert Stone Brick=Wüstensteinziegel +Desert Stone Block=Wüstensteinblock +Sandstone=Sandstein +Sandstone Brick=Sandsteinziegel +Sandstone Block=Sandsteinblock +Desert Sandstone=Wüstensandstein +Desert Sandstone Brick=Wüstensandsteinziegel +Desert Sandstone Block=Wüstensandsteinblock +Silver Sandstone=Silbersandstein +Silver Sandstone Brick=Silbersandsteinziegel +Silver Sandstone Block=Silbersandsteinblock +Obsidian=Obsidian +Obsidian Brick=Obsidianziegel +Obsidian Block=Obsidianblock +Dirt=Erde +Dirt with Grass=Erde mit Gras +Dirt with Grass and Footsteps=Erde mit Gras und Fußstapfen +Dirt with Dry Grass=Erde mit trockenem Gras +Dirt with Snow=Erde mit Schnee +Dirt with Rainforest Litter=Erde mit Regenwaldboden +Dirt with Coniferous Litter=Erde mit Nadelwaldboden +Dry Dirt=Trockene Erde +Dry Dirt with Dry Grass=Trockene Erde mit trockenem Gras +Permafrost=Permafrost +Permafrost with Stones=Permafrost mit Steinen +Permafrost with Moss=Permafrost mit Moos +Sand=Sand +Desert Sand=Wüstensand +Silver Sand=Silbersand +Gravel=Kies +Clay=Ton +Snow=Schnee +Snow Block=Schneeblock +Ice=Eis +Cave Ice=Höhleneis +Apple Tree=Apfelbaum +Apple Wood Planks=Apfelbaumplanken +Apple Tree Sapling=Apfelbaumsetzling +Apple Tree Leaves=Apfelbaumblätter +Apple=Apfel +Apple Marker=Apfelmarkierung +Jungle Tree=Dschungelbaum +Jungle Wood Planks=Dschungelholzplanken +Jungle Tree Leaves=Dschungelbaumblätter +Jungle Tree Sapling=Dschungelbaumsetzling +Emergent Jungle Tree Sapling=Hervorstehender Dschungelbaumsetzling +Pine Tree=Kiefernbaum +Pine Wood Planks=Kiefernholzplanken +Pine Needles=Kiefernnadeln +Pine Tree Sapling=Kiefernbaumsetzling +Acacia Tree=Akazienbaum +Acacia Wood Planks=Akazienholzplanken +Acacia Tree Leaves=Akazienbaumblätter +Acacia Tree Sapling=Akazienbaumsetzling +Aspen Tree=Espenbaum +Aspen Wood Planks=Espenholzplanken +Aspen Tree Leaves=Espenbaumblätter +Aspen Tree Sapling=Esepenbaumsetzling +Coal Ore=Kohleerz +Coal Block=Kohleblock +Iron Ore=Eisenerz +Steel Block=Stahlblock +Copper Ore=Kupfererz +Copper Block=Kupferblock +Tin Ore=Zinnerz +Tin Block=Zinnblock +Bronze Block=Bronzeblock +Mese Ore=Meseerz +Mese Block=Meseblock +Gold Ore=Golderz +Gold Block=Goldblock +Diamond Ore=Diamanterz +Diamond Block=Diamantblock +Cactus=Kaktus +Large Cactus Seedling=Großer Kaktussämling +Papyrus=Papyrus +Dry Shrub=Trockener Busch +Jungle Grass=Dschungelgras +Grass=Gras +Dry Grass=Trockenes Gras +Fern=Farn +Marram Grass=Dünengras +Bush Stem=Buschstamm +Bush Leaves=Buschblätter +Bush Sapling=Buschsetzling +Blueberry Bush Leaves with Berries=Blaubeerbuschblätter mit Beeren +Blueberry Bush Leaves=Blaubeerbuschblätter +Blueberry Bush Sapling=Blaubeerbuschsetzling +Acacia Bush Stem=Akazienbuschstamm +Acacia Bush Leaves=Akazienbuschblätter +Acacia Bush Sapling=Akazienbuschsetzling +Pine Bush Stem=Kiefernbuschstamm +Pine Bush Needles=Kiefernbuschnadeln +Pine Bush Sapling=Kiefernbuschsetzling +Kelp=Seetang +Green Coral=Grüne Koralle +Pink Coral=Rosa Koralle +Cyan Coral=Türkise Koralle +Brown Coral=Braune Koralle +Orange Coral=Orange Koralle +Coral Skeleton=Korallenskelett +Water Source=Wasserquelle +Flowing Water=Fließendes Wasser +River Water Source=Flusswasserquelle +Flowing River Water=Fließendes Flusswasser +Lava Source=Lavaquelle +Flowing Lava=Fließende Lava +Empty Bookshelf=Leeres Bücherregal +Bookshelf (@1 written, @2 empty books)=Bücherregal (@1 beschriebene, @2 leere Bücher) +Bookshelf=Bücherregal +Text too long=Text zu lang +Wooden Sign=Holzschild +Steel Sign=Stahlschild +Wooden Ladder=Holzleiter +Steel Ladder=Stahlleiter +Apple Wood Fence=Apfelholzzaun +Acacia Wood Fence=Akazienholzzaun +Jungle Wood Fence=Dschungelholzzaun +Pine Wood Fence=Kiefernholzzaun +Aspen Wood Fence=Espenholzzaun +Apple Wood Fence Rail=Apfelholzzaungeländer +Acacia Wood Fence Rail=Akazienholzzaungeländer +Jungle Wood Fence Rail=Dschungelholzzaungeländer +Pine Wood Fence Rail=Kiefernholzzaungeländer +Aspen Wood Fence Rail=Espenholzzaungeländer +Glass=Glas +Obsidian Glass=Obsidianglas +Brick Block=Ziegelblock +Mese Lamp=Meselampe +Mese Post Light=Mesestandlampe +Cloud=Wolke +Wooden Pickaxe=Holzspitzhacke +Stone Pickaxe=Steinspitzhacke +Bronze Pickaxe=Bronzespitzhacke +Steel Pickaxe=Stahlspitzhacke +Mese Pickaxe=Mesespitzhacke +Diamond Pickaxe=Diamantspitzhacke +Wooden Shovel=Holzschaufel +Stone Shovel=Steinschaufel +Bronze Shovel=Bronzeschaufel +Steel Shovel=Stahlschaufel +Mese Shovel=Meseschaufel +Diamond Shovel=Diamantschaufel +Wooden Axe=Holzaxt +Stone Axe=Steinaxt +Bronze Axe=Bronzeaxt +Steel Axe=Stahlaxt +Mese Axe=Meseaxt +Diamond Axe=Diamantaxt +Wooden Sword=Holzschwert +Stone Sword=Steinschwert +Bronze Sword=Bronzeschwert +Steel Sword=Stahlschwert +Mese Sword=Meseschwert +Diamond Sword=Diamantschwert +Key=Schlüssel +Torch=Fackel +@1 will intersect protection on growth.=@1 wird bei Wachstum mit geschützter Zone überlappen. +Title:=Titel: +Contents:=Inhalt: +Save=Speichern +by @1=von @1 +Page @1 of @2=Seite @1 von @2 +"@1"=„@1“ diff --git a/mods/default/locale/default.es.tr b/mods/default/locale/default.es.tr new file mode 100644 index 0000000..e55c133 --- /dev/null +++ b/mods/default/locale/default.es.tr @@ -0,0 +1,211 @@ +# textdomain: default +Locked Chest=Cofre cerrado +Locked Chest (owned by @1)=Cofre cerrado (propiedad de @1) +You do not own this chest.=Este cofre no te pertenece. +a locked chest=un cofre cerrado +Chest=Cofre +Stick=Palo +Paper=Papel +"@1" by @2="@1" por @2 +Book=Libro +Book with Text=Libro escrito +Skeleton Key=Llave esqueleto +Key to @1's @2=Llave para @2 de @1 +Coal Lump=Fragmento de carbón +Iron Lump=Pepita de hierro +Copper Lump=Pepita de cobre +Tin Lump=Pepita de estaño +Mese Crystal=Cristal de mese +Gold Lump=Pepita de oro +Diamond=Diamante +Clay Lump=Fragmento de arcilla +Steel Ingot=Lingote de acero +Copper Ingot=Lingote de cobre +Tin Ingot=Lingote de estaño +Bronze Ingot=Lingote de bronce +Gold Ingot=Lingote de oro +Mese Crystal Fragment=Fragmento de cristal de mese +Clay Brick=Ladrillo de arcilla +Obsidian Shard=Esquirla de obsidiana +Flint=Pedernal +Blueberries=Arándanos +Furnace is empty=El horno está vacío +100% (output full)=100% (salida completa) +@1%=@1% +Empty=Vacío +Not cookable=No se puede cocinar +Furnace active=Horno activado +Furnace inactive=Horno desactivado +(Item: @1; Fuel: @2)=(Objeto: @1; Combustible: @2) +Furnace=Horno +Stone=Piedra +Cobblestone=Adoquín +Stone Brick=Ladrillo de piedra +Stone Block=Bloque de piedra +Mossy Cobblestone=Adoquín musgoso +Desert Stone=Piedra desértica +Desert Cobblestone=Adoquín desértico +Desert Stone Brick=Ladrillo de piedra desértica +Desert Stone Block=Bloque de piedra desértica +Sandstone=Piedra arenisca +Sandstone Brick=Ladrillo de arenisca +Sandstone Block=Bloque de arenisca +Desert Sandstone=Piedra arenisca desértica +Desert Sandstone Brick=Ladrillo de arenisca desértica +Desert Sandstone Block=Bloque de arenisca deÅ›ertica +Silver Sandstone=Piedra arenisca plateada +Silver Sandstone Brick=Ladrillo de arenisca plateada +Silver Sandstone Block=Bloque de arenisca plateada +Obsidian=Obsidiana +Obsidian Brick=Ladrillo de obsidiana +Obsidian Block=Bloque de obsidiana +Dirt=Tierra +Dirt with Grass=Tierra con pasto +Dirt with Grass and Footsteps=Tierra con pasto y pisadas +Dirt with Dry Grass=Tierra con pasto seco +Dirt with Snow=Tierra con nieve +Dirt with Rainforest Litter=Tierra con hojarasca de selva tropical +Dirt with Coniferous Litter=Tierra con hojarasca de coníferas +Dry Dirt=Tierra Seca +Dry Dirt with Dry Grass=Tierra seca con pasto seco +Permafrost=Permafrost +Permafrost with Stones=Permafrost pedregoso +Permafrost with Moss=Permafrost musgoso +Sand=Arena +Desert Sand=Arena desértica +Silver Sand=Arena plateada +Gravel=Gravilla +Clay=Arcilla +Snow=Nieve +Snow Block=Bloque de nieve +Ice=Hielo +Cave Ice=Hielo de cueva +Apple Tree=Madera de manzano +Apple Wood Planks=Tablas de manzano +Apple Tree Sapling=Retoño de manzano +Apple Tree Leaves=Hojas de manzano +Apple=Manzana +Apple Marker=Marcador de manzano +Jungle Tree=Madera de árbol tropical +Jungle Wood Planks=Tablas de madera tropical +Jungle Tree Leaves=Hojas de árbol tropical +Jungle Tree Sapling=Retoño de árbol tropical +Emergent Jungle Tree Sapling=Retoño de árbol tropical +Pine Tree=Madera de pino +Pine Wood Planks=Tablas de pino +Pine Needles=Agujas de pino +Pine Tree Sapling=Retoño de pino +Acacia Tree=Madera de acacia +Acacia Wood Planks=Tablas de acacia +Acacia Tree Leaves=Hojas de acacia +Acacia Tree Sapling=Retoño de acacia +Aspen Tree=Madera de álamo +Aspen Wood Planks=Tablas de álamo +Aspen Tree Leaves=Hojas de álamo +Aspen Tree Sapling=Retoño de álamo +Coal Ore=Mineral de carbón +Coal Block=Bloque de carbón +Iron Ore=Mineral de hierro +Steel Block=Bloque de acero +Copper Ore=Mineral de cobre +Copper Block=Bloque de cobre +Tin Ore=Mineral de estaño +Tin Block=Bloque de estaño +Bronze Block=Bloque de bronce +Mese Ore=Mineral de mese +Mese Block=Bloque de mese +Gold Ore=Mineral de oro +Gold Block=Bloque de oro +Diamond Ore=Mineral de diamante +Diamond Block=Bloque de diamante +Cactus=Cáctus +Large Cactus Seedling=Vástago grande de cactus +Papyrus=Papiro +Dry Shrub=Arbusto seco +Jungle Grass=Pasto de jungla +Grass=Pasto +Dry Grass=Pasto seco +Fern=Helecho +Marram Grass=Carrizo +Bush Stem=Tallo de arbusto +Bush Leaves=Hojas de arbusto +Bush Sapling=Retoño de arbusto +Blueberry Bush Leaves with Berries=Hojas de arbusto de arándano con bayas +Blueberry Bush Leaves=Hojas de arbusto de arándano +Blueberry Bush Sapling=Retoño de arbusto de arándano +Acacia Bush Stem=Tallo de arbusto de acacia +Acacia Bush Leaves=Hojas de arbusto de acacia +Acacia Bush Sapling=Retoño de arbusto de acacia +Pine Bush Stem=Tallo de arbusto de pino +Pine Bush Needles=Agujas de arbusto de pino +Pine Bush Sapling=Retoño de arbusto de pino +Kelp=Alga marina +Green Coral=Coral verde +Pink Coral=Coral rosa +Cyan Coral=Coral cián +Brown Coral=Coral café +Orange Coral=Coral naranja +Coral Skeleton=Esqueleto de coral +Water Source=Fuente de agua +Flowing Water=Fluído de agua +River Water Source=Fuente de agua de río +Flowing River Water=Fluído de agua de río +Lava Source=Fuente de lava +Flowing Lava=Fluído de lava +Empty Bookshelf=Librería vacía +Bookshelf (@1 written, @2 empty books)=Librería(@1 escritos, @2 libros en blanco) +Bookshelf=Librería +Text too long=Texto demasiado largo +Wooden Sign=Cartel de madera +Steel Sign=Cartel de acero +Wooden Ladder=Escalera de madera +Steel Ladder=Escalera de acero +Apple Wood Fence=Cerca de manzano +Acacia Wood Fence=Cerca de acacia +Jungle Wood Fence=Cerca de madera tropical +Pine Wood Fence=Cerca de pino +Aspen Wood Fence=Cerca de álamo +Apple Wood Fence Rail=Listones de manzano para cerca +Acacia Wood Fence Rail=Listones de acacia para cerca +Jungle Wood Fence Rail=Listones de madera tropical para cerca +Pine Wood Fence Rail=Listones de pino para cerca +Aspen Wood Fence Rail=Listones de álamo para cerca +Glass=Vidrio +Obsidian Glass=Vidrio de obsidiana +Brick Block=Bloque de ladrillo +Mese Lamp=Lámpara de mese +Mese Post Light=Poste de luz de mese +Cloud=Nube +Wooden Pickaxe=Pico de madera +Stone Pickaxe=Pico de piedra +Bronze Pickaxe=Pico de bronce +Steel Pickaxe=Pico de acero +Mese Pickaxe=Pico de mese +Diamond Pickaxe=Pico de diamante +Wooden Shovel=Pala de madera +Stone Shovel=Pala de piedra +Bronze Shovel=Pala de bronce +Steel Shovel=Pala de acero +Mese Shovel=Pala de mese +Diamond Shovel=Pala de diamante +Wooden Axe=Hacha de madera +Stone Axe=Hacha de piedra +Bronze Axe=Hacha de bronce +Steel Axe=Hacha de acero +Mese Axe=Hacha de mese +Diamond Axe=Hacha de diamante +Wooden Sword=Espada de madera +Stone Sword=Espada de piedra +Bronze Sword=Espada de bronce +Steel Sword=Espada de acero +Mese Sword=Espada de mese +Diamond Sword=Espada de diamante +Key=Llave +Torch=Antorcha +@1 will intersect protection on growth.=@1 intersectará con protección cuando crezca. +Title:=Título: +Contents:=Contenidos: +Save=Guardar +by @1=por @1 +Page @1 of @2=Página @1 de @2 +"@1"="@1" diff --git a/mods/default/locale/default.fr.tr b/mods/default/locale/default.fr.tr new file mode 100644 index 0000000..2214e37 --- /dev/null +++ b/mods/default/locale/default.fr.tr @@ -0,0 +1,211 @@ +# textdomain: default +Locked Chest=Coffre verrouillé +Locked Chest (owned by @1)=Coffre verrouillé (possédé par @1) +You do not own this chest.=Ce coffre ne vous appartient pas. +a locked chest=un coffre verrouillé +Chest=Coffre +Stick=Baton +Paper=Papier +"@1" by @2=« @1 » de @2 +Book=Livre +Book with Text=Livre avec du texte +Skeleton Key=Squelette +Key to @1's @2=Clé pour @2 de @1 +Coal Lump=Morceau de charbon +Iron Lump=Morceau de fer +Copper Lump=Morceau de cuivre +Tin Lump=Morceau d'étain +Mese Crystal=Cristal de Mese +Gold Lump=Morceau d'or +Diamond=Diamant +Clay Lump=Morceau d'argile +Steel Ingot=Lingot d'acier +Copper Ingot=Lingot de cuivre +Tin Ingot=Lingot d'étain +Bronze Ingot=Lingot de bronze +Gold Ingot=Lingot d'or +Mese Crystal Fragment=Fragment de cristal de Mese +Clay Brick=Brique d'argile +Obsidian Shard=Tesson d'obsidienne +Flint=Silex +Blueberries=Myrtille +Furnace is empty=Le four est vide +100% (output full)=100% (Sortie pleine) +@1%=@1% +Empty=Vide +Not cookable=Ne se cuit pas +Furnace active=Four actif +Furnace inactive=Four inactif +(Item: @1; Fuel: @2)=(Article: @1; Carburant: @2) +Furnace=Four +Stone=Pierre +Cobblestone=Pavé +Stone Brick=Brique de pierre +Stone Block=Bloc de pierre +Mossy Cobblestone=Pavé moussu +Desert Stone=Pierre du désert +Desert Cobblestone=Pavé de pierre du désert +Desert Stone Brick=Brique de pierre du désert +Desert Stone Block=Bloc de pierre du désert +Sandstone=Grès +Sandstone Brick=Brique de grès +Sandstone Block=Bloc de grès +Desert Sandstone=Grès du désert +Desert Sandstone Brick=Brique de grès du désert +Desert Sandstone Block=Bloc de grès du désert +Silver Sandstone=Grès argenté +Silver Sandstone Brick=Brique de grès argenté +Silver Sandstone Block=Bloc de grès argenté +Obsidian=Obsidienne +Obsidian Brick=Brique d'obsidienne +Obsidian Block=Block d'obsidienne +Dirt=Terre +Dirt with Grass=Terre avec de l'herbe +Dirt with Grass and Footsteps=Terre avec de l'herbe et des traces de pas +Dirt with Dry Grass=Terre avec de l'herbe sèche +Dirt with Snow=Terre avec de la neige +Dirt with Rainforest Litter=Terre avec sol de forêt humide +Dirt with Coniferous Litter=Terre avec sol de forêt de conifère +Dry Dirt=Terre sèche +Dry Dirt with Dry Grass=Terre sèche avec de l'herbe sèche +Permafrost=Pergélisol +Permafrost with Stones=Pergélisol avec de la pierre +Permafrost with Moss=Pergélisol avec de la mousse +Sand=Sable +Desert Sand=Sable du désert +Silver Sand=Sable argenté +Gravel=Gravier +Clay=Argile +Snow=Neige +Snow Block=Bloc de neige +Ice=Glace +Cave Ice=Glace de grotte +Apple Tree=Pommier +Apple Wood Planks=Planche de pommier +Apple Tree Sapling=Pousse de pommier +Apple Tree Leaves=Feuilles de pommier +Apple=Pomme +Apple Marker=Marqueur de pomme +Jungle Tree=Arbre de la jungle +Jungle Wood Planks=Planche d'arbre de la jungle +Jungle Tree Leaves=Feuilles d'arbre de la jungle +Jungle Tree Sapling=Pousse d'arbre de la jungle +Emergent Jungle Tree Sapling=Pousse d'arbre de la jungle émergent +Pine Tree=Pin +Pine Wood Planks=Planche de pin +Pine Needles=Aiguilles de pin +Pine Tree Sapling=Pousse de pin +Acacia Tree=Acacia +Acacia Wood Planks=Planche d'acacia +Acacia Tree Leaves=Feuilles d'acacia +Acacia Tree Sapling=Pousse d'acacia +Aspen Tree=Tremble +Aspen Wood Planks=Planche de tremble +Aspen Tree Leaves=Feuilles de tremble +Aspen Tree Sapling=Pousse de tremble +Coal Ore=Minerai de charbon +Coal Block=Bloc de charbon +Iron Ore=Bloc de fer +Steel Block=Bloc d'acier +Copper Ore=Minerai de cuivre +Copper Block=Bloc de cuivre +Tin Ore=Minerai d'étain +Tin Block=Bloc d'étain +Bronze Block=Bloc de bronze +Mese Ore=Minerai de Mese +Mese Block=Bloc de Mese +Gold Ore=Minerai d'or +Gold Block=Bloc d'or +Diamond Ore=Minerai de diamant +Diamond Block=Bloc de diamant +Cactus=Cactus +Large Cactus Seedling=Grand plan de cactus +Papyrus=Papyrus +Dry Shrub=Arbuste sec +Jungle Grass=Herbe de la jungle +Grass=Herbe +Dry Grass=Herbe sèche +Fern=Fougère +Marram Grass=Ammophile +Bush Stem=Tige de buisson +Bush Leaves=Feuilles de buisson +Bush Sapling=Pousse de buisson +Blueberry Bush Leaves with Berries=Buisson de myrtille avec des myrtilles +Blueberry Bush Leaves=Feuilles de buisson à myrtilles +Blueberry Bush Sapling=Pousse de buisson à myrtilles +Acacia Bush Stem=Tige de buisson d'acacia +Acacia Bush Leaves=Feuilles de buisson d'acacia +Acacia Bush Sapling=Pousses de buisson d'acacia +Pine Bush Stem=Tige de buisson de pin +Pine Bush Needles=Aiguilles de buisson de pin +Pine Bush Sapling=Pousse de buisson de pin +Kelp=Varech +Green Coral=Corail vert +Pink Coral=Corail rose +Cyan Coral=Corail cyan +Brown Coral=Corail marron +Orange Coral=Corail orange +Coral Skeleton=Squelette de corail +Water Source=Source d'eau +Flowing Water=Ecoulement d'eau +River Water Source=Source d'eau de rivière +Flowing River Water=Ecoulement d'eau de rivière +Lava Source=Source de lave +Flowing Lava=Ecoulement de lave +Empty Bookshelf=Bibliothèque vide +Bookshelf (@1 written, @2 empty books)=Bibliothèque (@1 écrits, @2 livres vides) +Bookshelf=Bibliothèque +Text too long=Texte trop longue +Wooden Sign=Panneau en bois +Steel Sign=Panneau en acier +Wooden Ladder=Echelle en bois +Steel Ladder=Echelle en acier +Apple Wood Fence=Barrière de bois de pommier +Acacia Wood Fence=Barrière de bois d'acacia +Jungle Wood Fence=Barrière de bois de la jungle +Pine Wood Fence=Barrière de bois de pin +Aspen Wood Fence=Barrière de bois de tremble +Apple Wood Fence Rail=Clôture de bois de pommier +Acacia Wood Fence Rail=Clôture de bois d'acacia +Jungle Wood Fence Rail=Clôture de bois de la jungle +Pine Wood Fence Rail=Clôture de bois de pin +Aspen Wood Fence Rail=Clôture de bois de tremble +Glass=Verre +Obsidian Glass=Verre d'obsidienne +Brick Block=Bloc de brique +Mese Lamp=Lampe de Mese +Mese Post Light=Réverbère de Mese +Cloud=Nuage +Wooden Pickaxe=Pioche en bois +Stone Pickaxe=Pioche en pierre +Bronze Pickaxe=Pioche en bronze +Steel Pickaxe=Pioche en acier +Mese Pickaxe=Pioche de Mese +Diamond Pickaxe=Pioche en diamant +Wooden Shovel=Pelle en bois +Stone Shovel=Pelle en pierre +Bronze Shovel=Pelle en bronze +Steel Shovel=Pelle en acier +Mese Shovel=Pelle en Mese +Diamond Shovel=Pelle en diamant +Wooden Axe=Hache en bois +Stone Axe=Hache en pierre +Bronze Axe=Hache en bronze +Steel Axe=Hache en acier +Mese Axe=Hache en Mese +Diamond Axe=Hache en diamant +Wooden Sword=Epée en bois +Stone Sword=Epée en pierre +Bronze Sword=Epée en bronze +Steel Sword=Epée en acier +Mese Sword=Epée en Mese +Diamond Sword=Epée en diamant +Key=Clé +Torch=Torche +@1 will intersect protection on growth.=@1 chevauchera la zone protégée avec la croissance. +Title:=Titre : +Contents:=Contenu : +Save=Sauvegarder +by @1=de @1 +Page @1 of @2=Page @1 sur @2 +"@1"=« @1 » diff --git a/mods/default/locale/default.it.tr b/mods/default/locale/default.it.tr new file mode 100644 index 0000000..ea3ee20 --- /dev/null +++ b/mods/default/locale/default.it.tr @@ -0,0 +1,205 @@ +# textdomain: default +Locked Chest=Baule chiuso a chiave +Locked Chest (owned by @1)=Baule chiuso a chiave (di proprietà di @1) +You do not own this chest.=Questo baule non ti appartiene. +a locked chest=un baule chiuso a chiave +Chest=Baule +Stick=Bastone +Paper=Carta +"@1" by @2="@1" di @2 +Book=Libro +Book with Text=Libro con testo +Skeleton Key=Chiave dello Scheletro +Key to @1's @2=Chiave per @2 di @1 +Coal Lump=Grumo di carbone +Iron Lump=Grumo di ferro +Copper Lump=Grumo di rame +Tin Lump=Grumo di stagno +Mese Crystal=Cristallo di mese +Gold Lump=Grumo d'oro +Diamond=Diamante +Clay Lump=Grumo d'argilla +Steel Ingot=Lingotto d'acciaio +Copper Ingot=Lingotto di rame +Tin Ingot=Lingotto di stagno +Bronze Ingot=Lingotto di bronzo +Gold Ingot=Lingotto d'oro +Mese Crystal Fragment=Frammento di cristallo di mese +Clay Brick=Mattone d'argilla +Obsidian Shard=Scheggia d'ossidiana +Flint=Selce +Blueberries=Mirtilli +Furnace is empty=La fornace è vuota +100% (output full)=100% (uscita piena) +@1%=@1% +Empty=Vuota +Not cookable=Non cucinabile +Furnace active=Fornace attiva +Furnace inactive=Fornace inattiva +(Item: @1; Fuel: @2)=(Oggetto: @1; Combustibile: @2) +Furnace=Fornace +Stone=Pietra +Cobblestone=Ciottoli +Stone Brick=Mattone di pietra +Stone Block=Blocco di pietra +Mossy Cobblestone=Ciottoli muschiosi +Desert Stone=Pietra del deserto +Desert Cobblestone=Ciottoli del deserto +Desert Stone Brick=Mattone di pietra del deserto +Desert Stone Block=Blocco di pietra del deserto +Sandstone=Arenaria +Sandstone Brick=Mattone d'arenaria +Sandstone Block=Blocco d'arenaria +Desert Sandstone=Arenaria del deserto +Desert Sandstone Brick=Mattone d'arenaria del deserto +Desert Sandstone Block=Blocco d'arenaria del deserto +Silver Sandstone=Arenaria argentata +Silver Sandstone Brick=Mattone d'arenaria argentata +Silver Sandstone Block=Blocco d'arenaria argentata +Obsidian=Ossidiana +Obsidian Brick=Mattone d'ossidiana +Obsidian Block=Blocco d'ossidiana +Dirt=Terra +Dirt with Grass=Terra con erba +Dirt with Grass and Footsteps=Terra con erba e impronte +Dirt with Dry Grass=Terra con erba secca +Dirt with Snow=Terra con neve +Dirt with Rainforest Litter=Terra con detriti della foresta pluviale +Dirt with Coniferous Litter=Terra con detriti di conifera +Dry Dirt=Terra asciutta +Dry Dirt with Dry Grass=Terra asciutta con erba secca +Permafrost=Permafrost +Permafrost with Stones=Permafrost con pietra +Permafrost with Moss=Permafrost con muschio +Sand=Sabbia +Desert Sand=Sabbia del deserto +Silver Sand=Sabbia argentata +Gravel=Ghiaia +Clay=Argilla +Snow=Neve +Snow Block=Blocco di neve +Ice=Ghiaccio +Cave Ice=Ghiaccio di caverna +Apple Tree=Melo +Apple Wood Planks=Assi di melo +Apple Tree Sapling=Alberello di melo +Apple Tree Leaves=Foglie di melo +Apple=Mela +Apple Marker=Marcatore mela +Jungle Tree=Albero della giungla +Jungle Wood Planks=Assi di legno della giungla +Jungle Tree Leaves=Foglie di albero della giungla +Jungle Tree Sapling=Alberello della giungla +Emergent Jungle Tree Sapling=Alberello della giungla emergente +Pine Tree=Pino +Pine Wood Planks=Assi di legno di pino +Pine Needles=Aghi di pino +Pine Tree Sapling=Alberello di pino +Acacia Tree=Acacia +Acacia Wood Planks=Assi di legno d'acacia +Acacia Tree Leaves=Foglie d'acacia +Acacia Tree Sapling=Alberello d'acacia +Aspen Tree=Pioppo +Aspen Wood Planks=Assi di legno di pioppo +Aspen Tree Leaves=Foglie di pioppo +Aspen Tree Sapling=Alberello di pioppo +Coal Ore=Minerale di carbone +Coal Block=Blocco di carbone +Iron Ore=Minerale di ferro +Steel Block=Blocco d'acciaio +Copper Ore=Minerale di rame +Copper Block=Blocco di rame +Tin Ore=Minerale di stagno +Tin Block=Blocco di stagno +Bronze Block=Blocco di bronzo +Mese Ore=Minerale di mese +Mese Block=Blocco di mese +Gold Ore=Minerale d'oro +Gold Block=Blocco d'oro +Diamond Ore=Minerale di diamante +Diamond Block=Blocco di diamante +Cactus=Cactus +Large Cactus Seedling=Piantina di cactus grande +Papyrus=Papiro +Dry Shrub=Arbusto secco +Jungle Grass=Erba della giungla +Grass=Erba +Dry Grass=Erba secca +Fern=Felce +Marram Grass=Ammofila arenaria +Bush Stem=Fusto di cespuglio +Bush Leaves=Foglie di cespuglio +Bush Sapling=Alberello di cespuglio +Blueberry Bush Leaves with Berries=Foglie di cespuglio di mirtilli con bacche +Blueberry Bush Leaves=Foglie di cespuglio di mirtilli +Blueberry Bush Sapling=Alberello di cespuglio di mirtilli +Acacia Bush Stem=Fusto di cespuglio d'acacia +Acacia Bush Leaves=Foglie di cespuglio d'acacia +Acacia Bush Sapling=Alberello di cespuglio d'acacia +Pine Bush Stem=Fusto di cespuglio di pino +Pine Bush Needles=Aghi di cespuglio di pino +Pine Bush Sapling=Alberello di cespuglio di pino +Kelp=Alga +Green Coral=Corallo verde +Pink Coral=Corallo rosa +Cyan Coral=Corallo ciano +Brown Coral=Corallo marrone +Orange Coral=Corallo arancione +Coral Skeleton=Scheletro di corallo +Water Source=Fonte d'acqua +Flowing Water=Acqua corrente +River Water Source=Fonte d'acqua di fiume +Flowing River Water=Acqua corrente di fiume +Lava Source=Fonte di lava +Flowing Lava=Lava corrente +Empty Bookshelf=Libreria vuota +Bookshelf (@1 written, @2 empty books)=Libreria (@1 scritti, @2 vuoti) +Bookshelf=Libreria +Text too long=Testo troppo lungo +Wooden Sign=Cartello di legno +Steel Sign=Cartello d'acciaio +Wooden Ladder=Scala a pioli di legno +Steel Ladder=Scala a pioli d'acciaio +Apple Wood Fence=Recinzione di legno di melo +Acacia Wood Fence=Recinzione di legno d'acacia +Jungle Wood Fence=Recinzione di legno della giungla +Pine Wood Fence=Recinzione di legno di pino +Aspen Wood Fence=Recinzione di legno di pioppo +Apple Wood Fence Rail=Ringhiera della recinzione di legno di melo +Acacia Wood Fence Rail=Ringhiera della recinzione di legno d'acacia +Jungle Wood Fence Rail=Ringhiera della recinzione di legno della giungla +Pine Wood Fence Rail=Ringhiera della recinzione di legno di pino +Aspen Wood Fence Rail=Ringhiera della recinzione di legno di pioppo +Glass=Vetro +Obsidian Glass=Vetro d'ossidiana +Brick Block=Blocco di mattone +Mese Lamp=Lampada di mese +Mese Post Light=Lampioncino di mese +Cloud=Nuvola +Wooden Pickaxe=Piccone di legno +Stone Pickaxe=Piccone di pietra +Bronze Pickaxe=Piccone di bronzo +Steel Pickaxe=Piccone d'acciaio +Mese Pickaxe=Piccone di mese +Diamond Pickaxe=Piccone di diamante +Wooden Shovel=Pala di legno +Stone Shovel=Pala di pietra +Bronze Shovel=Pala di bronzo +Steel Shovel=Pala d'acciaio +Mese Shovel=Pala di mese +Diamond Shovel=Pala di diamante +Wooden Axe=Ascia di legno +Stone Axe=Ascia di pietra +Bronze Axe=Ascia di bronzo +Steel Axe=Ascia d'acciaio +Mese Axe=Ascia di mese +Diamond Axe=Ascia di diamante +Wooden Sword=Spada di legno +Stone Sword=Spada di pietra +Bronze Sword=Spada di bronzo +Steel Sword=Spada d'acciaio +Mese Sword=Spada di mese +Diamond Sword=Spada di diamante +Key=Chiave +Torch=Torcia +@1 will intersect protection on growth.=@1 crescendo attraverserà la protezione. diff --git a/mods/default/locale/default.ms.tr b/mods/default/locale/default.ms.tr new file mode 100644 index 0000000..b82c201 --- /dev/null +++ b/mods/default/locale/default.ms.tr @@ -0,0 +1,211 @@ +# textdomain: default +Locked Chest=Peti Berkunci +Locked Chest (owned by @1)=Peti Berkunci (milik @1) +You do not own this chest.=Ini bukan peti milik anda. +a locked chest=peti berkunci +Chest=Peti +Stick=Serpihan Kayu +Paper=Kertas +"@1" by @2="@1" oleh @2 +Book=Buku +Book with Text=Buku Bertulisan +Skeleton Key=Kunci Induk +Key to @1's @2=Kunci @2 milik @1 +Coal Lump=Longgokan Batu Arang +Iron Lump=Longgokan Besi +Copper Lump=Longgokan Tembaga +Tin Lump=Longgokan Timah +Mese Crystal=Kristal Mese +Gold Lump=Longgokan Emas +Diamond=Berlian +Clay Lump=Longgokan Tanah Liat +Steel Ingot=Jongkong Keluli +Copper Ingot=Jongkong Tembaga +Tin Ingot=Jongkong Timah +Bronze Ingot=Jongkong Gangsa +Gold Ingot=Jongkong Emas +Mese Crystal Fragment=Serpihan Mese +Clay Brick=Bata Tanah Liat +Obsidian Shard=Serpihan Obsidia +Flint=Batu Api +Blueberries=Beri Biru +Furnace is empty=Relau masih kosong +100% (output full)=100% (keluaran penuh) +@1%=@1% +Empty=Kosong +Not cookable=Tidak boleh dimasak +Furnace active=Relau aktif +Furnace inactive=Relau tidak aktif +(Item: @1; Fuel: @2)=(Item: @1; Bahan api: @2) +Furnace=Relau +Stone=Batu +Cobblestone=Batu Buntar +Stone Brick=Bata Batu +Stone Block=Bongkah Batu +Mossy Cobblestone=Batu Buntar Berlumut +Desert Stone=Batu Gurun +Desert Cobblestone=Batu Buntar Gurun +Desert Stone Brick=Bata Batu Gurun +Desert Stone Block=Bongkah Batu Gurun +Sandstone=Batu Pasir +Sandstone Brick=Bata Batu Pasir +Sandstone Block=Bongkah Batu Pasir +Desert Sandstone=Batu Pasir Gurun +Desert Sandstone Brick=Bata Batu Pasir Gurun +Desert Sandstone Block=Bongkah Batu Pasir Gurun +Silver Sandstone=Batu Pasir Perak +Silver Sandstone Brick=Bata Batu Pasir Perak +Silver Sandstone Block=Bongkah Batu Pasir Perak +Obsidian=Obsidia +Obsidian Brick=Bata Obsidia +Obsidian Block=Bongkah Obsidia +Dirt=Tanah +Dirt with Grass=Tanah Berumput +Dirt with Grass and Footsteps=Tanah Berumput dan Tapak Kaki +Dirt with Dry Grass=Tanah Berumput Kering +Dirt with Snow=Tanah Bersalji +Dirt with Rainforest Litter=Tanah Bersarap Hutan Hujan +Dirt with Coniferous Litter=Tanah Bersarap Hutan Konifer +Dry Dirt=Tanah Kering +Dry Dirt with Dry Grass=Tanah Kering Berumput Kering +Permafrost=Ibun Abadi +Permafrost with Stones=Ibun Abadi Berbatu +Permafrost with Moss=Ibun Abadi Berlumut +Sand=Pasir +Desert Sand=Pasir Gurun +Silver Sand=Pasir Perak +Gravel=Kelikir +Clay=Tanah Liat +Snow=Salji +Snow Block=Bongkah Salji +Ice=Ais +Cave Ice=Ais Gua +Apple Tree=Kayu Pokok Epal +Apple Wood Planks=Papan Kayu Epal +Apple Tree Sapling=Anak Pokok Epal +Apple Tree Leaves=Daun Pokok Epal +Apple=Epal +Apple Marker=Penanda Epal +Jungle Tree=Kayu Pokok Hutan +Jungle Wood Planks=Papan Kayu Hutan +Jungle Tree Leaves=Daun Pokok Hutan +Jungle Tree Sapling=Anak Pokok Hutan +Emergent Jungle Tree Sapling=Anak Pokok Hutan Kembang +Pine Tree=Kayu Pokok Pain +Pine Wood Planks=Papan Kayu Pain +Pine Needles=Daun Pokok Pain +Pine Tree Sapling=Anak Pokok Pain +Acacia Tree=Kayu Pokok Akasia +Acacia Wood Planks=Papan Kayu Akasia +Acacia Tree Leaves=Daun Pokok Akasia +Acacia Tree Sapling=Anak Pokok Akasia +Aspen Tree=Kayu Pokok Aspen +Aspen Wood Planks=Papan Kayu Aspen +Aspen Tree Leaves=Daun Pokok Aspen +Aspen Tree Sapling=Anak Pokok Aspen +Coal Ore=Bijih Batu Arang +Coal Block=Bongkah Batu Arang +Iron Ore=Bijih Besi +Steel Block=Bongkah Keluli +Copper Ore=Bijih Tembaga +Copper Block=Bongkah Tembaga +Tin Ore=Bijih Timah +Tin Block=Bongkah Timah +Bronze Block=Bongkah Gangsa +Mese Ore=Bijih Mese +Mese Block=Bongkah Mese +Gold Ore=Bijih Emas +Gold Block=Bongkah Emas +Diamond Ore=Bijih Intan +Diamond Block=Bongkah Intan +Cactus=Kaktus +Large Cactus Seedling=Benih Kaktus Besar +Papyrus=Papirus +Dry Shrub=Pokok Renek Kering +Jungle Grass=Rumput Hutan +Grass=Rumput +Dry Grass=Rumput Kering +Fern=Paku Pakis +Marram Grass=Rumput Maram +Bush Stem=Batang Belukar +Bush Leaves=Daun Belukar +Bush Sapling=Anak Belukar +Blueberry Bush Leaves with Berries=Daun Belukar Beri Biru Berberi +Blueberry Bush Leaves=Daun Belukar Beri Biru +Blueberry Bush Sapling=Anak Belukar Beri Biru +Acacia Bush Stem=Batang Belukar Akasia +Acacia Bush Leaves=Daun Belukar Akasia +Acacia Bush Sapling=Anak Belukar Akasia +Pine Bush Stem=Batang Belukar Pain +Pine Bush Needles=Daun Belukar Pain +Pine Bush Sapling=Anak Belukar Pain +Kelp=Kelpa +Green Coral=Batu Karang Hijau +Pink Coral=Batu Karang Merah Jambu +Cyan Coral=Batu Karang Biru Kehijauan +Brown Coral=Batu Karang Perang +Orange Coral=Batu Karang Jingga +Coral Skeleton= Rangka Karang +Water Source=Sumber Air +Flowing Water=Air Mengalir +River Water Source=Sumber Air Sungai +Flowing River Water=Air Sungai Mengalir +Lava Source=Sumber Lava +Flowing Lava=Lava Mengalir +Empty Bookshelf=Rak Buku Kosong +Bookshelf (@1 written, @2 empty books)=Rak Buku (@1 buku bertulis, @2 buku kosong) +Bookshelf=Rak Buku +Text too long=Tulisan terlalu panjang +Wooden Sign=Papan Tanda Kayu +Steel Sign=Papan Tanda Keluli +Wooden Ladder=Tangga Panjat Kayu +Steel Ladder=Tangga Panjat Keluli +Apple Wood Fence=Pagar Kayu Epal +Acacia Wood Fence=Pagar Kayu Akasia +Jungle Wood Fence=Pagar Kayu Hutan +Pine Wood Fence=Pagar Kayu Pain +Aspen Wood Fence=Pagar Kayu Aspen +Apple Wood Fence Rail=Pagar Rel Kayu Epal +Acacia Wood Fence Rail=Pagar Rel Kayu Akasia +Jungle Wood Fence Rail=Pagar Rel Kayu Hutan +Pine Wood Fence Rail=Pagar Rel Kayu Pain +Aspen Wood Fence Rail=Pagar Rel Kayu Aspen +Glass=Kaca +Obsidian Glass=Kaca Obsidia +Brick Block=Bongkah Bata +Mese Lamp=Lampu Mese +Mese Post Light=Lampu Tiang Mese +Cloud=Awan +Wooden Pickaxe=Beliung Kayu +Stone Pickaxe=Beliung Batu +Bronze Pickaxe=Beliung Gangsa +Steel Pickaxe=Beliung Keluli +Mese Pickaxe=Beliung Mese +Diamond Pickaxe=Beliung Intan +Wooden Shovel=Penyodok Kayu +Stone Shovel=Penyodok Batu +Bronze Shovel=Penyodok Gangsa +Steel Shovel=Penyodok Keluli +Mese Shovel=Penyodok Mese +Diamond Shovel=Penyodok Intan +Wooden Axe=Kapak Kayu +Stone Axe=Kapak Batu +Bronze Axe=Kapak Gangsa +Steel Axe=Kapak Keluli +Mese Axe=Kapak Mese +Diamond Axe=Kapak Intan +Wooden Sword=Pedang Kayu +Stone Sword=Pedang Batu +Bronze Sword=Pedang Gangsa +Steel Sword=Pedang Keluli +Mese Sword=Pedang Mese +Diamond Sword=Pedang Intan +Key=Kunci +Torch=Obor +@1 will intersect protection on growth.=@1 akan masuk kawasan perlindungan lain apabila ia tumbuh. +Title:=Tajuk: +Contents:=Kandungan: +Save=Simpan +by @1=oleh @1 +Page @1 of @2=Ms. @1 / @2 +"@1"="@1" diff --git a/mods/default/locale/default.ru.tr b/mods/default/locale/default.ru.tr new file mode 100644 index 0000000..214f669 --- /dev/null +++ b/mods/default/locale/default.ru.tr @@ -0,0 +1,211 @@ +# textdomain: default +Locked Chest=Заблокированный Сундук +Locked Chest (owned by @1)=Заблокированный Сундук (владелец: @1) +You do not own this chest.=Ð’Ñ‹ не владелец Ñтого Ñундука. +a locked chest=заблокированный Ñундук +Chest=Сундук +Stick=Палка +Paper=Бумага +"@1" by @2="@1" @2 +Book=Книга +Book with Text=Книга Ñ Ð¢ÐµÐºÑтом +Skeleton Key=Ключ Скелета +Key to @1's @2=Ключ к @2 от @1 +Coal Lump=КуÑок Ð£Ð³Ð»Ñ +Iron Lump=КуÑок Железа +Copper Lump=КуÑок Меди +Tin Lump=КуÑок Олова +Mese Crystal=КриÑталл МеÑе +Gold Lump=КуÑок Золота +Diamond=Ðлмаз +Clay Lump=Ком Глины +Steel Ingot=Железный БруÑок +Copper Ingot=Медный БруÑок +Tin Ingot=ОловÑнный БруÑок +Bronze Ingot=Бронзовый БруÑок +Gold Ingot=Золотой БруÑок +Mese Crystal Fragment=ОÑколок КриÑталла МеÑе +Clay Brick=ГлинÑный Кирпич +Obsidian Shard=ОбÑидиановый ОÑколок +Flint=Огниво +Blueberries=Черника +Furnace is empty=Печь пуÑÑ‚Ð°Ñ +100% (output full)=100% (полное приготовление) +@1%=@1% +Empty=ПуÑтое +Not cookable=Ðе может быть приготовлено +Furnace active=Печь зажжена +Furnace inactive=Печь не зажжена +(Item: @1; Fuel: @2)=(Предмет: @1; Топливо: @2) +Furnace=Печь +Stone=Камень +Cobblestone=Булыжник +Stone Brick=Каменный Кирпич +Stone Block=Каменный Блок +Mossy Cobblestone=МшиÑтый Булыжник +Desert Stone=ПуÑтынный Камень +Desert Cobblestone=ПуÑтынный Булыжник +Desert Stone Brick=ПуÑтынный Каменный Кирпич +Desert Stone Block=ПуÑтынный Каменный Блок +Sandstone=ПеÑчаник +Sandstone Brick=ПеÑчаниковый Кирпич +Sandstone Block=ПеÑчаниковый Блок +Desert Sandstone=ПуÑтынный ПеÑчаник +Desert Sandstone Brick=ПуÑтынный ПеÑчаниковый Кирпич +Desert Sandstone Block=ПуÑтынный ПеÑчаниковый Блок +Silver Sandstone=СеребрÑный ПеÑчаник +Silver Sandstone Brick=СеребрÑный ПеÑчаниковый Кирпич +Silver Sandstone Block=СеребрÑный ПеÑчаниковый Блок +Obsidian=ОбÑидиан +Obsidian Brick=ОбÑидиановый Кирпич +Obsidian Block=ОбÑидиановый Блок +Dirt=Ð—ÐµÐ¼Ð»Ñ +Dirt with Grass=Ð—ÐµÐ¼Ð»Ñ Ñ Ð¢Ñ€Ð°Ð²Ð¾Ð¹ +Dirt with Grass and Footsteps=Ð—ÐµÐ¼Ð»Ñ Ñ Ð¢Ñ€Ð°Ð²Ð¾Ð¹ и Следами +Dirt with Dry Grass=Ð—ÐµÐ¼Ð»Ñ Ñ Ð¡ÑƒÑ…Ð¾Ð¹ Травой +Dirt with Snow=Ð—ÐµÐ¼Ð»Ñ Ð¡Ð¾ Снегом +Dirt with Rainforest Litter=Ð—ÐµÐ¼Ð»Ñ Ñ Ð¢Ñ€Ð¾Ð¿Ð¸Ñ‡ÐµÑкой ПодÑтилкой +Dirt with Coniferous Litter=Ð—ÐµÐ¼Ð»Ñ Ñ Ð¡Ð¾Ñновой ПодÑтилкой +Dry Dirt=Ð¡ÑƒÑ…Ð°Ñ Ð—ÐµÐ¼Ð»Ñ +Dry Dirt with Dry Grass=Ð¡ÑƒÑ…Ð°Ñ Ð—ÐµÐ¼Ð»Ñ Ñ Ð¡ÑƒÑ…Ð¾Ð¹ Травой +Permafrost=Ð—Ð°Ð¼Ð¾Ñ€Ð¾Ð¶ÐµÐ½Ð½Ð°Ñ ÐŸÐ¾Ñ‡Ð²Ð° +Permafrost with Stones=Ð—Ð°Ð¼Ð¾Ñ€Ð¾Ð¶ÐµÐ½Ð½Ð°Ñ ÐŸÐ¾Ñ‡Ð²Ð° Ñ ÐšÐ°Ð¼Ð½Ñми +Permafrost with Moss=Ð—Ð°Ð¼Ð¾Ñ€Ð¾Ð¶ÐµÐ½Ð½Ð°Ñ ÐŸÐ¾Ñ‡Ð²Ð° Ñ ÐœÑ…Ð¾Ð¼ +Sand=ПеÑок +Desert Sand=ПуÑтынный ПеÑок +Silver Sand=СеребрÑный ПеÑок +Gravel=Гравий +Clay=ГлинÑный Блок +Snow=Снег +Snow Block=Снежный Блок +Ice=Лёд +Cave Ice=Пещерный Лёд +Apple Tree=Яблоневый Ствол +Apple Wood Planks=Яблоневые ДеревÑнные ДоÑки +Apple Tree Sapling=Яблоневый Саженец +Apple Tree Leaves=Ð¯Ð±Ð»Ð¾Ð½ÐµÐ²Ð°Ñ Ð›Ð¸Ñтва +Apple=Яблоко +Apple Marker=Ð¯Ð±Ð»Ð¾Ñ‡Ð½Ð°Ñ ÐœÐµÑ‚ÐºÐ° +Jungle Tree=Ствол ТропичеÑкого Дерева +Jungle Wood Planks=ДеревÑнные ДоÑки ТропичеÑкого Дерева +Jungle Tree Leaves=ЛиÑтва ТропичеÑкого Дерева +Jungle Tree Sapling=Саженец ТропичеÑкого Дерева +Emergent Jungle Tree Sapling=ВыроÑший Саженец ТропичеÑкого Дерева +Pine Tree=СоÑновый Ствол +Pine Wood Planks=СоÑновые ДеревÑнные ДоÑки +Pine Needles=СоÑÐ½Ð¾Ð²Ð°Ñ Ð¥Ð²Ð¾Ñ +Pine Tree Sapling=СоÑновый Саженец +Acacia Tree=Ствол Ðкации +Acacia Wood Planks=ДеревÑнные ДоÑки Ðкации +Acacia Tree Leaves=ЛиÑтва Ðкации +Acacia Tree Sapling=Саженец Ðкации +Aspen Tree=ОÑиновый Ствол +Aspen Wood Planks=ОÑиновые ДеревÑнные ДоÑки +Aspen Tree Leaves=ОÑÐ¸Ð½Ð¾Ð²Ð°Ñ Ð›Ð¸Ñтва +Aspen Tree Sapling=ОÑиновый Саженец +Coal Ore=Уголь +Coal Block=Угольный Блок +Iron Ore=Ð–ÐµÐ»ÐµÐ·Ð½Ð°Ñ Ð ÑƒÐ´Ð° +Steel Block=Стальной Блок +Copper Ore=ÐœÐµÐ´Ð½Ð°Ñ Ð ÑƒÐ´Ð° +Copper Block=Медный Блок +Tin Ore=ОловÑÐ½Ð½Ð°Ñ Ð ÑƒÐ´Ð° +Tin Block=ОловÑнный Блок +Bronze Block=Бронзовый Блок +Mese Ore=МеÑÐµÐ²Ð°Ñ Ð ÑƒÐ´Ð° +Mese Block=МеÑевый Блок +Gold Ore=Ð—Ð¾Ð»Ð¾Ñ‚Ð°Ñ Ð ÑƒÐ´Ð° +Gold Block=Золотой Блок +Diamond Ore=Ðлмаз +Diamond Block=Ðлмазный Блок +Cactus=ÐšÐ°ÐºÑ‚ÑƒÑ +Large Cactus Seedling=КактуÑовый Саженец +Papyrus=ÐŸÐ°Ð¿Ð¸Ñ€ÑƒÑ +Dry Shrub=Сухой КуÑÑ‚ +Jungle Grass=ТропичеÑÐºÐ°Ñ Ð¢Ñ€Ð°Ð²Ð° +Grass=Трава +Dry Grass=Ð¡ÑƒÑ…Ð°Ñ Ð¢Ñ€Ð°Ð²Ð° +Fern=Папоротник +Marram Grass=ПеÑколюб +Bush Stem=Ствол Яблочного Деревца +Bush Leaves=ЛиÑÑ‚ÑŒÑ Ð¯Ð±Ð»Ð¾Ñ‡Ð½Ð¾Ð³Ð¾ Деревца +Bush Sapling=Саженца Ñблочного деревца +Blueberry Bush Leaves with Berries=КуÑÑ‚ Черники Ñ Ð¯Ð³Ð¾Ð´Ð°Ð¼Ð¸ +Blueberry Bush Leaves=КуÑÑ‚ Черники +Blueberry Bush Sapling=Саженца КуÑта Черники +Acacia Bush Stem=Ствол Деревца Ðкации +Acacia Bush Leaves=ЛиÑÑ‚ÑŒÑ Ð”ÐµÑ€ÐµÐ²Ñ†Ð° Ðкации +Acacia Bush Sapling=Саженца Деревца Ðкации +Pine Bush Stem=СоÑновое Деревце +Pine Bush Needles=Ð¥Ð²Ð¾Ñ Ð¡Ð¾Ñнового Деревца +Pine Bush Sapling=Саженца СоÑнового Деревца +Kelp=Ð›Ð°Ð¼Ð¸Ð½Ð°Ñ€Ð¸Ñ +Green Coral=Зеленый Коралл +Pink Coral=Розовый Коралл +Cyan Coral=Голубой Коралл +Brown Coral=Бурый Коралл +Orange Coral=Оранжевый Коралл +Coral Skeleton=Коралловый ОÑтов +Water Source=Водный ИÑточник +Flowing Water=Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð’Ð¾Ð´Ð° +River Water Source=Речной Водный ИÑточник +Flowing River Water=Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð ÐµÑ‡Ð½Ð°Ñ Ð’Ð¾Ð´Ð° +Lava Source=Лавовый ИÑточник +Flowing Lava=Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð›Ð°Ð²Ð° +Empty Bookshelf=ПуÑÑ‚Ð°Ñ ÐšÐ½Ð¸Ð¶Ð½Ð°Ñ ÐŸÐ¾Ð»ÐºÐ° +Bookshelf (@1 written, @2 empty books)=ÐšÐ½Ð¸Ð¶Ð½Ð°Ñ ÐŸÐ¾Ð»ÐºÐ° (@1 напиÑано, @2 чиÑтые книги) +Bookshelf=ÐšÐ½Ð¸Ð¶Ð½Ð°Ñ ÐŸÐ¾Ð»ÐºÐ° +Text too long=ТекÑÑ‚ Ñлишком длинный +Wooden Sign=ДеревÑÐ½Ð½Ð°Ñ Ð¢Ð°Ð±Ð»Ð¸Ñ‡ÐºÐ° +Steel Sign=Ð¡Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¢Ð°Ð±Ð»Ð¸Ñ‡ÐºÐ° +Wooden Ladder=ДеревÑÐ½Ð½Ð°Ñ Ð›ÐµÑтница +Steel Ladder=Ð¡Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð›ÐµÑтница +Apple Wood Fence=Яблоневый ДеревÑнный Забор +Acacia Wood Fence=ДеревÑнный Забор Из Ðкации +Jungle Wood Fence=ДеревÑнный Забор Из ТропичеÑкого Дерева +Pine Wood Fence=СоÑновый ДеревÑнный Забор +Aspen Wood Fence=ОÑиновый ДеревÑнный Забор +Apple Wood Fence Rail=Яблоневый ДеревÑнный Реечный Забор +Acacia Wood Fence Rail=ДеревÑнный Реечный Забор Из Ðкации +Jungle Wood Fence Rail=ДеревÑнный Реечный Забор Из ТропичеÑкого Дерева +Pine Wood Fence Rail=СоÑновый ДеревÑнный Реечный Забор +Aspen Wood Fence Rail=ОÑиновый ДеревÑнный Реечный Забор +Glass=Стекло +Obsidian Glass=ОбÑидиановое Стекло +Brick Block=Кирпичный Блок +Mese Lamp=МеÑе Лампа +Mese Post Light=Столб Ñ ÐœÐµÑе Фонарем +Cloud=Облако +Wooden Pickaxe=ДеревÑÐ½Ð½Ð°Ñ ÐšÐ¸Ñ€ÐºÐ° +Stone Pickaxe=ÐšÐ°Ð¼ÐµÐ½Ð½Ð°Ñ ÐšÐ¸Ñ€ÐºÐ° +Bronze Pickaxe=Ð‘Ñ€Ð¾Ð½Ð·Ð¾Ð²Ð°Ñ ÐšÐ¸Ñ€ÐºÐ° +Steel Pickaxe=Ð¡Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ ÐšÐ¸Ñ€ÐºÐ° +Mese Pickaxe=МеÑе Кирка +Diamond Pickaxe=ÐÐ»Ð¼Ð°Ð·Ð½Ð°Ñ ÐšÐ¸Ñ€ÐºÐ° +Wooden Shovel=ДеревÑÐ½Ð½Ð°Ñ Ð›Ð¾Ð¿Ð°Ñ‚Ð° +Stone Shovel=ÐšÐ°Ð¼ÐµÐ½Ð½Ð°Ñ Ð›Ð¾Ð¿Ð°Ñ‚Ð° +Bronze Shovel=Ð‘Ñ€Ð¾Ð½Ð·Ð¾Ð²Ð°Ñ Ð›Ð¾Ð¿Ð°Ñ‚Ð° +Steel Shovel=Ð¡Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð›Ð¾Ð¿Ð°Ñ‚Ð° +Mese Shovel=МеÑе Лопата +Diamond Shovel=ÐÐ»Ð¼Ð°Ð·Ð½Ð°Ñ Ð›Ð¾Ð¿Ð°Ñ‚Ð° +Wooden Axe=ДеревÑнный Топор +Stone Axe=Каменный Топор +Bronze Axe=Бронзовый Топор +Steel Axe=Стальной Топор +Mese Axe=МеÑе Топор +Diamond Axe=Ðлмазный Топор +Wooden Sword=ДеревÑнный Меч +Stone Sword=Каменный Меч +Bronze Sword=Бронзовый Меч +Steel Sword=Стальной Меч +Mese Sword=МеÑе Меч +Diamond Sword=Ðлмазный Меч +Key=Ключ +Torch=Факел +@1 will intersect protection on growth.=@1 переÑечёт защиту по роÑту. +Title:=Заголовок: +Contents:=Содержимое: +Save=Сохранить +by @1=@1 +Page @1 of @2=Страница @1 из @2 +"@1"="@1" diff --git a/mods/default/locale/default.se.tr b/mods/default/locale/default.se.tr new file mode 100644 index 0000000..d123530 --- /dev/null +++ b/mods/default/locale/default.se.tr @@ -0,0 +1,211 @@ +## textdomain: default +Locked Chest=LÃ¥st kista +Locked Chest (owned by @1)=LÃ¥st kista (Ägd av @1) +You do not own this chest.=Du äger inte denna kistan. +a locked chest=en lÃ¥st kista +Chest=Kista +Stick=Pinne +Paper=Papper +"@1" by @2="@1" av @2 +Book=Bok +Book with Text=Bok med text +Skeleton Key=Skelett Nyckel +Key to @1's @2=Nyckel till @1s @2 +Coal Lump=Kol Klumo +Iron Lump=Järn Klump +Copper Lump=Koppar Klump +Tin Lump=Tenn Klump +Mese Crystal=Mese Kristall +Gold Lump=Guld Klump +Diamond=Diamant +Clay Lump=Lerklump +Steel Ingot=StÃ¥l tacka +Copper Ingot=Koppar tacka +Tin Ingot=Tenn tacka +Bronze Ingot=Brons tacka +Gold Ingot=Guld tacka +Mese Crystal Fragment=Mese Kristall Fragment +Clay Brick=Tegelsten +Obsidian Shard=Obsidian Skärva +Flint=Flinta +Blueberries=BlÃ¥bär +Furnace is empty=Ugnen är tom +100% (output full)=100% (utgÃ¥ngen full) +@1%=@1% +Empty=Tom +Not cookable=Inte kokbar +Furnace active=Ugn aktiv +Furnace inactive=Ugn inaktiv +(Item: @1; Fuel: @2)=(Sak: @1; Bränsle: @2) +Furnace=Ugn +Stone=Sten +Cobblestone=Kullersten +Stone Brick=Stentegel +Stone Block=Sten block +Mossy Cobblestone=Mossig kullersten +Desert Stone=Öken sten +Desert Cobblestone=Öken kullersten +Desert Stone Brick=Öken stentegel +Desert Stone Block=Öken sten block +Sandstone=Sandsten +Sandstone Brick=Sandstenstegel +Sandstone Block=Sandsten block +Desert Sandstone=Öken sandsten +Desert Sandstone Brick=Öken Sandstenstegel +Desert Sandstone Block=Öken sandsten block +Silver Sandstone=Silver sandsten +Silver Sandstone Brick=Silver Sandstenstegel +Silver Sandstone Block=Silver sandsten block +Obsidian=Obsidian +Obsidian Brick=Obsidiantegel +Obsidian Block=Obsidian block +Dirt=Jord +Dirt with Grass=Jord med gräs +Dirt with Grass and Footsteps=Jord med gräs och fotsteg +Dirt with Dry Grass=Jord med torrt gräs +Dirt with Snow=Jord med snö +Dirt with Rainforest Litter=Jord med regnskogströ +Dirt with Coniferous Litter=Jord med Barrträd +Dry Dirt=Torr jord +Dry Dirt with Dry Grass=Torr jord med torrt gräs +Permafrost=Permafrost +Permafrost with Stones=Permafrost med sten +Permafrost with Moss=Permafrost med mossa +Sand=Sand +Desert Sand=Öken sand +Silver Sand=Silver sand +Gravel=Grus +Clay=Lera +Snow=Snö +Snow Block=Snö block +Ice=Is +Cave Ice=Grott Is +Apple Tree=Äpple Träd +Apple Wood Planks=Äpple Plankor +Apple Tree Sapling=Äpple Planta +Apple Tree Leaves=Äpple Löv +Apple=Äpple +Apple Marker=Äpple Markör +Jungle Tree=Djungel Träd +Jungle Wood Planks=Djungel Plankor +Jungle Tree Leaves=Djungel Löv +Jungle Tree Sapling=Djungel Planta +Emergent Jungle Tree Sapling=Nybliven Djungel Planta +Pine Tree=Tall +Pine Wood Planks= Tall Plankor +Pine Needles=Granbarr +Pine Tree Sapling=Tall Planta +Acacia Tree=Akacia Träd +Acacia Wood Planks=Akacia Plankor +Acacia Tree Leaves=Akacia Löv +Acacia Tree Sapling=Akacia Planta +Aspen Tree=Asp +Aspen Wood Planks=Asp Plankor +Aspen Tree Leaves=Asp Löv +Aspen Tree Sapling=Asp Planta +Coal Ore=Kol Malm +Coal Block=Kol Block +Iron Ore=Järn Malm +Steel Block=StÃ¥l Block +Copper Ore=Koppar Malm +Copper Block=Koppar Block +Tin Ore=Tenn Malm +Tin Block=Tenn Block +Bronze Block=Brons Block +Mese Ore=Mese Malm +Mese Block=Mese Block +Gold Ore=Guld Malm +Gold Block=Guld Block +Diamond Ore=Diamant Malm +Diamond Block=Diamant Block +Cactus=Kaktus +Large Cactus Seedling=Stor kaktusplanta +Papyrus=Papyrus +Dry Shrub=Torr Buske +Jungle Grass=Djungel Gräs +Grass=Gräs +Dry Grass=Torrt Gräs +Fern=Ormbunke +Marram Grass=Marram Gräs +Bush Stem=Busk Stam +Bush Leaves=Busk Löv +Bush Sapling=Busk Planta +Blueberry Bush Leaves with Berries=BlÃ¥bärsbusks Löv med Bär +Blueberry Bush Leaves=BlÃ¥bärsbusks Löv +Blueberry Bush Sapling=BlÃ¥bärsbusks Plantga +Acacia Bush Stem=Akacia Busks Stam +Acacia Bush Leaves=Akacia Busks Löv +Acacia Bush Sapling=Akacia Busks Planta +Pine Bush Stem=Tall Busks Stam +Pine Bush Needles=Tall Busks Granbarr +Pine Bush Sapling=Tall Busks Planta +Kelp=Brunalg +Green Coral=Grön Korall +Pink Coral=Rosa Korall +Cyan Coral=Cyan Korall +Brown Coral=Brun Korall +Orange Coral=Orange Korall +Coral Skeleton=Korall Skelett +Water Source=Vattenkälla +Flowing Water=Flödande Vatten +River Water Source=Flodvattenkälla +Flowing River Water=Flödande Flodvatten +Lava Source=Lavakälla +Flowing Lava=Flödande Lava +Empty Bookshelf=Tom Bokhylla +Bookshelf (@1 written, @2 empty books)=Bokhylla (@1 skriva, @2 tomma böcker) +Bookshelf=Bokhylla +Text too long=Text för lÃ¥ng +Wooden Sign=Trä Skylt +Steel Sign=StÃ¥l Skylt +Wooden Ladder=Trä Stege +Steel Ladder=StÃ¥l Stege +Apple Wood Fence=Äpple Trä Staket +Acacia Wood Fence=Akacia Trä Staket +Jungle Wood Fence=Djungel Trä Staket +Pine Wood Fence=Tall Trä Staket +Aspen Wood Fence=Asp Trä Staket +Apple Wood Fence Rail=Äpple Trä Staket Pinne +Acacia Wood Fence Rail=Akacia Trä Staket Pinne +Jungle Wood Fence Rail=Djungel Trä Staket Pinne +Pine Wood Fence Rail=Tall Trä Staket Pinne +Aspen Wood Fence Rail=Asp Trä Staket Pinne +Glass=Glas +Obsidian Glass=Obsidian Glas +Brick Block=Tegelstens Block +Mese Lamp=Mese Lampa +Mese Post Light=Mese Postljus +Cloud=Moln +Wooden Pickaxe=Trä Hacka +Stone Pickaxe=Sten Hacka +Bronze Pickaxe=Brons Hacka +Steel Pickaxe=StÃ¥l Hacka +Mese Pickaxe=Mese Hacka +Diamond Pickaxe=Diamant Hacka +Wooden Shovel=Trä Spade +Stone Shovel=Sten Spade +Bronze Shovel=Brons Spade +Steel Shovel=StÃ¥l Spade +Mese Shovel=Mese Spade +Diamond Shovel=Diamant Spade +Wooden Axe=Trä Yxa +Stone Axe=Sten Yxa +Bronze Axe=Brons Yxa +Steel Axe=StÃ¥l Yxa +Mese Axe=Mese Yxa +Diamond Axe=Diamant Yxa +Wooden Sword=Trä Svärd +Stone Sword=Sten Svärd +Bronze Sword=Brons Svärd +Steel Sword=StÃ¥l Svärd +Mese Sword=Mese Svärd +Diamond Sword=Diamant Svärd +Key=Nyckel +Torch=Fakla +@1 will intersect protection on growth.=@1 kommer korsa skyddet mot tillväxt. +Title:=Titel: +Contents:=InnehÃ¥ll: +Save=Spara +by @1=av @1 +Page @1 of @2=Sida @1 av @2 +"@1"="@1" \ No newline at end of file diff --git a/mods/default/locale/default.zh_CN.tr b/mods/default/locale/default.zh_CN.tr new file mode 100644 index 0000000..ddd9471 --- /dev/null +++ b/mods/default/locale/default.zh_CN.tr @@ -0,0 +1,211 @@ +# textdomain: default +Locked Chest=已上é”çš„ç®±å­ +Locked Chest (owned by @1)=已上é”çš„ç®±å­ï¼ˆå±žäºŽ@1所有) +You do not own this chest.=这个箱å­ä¸å±žäºŽä½ æ‰€æœ‰ã€‚ +a locked chest=一个已上é”çš„ç®±å­ +Chest=ç®±å­ +Stick=棒 +Paper=纸 +"@1" by @2="@1" by @2 +Book=书 +Book with Text=带文字的书 +Skeleton Key=万能钥匙 +Key to @1's @2=@1çš„@2的钥匙 +Coal Lump=ç…¤å— +Iron Lump=é“å— +Copper Lump=é“œå— +Tin Lump=é”¡å— +Mese Crystal=黄石晶体 +Gold Lump=é‡‘å— +Diamond=钻石 +Clay Lump=ç²˜åœŸå— +Steel Ingot=é“é”­ +Copper Ingot=铜锭 +Tin Ingot=锡锭 +Bronze Ingot=é’铜锭 +Gold Ingot=金锭 +Mese Crystal Fragment=黄石晶体碎片 +Clay Brick=粘土砖 +Obsidian Shard=黑曜石碎片 +Flint=燧石 +Blueberries=è“莓 +Furnace is empty=熔炉是空的 +100% (output full)=100%(输出已满) +@1%=@1% +Empty=空 +Not cookable=ä¸å¯çƒ¹é¥ª +Furnace active=熔炉正在è¿è½¬ +Furnace inactive=熔炉未使用 +(Item: @1; Fuel: @2)=(项目:@1;燃料:@2) +Furnace=熔炉 +Stone=石 +Cobblestone=é¹…åµçŸ³ +Stone Brick=石砖 +Stone Block=çŸ³æ–¹å— +Mossy Cobblestone=苔藓覆盖的鹅åµçŸ³ +Desert Stone=沙漠石 +Desert Cobblestone=沙漠鹅åµçŸ³ +Desert Stone Brick=沙漠鹅åµçŸ³ç – +Desert Stone Block=沙漠鹅åµçŸ³æ–¹å— +Sandstone=砂岩 +Sandstone Brick=砂岩砖 +Sandstone Block=ç ‚å²©æ–¹å— +Desert Sandstone=沙漠砂岩 +Desert Sandstone Brick=沙漠砂岩砖 +Desert Sandstone Block=æ²™æ¼ ç ‚å²©æ–¹å— +Silver Sandstone=银砂岩 +Silver Sandstone Brick=银砂岩砖 +Silver Sandstone Block=é“¶ç ‚å²©æ–¹å— +Obsidian=黑曜石 +Obsidian Brick=黑曜石砖 +Obsidian Block=é»‘æ›œçŸ³æ–¹å— +Dirt=土 +Dirt with Grass=带è‰çš„土 +Dirt with Grass and Footsteps=带è‰çš„土åŠè„šå° +Dirt with Dry Grass=带干è‰çš„土 +Dirt with Snow=带雪的土 +Dirt with Rainforest Litter=雨林è…土 +Dirt with Coniferous Litter=é’ˆå¶æž—è…土 +Dry Dirt=干土 +Dry Dirt with Dry Grass=å¹²åœŸå’Œå¹²è‰ +Permafrost=多年冻土 +Permafrost with Stones=带石头的多年冻土 +Permafrost with Moss=生苔的多年冻土 +Sand=æ²™ +Desert Sand=沙漠沙 +Silver Sand=银沙 +Gravel=沙砾 +Clay=粘土 +Snow=雪 +Snow Block=é›ªæ–¹å— +Ice=冰 +Cave Ice=洞穴冰 +Apple Tree=苹果树 +Apple Wood Planks=è‹¹æžœæ ‘æœ¨æ¿ +Apple Tree Sapling=苹果树苗 +Apple Tree Leaves=è‹¹æžœæ ‘å¶ +Apple=苹果 +Apple Marker=苹果标记 +Jungle Tree=丛林树 +Jungle Wood Planks=ä¸›æž—æ ‘æœ¨æ¿ +Jungle Tree Leaves=ä¸›æž—æ ‘å¶ +Jungle Tree Sapling=丛林树苗 +Emergent Jungle Tree Sapling=应急丛林树苗 +Pine Tree=æ¾æ ‘ +Pine Wood Planks=æ¾æ ‘æœ¨æ¿ +Pine Needles=æ¾é’ˆ +Pine Tree Sapling=æ¾æ ‘æ ‘è‹— +Acacia Tree=相æ€æ ‘ +Acacia Wood Planks=相æ€æ ‘æœ¨æ¿ +Acacia Tree Leaves=相æ€æ ‘å¶ +Acacia Tree Sapling=相æ€æ ‘æ ‘è‹— +Aspen Tree=白æ¨æ ‘ +Aspen Wood Planks=白æ¨æ ‘æœ¨æ¿ +Aspen Tree Leaves=白æ¨æ ‘å¶ +Aspen Tree Sapling=白æ¨æ ‘æ ‘è‹— +Coal Ore=煤炭矿石 +Coal Block=ç…¤ç‚­æ–¹å— +Iron Ore=é“矿石 +Steel Block=é’¢æ–¹å— +Copper Ore=铜矿石 +Copper Block=é“œæ–¹å— +Tin Ore=锡矿石 +Tin Block=é”¡æ–¹å— +Bronze Block=é’é“œæ–¹å— +Mese Ore=黄石矿石 +Mese Block=é»„çŸ³æ–¹å— +Gold Ore=金矿石 +Gold Block=é‡‘æ–¹å— +Diamond Ore=钻石矿石 +Diamond Block=é’»çŸ³æ–¹å— +Cactus=仙人掌 +Large Cactus Seedling=大仙人掌苗 +Papyrus=莎è‰çº¸ +Dry Shrub=å¹²çŒæœ¨ +Jungle Grass=ä¸›æž—è‰ +Grass=è‰ +Dry Grass=å¹²è‰ +Fern=蕨 +Marram Grass=æ»¨è‰ +Bush Stem=çŒæœ¨ +Bush Leaves=çŒæœ¨å¶ +Bush Sapling=çŒæœ¨è‹— +Blueberry Bush Leaves with Berries=è“莓çŒæœ¨å¶ä¸Žæµ†æžœ +Blueberry Bush Leaves=è“莓çŒæœ¨å¶ +Blueberry Bush Sapling=è“莓çŒæœ¨è‹— +Acacia Bush Stem=相æ€çŒæœ¨ +Acacia Bush Leaves=相æ€çŒæœ¨å¶ +Acacia Bush Sapling=相æ€çŒæœ¨è‹— +Pine Bush Stem=æ¾æ ‘çŒæœ¨ +Pine Bush Needles=æ¾æ ‘çŒæœ¨é’ˆ +Pine Bush Sapling=æ¾æ ‘çŒæœ¨è‹— +Kelp=海带 +Green Coral=绿çŠç‘š +Pink Coral=淡红çŠç‘š +Cyan Coral=é’çŠç‘š +Brown Coral=棕çŠç‘š +Orange Coral=æ©™çŠç‘š +Coral Skeleton=çŠç‘šéª¨æž¶ +Water Source=æ°´æ–¹å— +Flowing Water=æµåŠ¨çš„æ°´ +River Water Source=æ²³æ°´æ–¹å— +Flowing River Water=æµåŠ¨çš„河水 +Lava Source=å²©æµ†æ–¹å— +Flowing Lava=æµåŠ¨çš„岩浆 +Empty Bookshelf=空书架 +Bookshelf (@1 written, @2 empty books)=书架(@1本有字的书,@2本空书) +Bookshelf=书架 +Text too long=文字太长 +Wooden Sign=木牌 +Steel Sign=é“牌 +Wooden Ladder=æœ¨æ¢¯å­ +Steel Ladder=é“æ¢¯å­ +Apple Wood Fence=è‹¹æžœæœ¨æ …æ  +Acacia Wood Fence=相æ€æœ¨æ …æ  +Jungle Wood Fence=ä¸›æž—æœ¨æ …æ  +Pine Wood Fence=æ¾æœ¨æ …æ  +Aspen Wood Fence=白æ¨æœ¨æ …æ  +Apple Wood Fence Rail=苹果木æ æ† +Acacia Wood Fence Rail=相æ€æœ¨æ æ† +Jungle Wood Fence Rail=丛林木æ æ† +Pine Wood Fence Rail=æ¾æœ¨æ æ† +Aspen Wood Fence Rail=白æ¨æœ¨æ æ† +Glass=玻璃 +Obsidian Glass=黑曜石玻璃 +Brick Block=ç –æ–¹å— +Mese Lamp=é»„çŸ³ç¯ +Mese Post Light=é»„çŸ³æŸ±ç¯ +Cloud=云 +Wooden Pickaxe=æœ¨é• +Stone Pickaxe=çŸ³é• +Bronze Pickaxe=é’é“œé• +Steel Pickaxe=é“é• +Mese Pickaxe=é»„çŸ³é• +Diamond Pickaxe=é’»çŸ³é• +Wooden Shovel=木铲 +Stone Shovel=石铲 +Bronze Shovel=é’铜铲 +Steel Shovel=é“铲 +Mese Shovel=黄石铲 +Diamond Shovel=钻石铲 +Wooden Axe=木斧 +Stone Axe=石斧 +Bronze Axe=é’铜斧 +Steel Axe=é“æ–§ +Mese Axe=黄石斧 +Diamond Axe=钻石斧 +Wooden Sword=木剑 +Stone Sword=石剑 +Bronze Sword=é’铜剑 +Steel Sword=é“剑 +Mese Sword=黄石剑 +Diamond Sword=钻石剑 +Key=钥匙 +Torch=ç«æŠŠ +@1 will intersect protection on growth.=@1将与增长的ä¿æŠ¤ç›¸äº¤ã€‚ +Title:=标题: +Contents:=内容: +Save=ä¿å­˜ +by @1=ç”±@1 +Page @1 of @2=第@1页,共@2页。 +"@1"="@1" diff --git a/mods/default/locale/default.zh_TW.tr b/mods/default/locale/default.zh_TW.tr new file mode 100644 index 0000000..6b06b8a --- /dev/null +++ b/mods/default/locale/default.zh_TW.tr @@ -0,0 +1,211 @@ +# textdomain: default +Locked Chest=å·²ä¸ŠéŽ–çš„ç®±å­ +Locked Chest (owned by @1)=已上鎖的箱å­ï¼ˆå±¬æ–¼@1所有) +You do not own this chest.=這個箱å­ä¸å±¬æ–¼ä½ æ‰€æœ‰ã€‚ +a locked chest=ä¸€å€‹å·²ä¸ŠéŽ–çš„ç®±å­ +Chest=ç®±å­ +Stick=棒 +Paper=ç´™ +"@1" by @2="@1" by @2 +Book=書 +Book with Text=帶文字的書 +Skeleton Key=è¬èƒ½é‘°åŒ™ +Key to @1's @2=@1çš„@2的鑰匙 +Coal Lump=煤塊 +Iron Lump=éµå¡Š +Copper Lump=銅塊 +Tin Lump=錫塊 +Mese Crystal=黃石晶體 +Gold Lump=金塊 +Diamond=鑽石 +Clay Lump=粘土塊 +Steel Ingot=éµéŒ  +Copper Ingot=銅錠 +Tin Ingot=錫錠 +Bronze Ingot=é’銅錠 +Gold Ingot=金錠 +Mese Crystal Fragment=黃石晶體碎片 +Clay Brick=粘土磚 +Obsidian Shard=黑曜石碎片 +Flint=燧石 +Blueberries=è—莓 +Furnace is empty=熔çˆæ˜¯ç©ºçš„ +100% (output full)=100%(輸出已滿) +@1%=@1% +Empty=空 +Not cookable=ä¸å¯çƒ¹é£ª +Furnace active=熔çˆæ­£åœ¨é‹è½‰ +Furnace inactive=熔çˆæœªä½¿ç”¨ +(Item: @1; Fuel: @2)=(項目:@1;燃料:@2) +Furnace=ç†”çˆ +Stone=石 +Cobblestone=éµåµçŸ³ +Stone Brick=石磚 +Stone Block=石方塊 +Mossy Cobblestone=苔蘚覆蓋的éµåµçŸ³ +Desert Stone=沙漠石 +Desert Cobblestone=沙漠éµåµçŸ³ +Desert Stone Brick=沙漠éµåµçŸ³ç£š +Desert Stone Block=沙漠éµåµçŸ³æ–¹å¡Š +Sandstone=砂岩 +Sandstone Brick=砂岩磚 +Sandstone Block=砂岩方塊 +Desert Sandstone=沙漠砂岩 +Desert Sandstone Brick=沙漠砂岩磚 +Desert Sandstone Block=沙漠砂岩方塊 +Silver Sandstone=銀砂岩 +Silver Sandstone Brick=銀砂岩磚 +Silver Sandstone Block=銀砂岩方塊 +Obsidian=黑曜石 +Obsidian Brick=黑曜石磚 +Obsidian Block=黑曜石方塊 +Dirt=土 +Dirt with Grass=帶è‰çš„土 +Dirt with Grass and Footsteps=帶è‰çš„土åŠè…³å° +Dirt with Dry Grass=帶乾è‰çš„土 +Dirt with Snow=帶雪的土 +Dirt with Rainforest Litter=雨林è…土 +Dirt with Coniferous Litter=é‡è‘‰æž—è…土 +Dry Dirt=乾土 +Dry Dirt with Dry Grass=ä¹¾åœŸå’Œä¹¾è‰ +Permafrost=多年å‡åœŸ +Permafrost with Stones=帶石頭的多年å‡åœŸ +Permafrost with Moss=生苔的多年å‡åœŸ +Sand=æ²™ +Desert Sand=沙漠沙 +Silver Sand=銀沙 +Gravel=沙礫 +Clay=粘土 +Snow=雪 +Snow Block=雪方塊 +Ice=冰 +Cave Ice=洞穴冰 +Apple Tree=蘋果樹 +Apple Wood Planks=è˜‹æžœæ¨¹æœ¨æ¿ +Apple Tree Sapling=蘋果樹苗 +Apple Tree Leaves=蘋果樹葉 +Apple=蘋果 +Apple Marker=蘋果標記 +Jungle Tree=å¢æž—樹 +Jungle Wood Planks=å¢æž—æ¨¹æœ¨æ¿ +Jungle Tree Leaves=å¢æž—樹葉 +Jungle Tree Sapling=å¢æž—樹苗 +Emergent Jungle Tree Sapling=應急å¢æž—樹苗 +Pine Tree=æ¾æ¨¹ +Pine Wood Planks=æ¾æ¨¹æœ¨æ¿ +Pine Needles=æ¾é‡ +Pine Tree Sapling=æ¾æ¨¹æ¨¹è‹— +Acacia Tree=相æ€æ¨¹ +Acacia Wood Planks=相æ€æ¨¹æœ¨æ¿ +Acacia Tree Leaves=相æ€æ¨¹è‘‰ +Acacia Tree Sapling=相æ€æ¨¹æ¨¹è‹— +Aspen Tree=白楊樹 +Aspen Wood Planks=ç™½æ¥Šæ¨¹æœ¨æ¿ +Aspen Tree Leaves=白楊樹葉 +Aspen Tree Sapling=白楊樹樹苗 +Coal Ore=煤炭礦石 +Coal Block=煤炭方塊 +Iron Ore=éµç¤¦çŸ³ +Steel Block=鋼方塊 +Copper Ore=銅礦石 +Copper Block=銅方塊 +Tin Ore=錫礦石 +Tin Block=錫方塊 +Bronze Block=é’銅方塊 +Mese Ore=黃石礦石 +Mese Block=黃石方塊 +Gold Ore=金礦石 +Gold Block=金方塊 +Diamond Ore=鑽石礦石 +Diamond Block=鑽石方塊 +Cactus=仙人掌 +Large Cactus Seedling=大仙人掌苗 +Papyrus=莎è‰ç´™ +Dry Shrub=å¹¹çŒæœ¨ +Jungle Grass=å¢æž—è‰ +Grass=è‰ +Dry Grass=ä¹¾è‰ +Fern=蕨 +Marram Grass=æ¿±è‰ +Bush Stem=çŒæœ¨ +Bush Leaves=çŒæœ¨è‘‰ +Bush Sapling=çŒæœ¨è‹— +Blueberry Bush Leaves with Berries=è—莓çŒæœ¨è‘‰èˆ‡æ¼¿æžœ +Blueberry Bush Leaves=è—莓çŒæœ¨è‘‰ +Blueberry Bush Sapling=è—莓çŒæœ¨è‹— +Acacia Bush Stem=相æ€çŒæœ¨ +Acacia Bush Leaves=相æ€çŒæœ¨è‘‰ +Acacia Bush Sapling=相æ€çŒæœ¨è‹— +Pine Bush Stem=æ¾æ¨¹çŒæœ¨ +Pine Bush Needles=æ¾æ¨¹çŒæœ¨é‡ +Pine Bush Sapling=æ¾æ¨¹çŒæœ¨è‹— +Kelp=海帶 +Green Coral=綠çŠç‘š +Pink Coral=æ·¡ç´…çŠç‘š +Cyan Coral=é’çŠç‘š +Brown Coral=棕çŠç‘š +Orange Coral=æ©™çŠç‘š +Coral Skeleton=çŠç‘šéª¨æž¶ +Water Source=水方塊 +Flowing Water=æµå‹•çš„æ°´ +River Water Source=河水方塊 +Flowing River Water=æµå‹•çš„河水 +Lava Source=岩漿方塊 +Flowing Lava=æµå‹•çš„岩漿 +Empty Bookshelf=空書架 +Bookshelf (@1 written, @2 empty books)=書架(@1本有字的書,@2本空書) +Bookshelf=書架 +Text too long=文字太長 +Wooden Sign=木牌 +Steel Sign=éµç‰Œ +Wooden Ladder=æœ¨æ¢¯å­ +Steel Ladder=éµæ¢¯å­ +Apple Wood Fence=蘋果木柵欄 +Acacia Wood Fence=相æ€æœ¨æŸµæ¬„ +Jungle Wood Fence=å¢æž—木柵欄 +Pine Wood Fence=æ¾æœ¨æŸµæ¬„ +Aspen Wood Fence=白楊木柵欄 +Apple Wood Fence Rail=è˜‹æžœæœ¨æ¬„æ† +Acacia Wood Fence Rail=相æ€æœ¨æ¬„æ† +Jungle Wood Fence Rail=å¢æž—æœ¨æ¬„æ† +Pine Wood Fence Rail=æ¾æœ¨æ¬„æ† +Aspen Wood Fence Rail=ç™½æ¥Šæœ¨æ¬„æ† +Glass=玻璃 +Obsidian Glass=黑曜石玻璃 +Brick Block=磚方塊 +Mese Lamp=黃石燈 +Mese Post Light=黃石柱燈 +Cloud=雲 +Wooden Pickaxe=木鎬 +Stone Pickaxe=石鎬 +Bronze Pickaxe=é’銅鎬 +Steel Pickaxe=éµéŽ¬ +Mese Pickaxe=黃石鎬 +Diamond Pickaxe=鑽石鎬 +Wooden Shovel=æœ¨éŸ +Stone Shovel=çŸ³éŸ +Bronze Shovel=é’éŠ…éŸ +Steel Shovel=éµéŸ +Mese Shovel=é»ƒçŸ³éŸ +Diamond Shovel=é‘½çŸ³éŸ +Wooden Axe=木斧 +Stone Axe=石斧 +Bronze Axe=é’銅斧 +Steel Axe=éµæ–§ +Mese Axe=黃石斧 +Diamond Axe=鑽石斧 +Wooden Sword=æœ¨åŠ +Stone Sword=çŸ³åŠ +Bronze Sword=é’éŠ…åŠ +Steel Sword=éµåŠ +Mese Sword=é»ƒçŸ³åŠ +Diamond Sword=é‘½çŸ³åŠ +Key=鑰匙 +Torch=ç«æŠŠ +@1 will intersect protection on growth.=@1將與增長的ä¿è­·ç›¸äº¤ã€‚ +Title:=標題: +Contents:=內容: +Save=ä¿å­˜ +by @1=ç”±@1 +Page @1 of @2=第@1é ï¼Œå…±@2é ã€‚ +"@1"="@1" diff --git a/mods/default/locale/template.txt b/mods/default/locale/template.txt new file mode 100644 index 0000000..c8e616c --- /dev/null +++ b/mods/default/locale/template.txt @@ -0,0 +1,211 @@ +# textdomain: default +Locked Chest= +Locked Chest (owned by @1)= +You do not own this chest.= +a locked chest= +Chest= +Stick= +Paper= +"@1" by @2= +Book= +Book with Text= +Skeleton Key= +Key to @1's @2= +Coal Lump= +Iron Lump= +Copper Lump= +Tin Lump= +Mese Crystal= +Gold Lump= +Diamond= +Clay Lump= +Steel Ingot= +Copper Ingot= +Tin Ingot= +Bronze Ingot= +Gold Ingot= +Mese Crystal Fragment= +Clay Brick= +Obsidian Shard= +Flint= +Blueberries= +Furnace is empty= +100% (output full)= +@1%= +Empty= +Not cookable= +Furnace active= +Furnace inactive= +(Item: @1; Fuel: @2)= +Furnace= +Stone= +Cobblestone= +Stone Brick= +Stone Block= +Mossy Cobblestone= +Desert Stone= +Desert Cobblestone= +Desert Stone Brick= +Desert Stone Block= +Sandstone= +Sandstone Brick= +Sandstone Block= +Desert Sandstone= +Desert Sandstone Brick= +Desert Sandstone Block= +Silver Sandstone= +Silver Sandstone Brick= +Silver Sandstone Block= +Obsidian= +Obsidian Brick= +Obsidian Block= +Dirt= +Dirt with Grass= +Dirt with Grass and Footsteps= +Dirt with Dry Grass= +Dirt with Snow= +Dirt with Rainforest Litter= +Dirt with Coniferous Litter= +Dry Dirt= +Dry Dirt with Dry Grass= +Permafrost= +Permafrost with Stones= +Permafrost with Moss= +Sand= +Desert Sand= +Silver Sand= +Gravel= +Clay= +Snow= +Snow Block= +Ice= +Cave Ice= +Apple Tree= +Apple Wood Planks= +Apple Tree Sapling= +Apple Tree Leaves= +Apple= +Apple Marker= +Jungle Tree= +Jungle Wood Planks= +Jungle Tree Leaves= +Jungle Tree Sapling= +Emergent Jungle Tree Sapling= +Pine Tree= +Pine Wood Planks= +Pine Needles= +Pine Tree Sapling= +Acacia Tree= +Acacia Wood Planks= +Acacia Tree Leaves= +Acacia Tree Sapling= +Aspen Tree= +Aspen Wood Planks= +Aspen Tree Leaves= +Aspen Tree Sapling= +Coal Ore= +Coal Block= +Iron Ore= +Steel Block= +Copper Ore= +Copper Block= +Tin Ore= +Tin Block= +Bronze Block= +Mese Ore= +Mese Block= +Gold Ore= +Gold Block= +Diamond Ore= +Diamond Block= +Cactus= +Large Cactus Seedling= +Papyrus= +Dry Shrub= +Jungle Grass= +Grass= +Dry Grass= +Fern= +Marram Grass= +Bush Stem= +Bush Leaves= +Bush Sapling= +Blueberry Bush Leaves with Berries= +Blueberry Bush Leaves= +Blueberry Bush Sapling= +Acacia Bush Stem= +Acacia Bush Leaves= +Acacia Bush Sapling= +Pine Bush Stem= +Pine Bush Needles= +Pine Bush Sapling= +Kelp= +Green Coral= +Pink Coral= +Cyan Coral= +Brown Coral= +Orange Coral= +Coral Skeleton= +Water Source= +Flowing Water= +River Water Source= +Flowing River Water= +Lava Source= +Flowing Lava= +Empty Bookshelf= +Bookshelf (@1 written, @2 empty books)= +Bookshelf= +Text too long= +Wooden Sign= +Steel Sign= +Wooden Ladder= +Steel Ladder= +Apple Wood Fence= +Acacia Wood Fence= +Jungle Wood Fence= +Pine Wood Fence= +Aspen Wood Fence= +Apple Wood Fence Rail= +Acacia Wood Fence Rail= +Jungle Wood Fence Rail= +Pine Wood Fence Rail= +Aspen Wood Fence Rail= +Glass= +Obsidian Glass= +Brick Block= +Mese Lamp= +Mese Post Light= +Cloud= +Wooden Pickaxe= +Stone Pickaxe= +Bronze Pickaxe= +Steel Pickaxe= +Mese Pickaxe= +Diamond Pickaxe= +Wooden Shovel= +Stone Shovel= +Bronze Shovel= +Steel Shovel= +Mese Shovel= +Diamond Shovel= +Wooden Axe= +Stone Axe= +Bronze Axe= +Steel Axe= +Mese Axe= +Diamond Axe= +Wooden Sword= +Stone Sword= +Bronze Sword= +Steel Sword= +Mese Sword= +Diamond Sword= +Key= +Torch= +@1 will intersect protection on growth.= +Title:= +Contents:= +Save= +by @1= +Page @1 of @2= +"@1"= diff --git a/mods/default/mapgen.lua b/mods/default/mapgen.lua new file mode 100644 index 0000000..8c161d1 --- /dev/null +++ b/mods/default/mapgen.lua @@ -0,0 +1,2492 @@ +-- +-- Aliases for map generators +-- + +-- All mapgens + +minetest.register_alias("mapgen_stone", "default:stone") +minetest.register_alias("mapgen_water_source", "default:water_source") +minetest.register_alias("mapgen_river_water_source", "default:river_water_source") + +-- Additional aliases needed for mapgen v6 + +minetest.register_alias("mapgen_lava_source", "default:lava_source") +minetest.register_alias("mapgen_dirt", "default:dirt") +minetest.register_alias("mapgen_dirt_with_grass", "default:dirt_with_grass") +minetest.register_alias("mapgen_sand", "default:sand") +minetest.register_alias("mapgen_gravel", "default:gravel") +minetest.register_alias("mapgen_desert_stone", "default:desert_stone") +minetest.register_alias("mapgen_desert_sand", "default:desert_sand") +minetest.register_alias("mapgen_dirt_with_snow", "default:dirt_with_snow") +minetest.register_alias("mapgen_snowblock", "default:snowblock") +minetest.register_alias("mapgen_snow", "default:snow") +minetest.register_alias("mapgen_ice", "default:ice") + +minetest.register_alias("mapgen_tree", "default:tree") +minetest.register_alias("mapgen_leaves", "default:leaves") +minetest.register_alias("mapgen_apple", "default:apple") +minetest.register_alias("mapgen_jungletree", "default:jungletree") +minetest.register_alias("mapgen_jungleleaves", "default:jungleleaves") +minetest.register_alias("mapgen_junglegrass", "default:junglegrass") +minetest.register_alias("mapgen_pine_tree", "default:pine_tree") +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") + + +-- +-- Register ores +-- + +-- Mgv6 + +function default.register_mgv6_ores() + + -- Blob ore + -- These first to avoid other ores in blobs + + -- Clay + -- This first to avoid clay in sand blobs + + minetest.register_ore({ + ore_type = "blob", + ore = "default:clay", + wherein = {"default:sand"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 0, + y_min = -15, + 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 + }, + }) + + -- Sand + + minetest.register_ore({ + ore_type = "blob", + ore = "default:sand", + wherein = {"default:stone", "default:desert_stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 0, + y_min = -31, + 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 + }, + }) + + -- Dirt + + minetest.register_ore({ + ore_type = "blob", + ore = "default:dirt", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -31, + 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 + }, + }) + + -- Gravel + + minetest.register_ore({ + ore_type = "blob", + ore = "default:gravel", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -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 + }, + }) + + -- Scatter ores + + -- Coal + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_coal", + wherein = "default:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 9, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_coal", + wherein = "default:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 8, + clust_size = 3, + y_max = 64, + y_min = -31000, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_coal", + wherein = "default:stone", + clust_scarcity = 24 * 24 * 24, + clust_num_ores = 27, + clust_size = 6, + y_max = 0, + y_min = -31000, + }) + + -- Iron + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 12, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 5, + clust_size = 3, + y_max = 0, + y_min = -31000, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 24 * 24 * 24, + clust_num_ores = 27, + clust_size = 6, + y_max = -64, + y_min = -31000, + }) + + -- Copper + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 4, + clust_size = 3, + y_max = -16, + y_min = -63, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = -64, + y_min = -31000, + }) + + -- Tin + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 4, + clust_size = 3, + y_max = -32, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -31000, + }) + + -- Gold + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 3, + clust_size = 2, + y_max = -64, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Mese crystal + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 18 * 18 * 18, + clust_num_ores = 3, + clust_size = 2, + y_max = -64, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Diamond + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_max = -128, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = -256, + y_min = -31000, + }) + + -- Mese block + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = -1024, + y_min = -31000, + }) +end + + +-- All mapgens except mgv6 + +function default.register_ores() + + -- Stratum ores. + -- These obviously first. + + -- Silver sandstone + + minetest.register_ore({ + ore_type = "stratum", + ore = "default:silver_sandstone", + wherein = {"default:stone"}, + clust_scarcity = 1, + y_max = 46, + y_min = 10, + noise_params = { + offset = 28, + scale = 16, + spread = {x = 128, y = 128, z = 128}, + seed = 90122, + octaves = 1, + }, + stratum_thickness = 4, + biomes = {"cold_desert"}, + }) + + minetest.register_ore({ + ore_type = "stratum", + ore = "default:silver_sandstone", + wherein = {"default:stone"}, + clust_scarcity = 1, + y_max = 42, + y_min = 6, + noise_params = { + offset = 24, + scale = 16, + spread = {x = 128, y = 128, z = 128}, + seed = 90122, + octaves = 1, + }, + stratum_thickness = 2, + biomes = {"cold_desert"}, + }) + + -- Desert sandstone + + minetest.register_ore({ + ore_type = "stratum", + ore = "default:desert_sandstone", + wherein = {"default:desert_stone"}, + clust_scarcity = 1, + y_max = 46, + y_min = 10, + noise_params = { + offset = 28, + scale = 16, + spread = {x = 128, y = 128, z = 128}, + seed = 90122, + octaves = 1, + }, + stratum_thickness = 4, + biomes = {"desert"}, + }) + + minetest.register_ore({ + ore_type = "stratum", + ore = "default:desert_sandstone", + wherein = {"default:desert_stone"}, + clust_scarcity = 1, + y_max = 42, + y_min = 6, + noise_params = { + offset = 24, + scale = 16, + spread = {x = 128, y = 128, z = 128}, + seed = 90122, + octaves = 1, + }, + stratum_thickness = 2, + biomes = {"desert"}, + }) + + -- Sandstone + + minetest.register_ore({ + ore_type = "stratum", + ore = "default:sandstone", + wherein = {"default:desert_stone"}, + clust_scarcity = 1, + y_max = 39, + y_min = 3, + noise_params = { + offset = 21, + scale = 16, + spread = {x = 128, y = 128, z = 128}, + seed = 90122, + octaves = 1, + }, + stratum_thickness = 2, + biomes = {"desert"}, + }) + + -- Blob ore. + -- These before scatter ores to avoid other ores in blobs. + + -- Clay + + minetest.register_ore({ + ore_type = "blob", + ore = "default:clay", + wherein = {"default:sand"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 0, + y_min = -15, + 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_max = 31000, + y_min = -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 + }, + }) + + -- Dirt + + minetest.register_ore({ + ore_type = "blob", + ore = "default:dirt", + wherein = {"default:stone"}, + clust_scarcity = 16 * 16 * 16, + clust_size = 5, + y_max = 31000, + y_min = -31, + 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 + }, + -- Only where default:dirt is present as surface material + biomes = {"taiga", "snowy_grassland", "grassland", "coniferous_forest", + "deciduous_forest", "deciduous_forest_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_max = 31000, + y_min = -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 + }, + }) + + -- Scatter ores + + -- Coal + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_coal", + wherein = "default:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 9, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_coal", + wherein = "default:stone", + clust_scarcity = 8 * 8 * 8, + clust_num_ores = 8, + clust_size = 3, + y_max = 64, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_coal", + wherein = "default:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 30, + clust_size = 5, + y_max = -128, + y_min = -31000, + }) + + -- Tin + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 4, + clust_size = 3, + y_max = -64, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_tin", + wherein = "default:stone", + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -31000, + }) + + -- Copper + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 4, + clust_size = 3, + y_max = -64, + y_min = -127, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_copper", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -31000, + }) + + -- Iron + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 9 * 9 * 9, + clust_num_ores = 12, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 5, + clust_size = 3, + y_max = -128, + y_min = -255, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_iron", + wherein = "default:stone", + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 29, + clust_size = 5, + y_max = -256, + y_min = -31000, + }) + + -- Gold + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 3, + clust_size = 2, + y_max = -256, + y_min = -511, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_gold", + wherein = "default:stone", + clust_scarcity = 13 * 13 * 13, + clust_num_ores = 5, + clust_size = 3, + y_max = -512, + y_min = -31000, + }) + + -- Mese crystal + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 18 * 18 * 18, + clust_num_ores = 3, + clust_size = 2, + y_max = -512, + y_min = -1023, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_mese", + wherein = "default:stone", + clust_scarcity = 14 * 14 * 14, + clust_num_ores = 5, + clust_size = 3, + y_max = -1024, + y_min = -31000, + }) + + -- Diamond + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_max = -1024, + y_min = -2047, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:stone_with_diamond", + wherein = "default:stone", + clust_scarcity = 15 * 15 * 15, + clust_num_ores = 4, + clust_size = 3, + y_max = -2048, + y_min = -31000, + }) + + -- Mese block + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = 31000, + y_min = 1025, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 36 * 36 * 36, + clust_num_ores = 3, + clust_size = 2, + y_max = -2048, + y_min = -4095, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "default:mese", + wherein = "default:stone", + clust_scarcity = 28 * 28 * 28, + clust_num_ores = 5, + clust_size = 3, + y_max = -4096, + y_min = -31000, + }) +end + + +-- +-- Register biomes +-- + +-- All mapgens except mgv6 + +function default.register_biomes() + + -- Icesheet + + minetest.register_biome({ + name = "icesheet", + node_dust = "default:snowblock", + node_top = "default:snowblock", + depth_top = 1, + node_filler = "default:snowblock", + depth_filler = 3, + node_stone = "default:cave_ice", + node_water_top = "default:ice", + depth_water_top = 10, + node_river_water = "default:ice", + node_riverbed = "default:gravel", + depth_riverbed = 2, + node_dungeon = "default:ice", + node_dungeon_stair = "stairs:stair_ice", + y_max = 31000, + y_min = -8, + heat_point = 0, + humidity_point = 73, + }) + + minetest.register_biome({ + name = "icesheet_ocean", + node_dust = "default:snowblock", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_water_top = "default:ice", + depth_water_top = 10, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -9, + y_min = -255, + heat_point = 0, + humidity_point = 73, + }) + + minetest.register_biome({ + name = "icesheet_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 0, + humidity_point = 73, + }) + + -- Tundra + + minetest.register_biome({ + name = "tundra_highland", + node_dust = "default:snow", + node_riverbed = "default:gravel", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 47, + heat_point = 0, + humidity_point = 40, + }) + + minetest.register_biome({ + name = "tundra", + node_top = "default:permafrost_with_stones", + depth_top = 1, + node_filler = "default:permafrost", + depth_filler = 1, + node_riverbed = "default:gravel", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 4, + y_max = 46, + y_min = 2, + heat_point = 0, + humidity_point = 40, + }) + + minetest.register_biome({ + name = "tundra_beach", + node_top = "default:gravel", + depth_top = 1, + node_filler = "default:gravel", + depth_filler = 2, + node_riverbed = "default:gravel", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = 1, + y_min = -3, + heat_point = 0, + humidity_point = 40, + }) + + minetest.register_biome({ + name = "tundra_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:gravel", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = -4, + y_min = -255, + heat_point = 0, + humidity_point = 40, + }) + + minetest.register_biome({ + name = "tundra_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 0, + humidity_point = 40, + }) + + -- Taiga + + minetest.register_biome({ + name = "taiga", + node_dust = "default:snow", + node_top = "default:dirt_with_snow", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 4, + heat_point = 25, + humidity_point = 70, + }) + + minetest.register_biome({ + name = "taiga_ocean", + node_dust = "default:snow", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = 3, + y_min = -255, + heat_point = 25, + humidity_point = 70, + }) + + minetest.register_biome({ + name = "taiga_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 25, + humidity_point = 70, + }) + + -- Snowy grassland + + minetest.register_biome({ + name = "snowy_grassland", + node_dust = "default:snow", + node_top = "default:dirt_with_snow", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 1, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 4, + heat_point = 20, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "snowy_grassland_ocean", + node_dust = "default:snow", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = 3, + y_min = -255, + heat_point = 20, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "snowy_grassland_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 20, + humidity_point = 35, + }) + + -- Grassland + + minetest.register_biome({ + name = "grassland", + node_top = "default:dirt_with_grass", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 1, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 6, + heat_point = 50, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "grassland_dunes", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 2, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = 5, + y_min = 4, + heat_point = 50, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "grassland_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 3, + y_min = -255, + heat_point = 50, + humidity_point = 35, + }) + + minetest.register_biome({ + name = "grassland_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 50, + humidity_point = 35, + }) + + -- Coniferous forest + + minetest.register_biome({ + name = "coniferous_forest", + node_top = "default:dirt_with_coniferous_litter", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 6, + heat_point = 45, + humidity_point = 70, + }) + + minetest.register_biome({ + name = "coniferous_forest_dunes", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = 5, + y_min = 4, + heat_point = 45, + humidity_point = 70, + }) + + minetest.register_biome({ + name = "coniferous_forest_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 3, + y_min = -255, + heat_point = 45, + humidity_point = 70, + }) + + minetest.register_biome({ + name = "coniferous_forest_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 45, + humidity_point = 70, + }) + + -- Deciduous forest + + minetest.register_biome({ + name = "deciduous_forest", + node_top = "default:dirt_with_grass", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 1, + heat_point = 60, + humidity_point = 68, + }) + + minetest.register_biome({ + name = "deciduous_forest_shore", + node_top = "default:dirt", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 0, + y_min = -1, + heat_point = 60, + humidity_point = 68, + }) + + minetest.register_biome({ + name = "deciduous_forest_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = -2, + y_min = -255, + heat_point = 60, + humidity_point = 68, + }) + + minetest.register_biome({ + name = "deciduous_forest_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 60, + humidity_point = 68, + }) + + -- Desert + + minetest.register_biome({ + name = "desert", + node_top = "default:desert_sand", + depth_top = 1, + node_filler = "default:desert_sand", + depth_filler = 1, + node_stone = "default:desert_stone", + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:desert_stone", + node_dungeon_stair = "stairs:stair_desert_stone", + y_max = 31000, + y_min = 4, + heat_point = 92, + humidity_point = 16, + }) + + minetest.register_biome({ + name = "desert_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_stone = "default:desert_stone", + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:desert_stone", + node_dungeon_stair = "stairs:stair_desert_stone", + vertical_blend = 1, + y_max = 3, + y_min = -255, + heat_point = 92, + humidity_point = 16, + }) + + minetest.register_biome({ + name = "desert_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 92, + humidity_point = 16, + }) + + -- Sandstone desert + + minetest.register_biome({ + name = "sandstone_desert", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 1, + node_stone = "default:sandstone", + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:sandstonebrick", + node_dungeon_stair = "stairs:stair_sandstone_block", + y_max = 31000, + y_min = 4, + heat_point = 60, + humidity_point = 0, + }) + + minetest.register_biome({ + name = "sandstone_desert_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_stone = "default:sandstone", + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:sandstonebrick", + node_dungeon_stair = "stairs:stair_sandstone_block", + y_max = 3, + y_min = -255, + heat_point = 60, + humidity_point = 0, + }) + + minetest.register_biome({ + name = "sandstone_desert_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 60, + humidity_point = 0, + }) + + -- Cold desert + + minetest.register_biome({ + name = "cold_desert", + node_top = "default:silver_sand", + depth_top = 1, + node_filler = "default:silver_sand", + depth_filler = 1, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 4, + heat_point = 40, + humidity_point = 0, + }) + + minetest.register_biome({ + name = "cold_desert_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = 3, + y_min = -255, + heat_point = 40, + humidity_point = 0, + }) + + minetest.register_biome({ + name = "cold_desert_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 40, + humidity_point = 0, + }) + + -- Savanna + + minetest.register_biome({ + name = "savanna", + node_top = "default:dry_dirt_with_dry_grass", + depth_top = 1, + node_filler = "default:dry_dirt", + depth_filler = 1, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 1, + heat_point = 89, + humidity_point = 42, + }) + + minetest.register_biome({ + name = "savanna_shore", + node_top = "default:dry_dirt", + depth_top = 1, + node_filler = "default:dry_dirt", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 0, + y_min = -1, + heat_point = 89, + humidity_point = 42, + }) + + minetest.register_biome({ + name = "savanna_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = -2, + y_min = -255, + heat_point = 89, + humidity_point = 42, + }) + + minetest.register_biome({ + name = "savanna_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 89, + humidity_point = 42, + }) + + -- Rainforest + + minetest.register_biome({ + name = "rainforest", + node_top = "default:dirt_with_rainforest_litter", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 31000, + y_min = 1, + heat_point = 86, + humidity_point = 65, + }) + + minetest.register_biome({ + name = "rainforest_swamp", + node_top = "default:dirt", + depth_top = 1, + node_filler = "default:dirt", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = 0, + y_min = -1, + heat_point = 86, + humidity_point = 65, + }) + + minetest.register_biome({ + name = "rainforest_ocean", + node_top = "default:sand", + depth_top = 1, + node_filler = "default:sand", + depth_filler = 3, + node_riverbed = "default:sand", + depth_riverbed = 2, + node_cave_liquid = "default:water_source", + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + vertical_blend = 1, + y_max = -2, + y_min = -255, + heat_point = 86, + humidity_point = 65, + }) + + minetest.register_biome({ + name = "rainforest_under", + node_cave_liquid = {"default:water_source", "default:lava_source"}, + node_dungeon = "default:cobble", + node_dungeon_alt = "default:mossycobble", + node_dungeon_stair = "stairs:stair_cobble", + y_max = -256, + y_min = -31000, + heat_point = 86, + humidity_point = 65, + }) +end + + +-- +-- Register decorations +-- + +-- Mgv6 + +function default.register_mgv6_decorations() + + -- Papyrus + + minetest.register_decoration({ + name = "default:papyrus", + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = -0.3, + scale = 0.7, + spread = {x = 100, y = 100, z = 100}, + seed = 354, + octaves = 3, + persist = 0.7 + }, + y_max = 1, + y_min = 1, + decoration = "default:papyrus", + height = 2, + height_max = 4, + spawn_by = "default:water_source", + num_spawn_by = 1, + }) + + -- Cacti + + minetest.register_decoration({ + name = "default:cactus", + deco_type = "simple", + place_on = {"default:desert_sand"}, + sidelen = 16, + noise_params = { + offset = -0.012, + scale = 0.024, + spread = {x = 100, y = 100, z = 100}, + seed = 230, + octaves = 3, + persist = 0.6 + }, + y_max = 30, + y_min = 1, + decoration = "default:cactus", + height = 3, + height_max = 4, + }) + + -- Long grasses + + for length = 1, 5 do + minetest.register_decoration({ + name = "default:grass_"..length, + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.007, + spread = {x = 100, y = 100, z = 100}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + y_max = 30, + y_min = 1, + decoration = "default:grass_"..length, + }) + end + + -- Dry shrubs + + minetest.register_decoration({ + name = "default:dry_shrub", + deco_type = "simple", + place_on = {"default:desert_sand", "default:dirt_with_snow"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.035, + spread = {x = 100, y = 100, z = 100}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + y_max = 30, + y_min = 1, + decoration = "default:dry_shrub", + param2 = 4, + }) +end + + +-- All mapgens except mgv6 + +local function register_grass_decoration(offset, scale, length) + minetest.register_decoration({ + name = "default:grass_" .. length, + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = offset, + scale = scale, + spread = {x = 200, y = 200, z = 200}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + biomes = {"grassland", "deciduous_forest"}, + y_max = 31000, + y_min = 1, + decoration = "default:grass_" .. length, + }) +end + +local function register_dry_grass_decoration(offset, scale, length) + minetest.register_decoration({ + name = "default:dry_grass_" .. length, + deco_type = "simple", + place_on = {"default:dry_dirt_with_dry_grass"}, + sidelen = 16, + noise_params = { + offset = offset, + scale = scale, + spread = {x = 200, y = 200, z = 200}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + biomes = {"savanna"}, + y_max = 31000, + y_min = 1, + decoration = "default:dry_grass_" .. length, + }) +end + +local function register_fern_decoration(seed, length) + minetest.register_decoration({ + name = "default:fern_" .. length, + deco_type = "simple", + place_on = {"default:dirt_with_coniferous_litter"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.2, + spread = {x = 100, y = 100, z = 100}, + seed = seed, + octaves = 3, + persist = 0.7 + }, + biomes = {"coniferous_forest"}, + y_max = 31000, + y_min = 6, + decoration = "default:fern_" .. length, + }) +end + + +function default.register_decorations() + -- Savanna bare dirt patches. + -- Must come before all savanna decorations that are placed on dry grass. + -- Noise is similar to long dry grass noise, but scale inverted, to appear + -- where long dry grass is least dense and shortest. + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dry_dirt_with_dry_grass"}, + sidelen = 4, + noise_params = { + offset = -1.5, + scale = -1.5, + spread = {x = 200, y = 200, z = 200}, + seed = 329, + octaves = 4, + persist = 1.0 + }, + biomes = {"savanna"}, + y_max = 31000, + y_min = 1, + decoration = "default:dry_dirt", + place_offset_y = -1, + flags = "force_placement", + }) + + -- Apple tree and log + + minetest.register_decoration({ + name = "default:apple_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0.024, + scale = 0.015, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/apple_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + minetest.register_decoration({ + name = "default:apple_log", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + place_offset_y = 1, + sidelen = 16, + noise_params = { + offset = 0.0012, + scale = 0.0007, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/apple_log.mts", + flags = "place_center_x", + rotation = "random", + spawn_by = "default:dirt_with_grass", + num_spawn_by = 8, + }) + + -- Emergent jungle tree + -- Due to 32 node height, altitude is limited and prescence depends on chunksize + + local chunksize = tonumber(minetest.get_mapgen_setting("chunksize")) + if chunksize >= 5 then + minetest.register_decoration({ + name = "default:emergent_jungle_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_rainforest_litter"}, + sidelen = 80, + noise_params = { + offset = 0.0, + scale = 0.0025, + spread = {x = 250, y = 250, z = 250}, + seed = 2685, + octaves = 3, + persist = 0.7 + }, + biomes = {"rainforest"}, + y_max = 32, + y_min = 1, + schematic = minetest.get_modpath("default") .. + "/schematics/emergent_jungle_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + place_offset_y = -4, + }) + end + + -- Jungle tree and log + + minetest.register_decoration({ + name = "default:jungle_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_rainforest_litter"}, + sidelen = 80, + fill_ratio = 0.1, + biomes = {"rainforest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/jungle_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + -- Swamp jungle trees + + minetest.register_decoration({ + name = "default:jungle_tree(swamp)", + deco_type = "schematic", + place_on = {"default:dirt"}, + sidelen = 16, + -- Noise tuned to place swamp trees where papyrus is absent + noise_params = { + offset = 0.0, + scale = -0.1, + spread = {x = 200, y = 200, z = 200}, + seed = 354, + octaves = 1, + persist = 0.5 + }, + biomes = {"rainforest_swamp"}, + y_max = 0, + y_min = -1, + schematic = minetest.get_modpath("default") .. "/schematics/jungle_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + minetest.register_decoration({ + name = "default:jungle_log", + deco_type = "schematic", + place_on = {"default:dirt_with_rainforest_litter"}, + place_offset_y = 1, + sidelen = 80, + fill_ratio = 0.005, + biomes = {"rainforest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/jungle_log.mts", + flags = "place_center_x", + rotation = "random", + spawn_by = "default:dirt_with_rainforest_litter", + num_spawn_by = 8, + }) + + -- Taiga and temperate coniferous forest pine tree, small pine tree and log + + minetest.register_decoration({ + name = "default:pine_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_snow", "default:dirt_with_coniferous_litter"}, + sidelen = 16, + noise_params = { + offset = 0.010, + scale = 0.048, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"taiga", "coniferous_forest"}, + y_max = 31000, + y_min = 4, + schematic = minetest.get_modpath("default") .. "/schematics/pine_tree.mts", + flags = "place_center_x, place_center_z", + }) + + minetest.register_decoration({ + name = "default:small_pine_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_snow", "default:dirt_with_coniferous_litter"}, + sidelen = 16, + noise_params = { + offset = 0.010, + scale = -0.048, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"taiga", "coniferous_forest"}, + y_max = 31000, + y_min = 4, + schematic = minetest.get_modpath("default") .. "/schematics/small_pine_tree.mts", + flags = "place_center_x, place_center_z", + }) + + minetest.register_decoration({ + name = "default:pine_log", + deco_type = "schematic", + place_on = {"default:dirt_with_snow", "default:dirt_with_coniferous_litter"}, + place_offset_y = 1, + sidelen = 80, + fill_ratio = 0.0018, + biomes = {"taiga", "coniferous_forest"}, + y_max = 31000, + y_min = 4, + schematic = minetest.get_modpath("default") .. "/schematics/pine_log.mts", + flags = "place_center_x", + rotation = "random", + spawn_by = {"default:dirt_with_snow", "default:dirt_with_coniferous_litter"}, + num_spawn_by = 8, + }) + + -- Acacia tree and log + + minetest.register_decoration({ + name = "default:acacia_tree", + deco_type = "schematic", + place_on = {"default:dry_dirt_with_dry_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.002, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"savanna"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/acacia_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + minetest.register_decoration({ + name = "default:acacia_log", + deco_type = "schematic", + place_on = {"default:dry_dirt_with_dry_grass"}, + place_offset_y = 1, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"savanna"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/acacia_log.mts", + flags = "place_center_x", + rotation = "random", + spawn_by = "default:dry_dirt_with_dry_grass", + num_spawn_by = 8, + }) + + -- Aspen tree and log + + minetest.register_decoration({ + name = "default:aspen_tree", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0.0, + scale = -0.015, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/aspen_tree.mts", + flags = "place_center_x, place_center_z", + }) + + minetest.register_decoration({ + name = "default:aspen_log", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + place_offset_y = 1, + sidelen = 16, + noise_params = { + offset = 0.0, + scale = -0.0008, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/aspen_log.mts", + flags = "place_center_x", + rotation = "random", + spawn_by = "default:dirt_with_grass", + num_spawn_by = 8, + }) + + -- Large cactus + + minetest.register_decoration({ + name = "default:large_cactus", + deco_type = "schematic", + place_on = {"default:desert_sand"}, + sidelen = 16, + noise_params = { + offset = -0.0003, + scale = 0.0009, + spread = {x = 200, y = 200, z = 200}, + seed = 230, + octaves = 3, + persist = 0.6 + }, + biomes = {"desert"}, + y_max = 31000, + y_min = 4, + schematic = minetest.get_modpath("default") .. "/schematics/large_cactus.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + -- Cactus + + minetest.register_decoration({ + name = "default:cactus", + deco_type = "simple", + place_on = {"default:desert_sand"}, + sidelen = 16, + noise_params = { + offset = -0.0003, + scale = 0.0009, + spread = {x = 200, y = 200, z = 200}, + seed = 230, + octaves = 3, + persist = 0.6 + }, + biomes = {"desert"}, + y_max = 31000, + y_min = 4, + decoration = "default:cactus", + height = 2, + height_max = 5, + }) + + -- Papyrus + + -- Dirt version for rainforest swamp + + minetest.register_decoration({ + name = "default:papyrus_on_dirt", + deco_type = "schematic", + place_on = {"default:dirt"}, + sidelen = 16, + noise_params = { + offset = -0.3, + scale = 0.7, + spread = {x = 200, y = 200, z = 200}, + seed = 354, + octaves = 3, + persist = 0.7 + }, + biomes = {"rainforest_swamp"}, + y_max = 0, + y_min = 0, + schematic = minetest.get_modpath("default") .. "/schematics/papyrus_on_dirt.mts", + }) + + -- Dry dirt version for savanna shore + + minetest.register_decoration({ + name = "default:papyrus_on_dry_dirt", + deco_type = "schematic", + place_on = {"default:dry_dirt"}, + sidelen = 16, + noise_params = { + offset = -0.3, + scale = 0.7, + spread = {x = 200, y = 200, z = 200}, + seed = 354, + octaves = 3, + persist = 0.7 + }, + biomes = {"savanna_shore"}, + y_max = 0, + y_min = 0, + schematic = minetest.get_modpath("default") .. + "/schematics/papyrus_on_dry_dirt.mts", + }) + + -- Bush + + minetest.register_decoration({ + name = "default:bush", + deco_type = "schematic", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = -0.004, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 137, + octaves = 3, + persist = 0.7, + }, + biomes = {"grassland", "deciduous_forest"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/bush.mts", + flags = "place_center_x, place_center_z", + }) + + -- Blueberry bush + + minetest.register_decoration({ + name = "default:blueberry_bush", + deco_type = "schematic", + place_on = {"default:dirt_with_grass", "default:dirt_with_snow"}, + sidelen = 16, + noise_params = { + offset = -0.004, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 697, + octaves = 3, + persist = 0.7, + }, + biomes = {"grassland", "snowy_grassland"}, + y_max = 31000, + y_min = 1, + place_offset_y = 1, + schematic = minetest.get_modpath("default") .. "/schematics/blueberry_bush.mts", + flags = "place_center_x, place_center_z", + }) + + -- Acacia bush + + minetest.register_decoration({ + name = "default:acacia_bush", + deco_type = "schematic", + place_on = {"default:dry_dirt_with_dry_grass"}, + sidelen = 16, + noise_params = { + offset = -0.004, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 90155, + octaves = 3, + persist = 0.7, + }, + biomes = {"savanna"}, + y_max = 31000, + y_min = 1, + schematic = minetest.get_modpath("default") .. "/schematics/acacia_bush.mts", + flags = "place_center_x, place_center_z", + }) + + -- Pine bush + + minetest.register_decoration({ + name = "default:pine_bush", + deco_type = "schematic", + place_on = {"default:dirt_with_snow"}, + sidelen = 16, + noise_params = { + offset = -0.004, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 137, + octaves = 3, + persist = 0.7, + }, + biomes = {"taiga", "snowy_grassland"}, + y_max = 31000, + y_min = 4, + schematic = minetest.get_modpath("default") .. "/schematics/pine_bush.mts", + flags = "place_center_x, place_center_z", + }) + + -- Grasses + + register_grass_decoration(-0.03, 0.09, 5) + register_grass_decoration(-0.015, 0.075, 4) + register_grass_decoration(0, 0.06, 3) + register_grass_decoration(0.015, 0.045, 2) + register_grass_decoration(0.03, 0.03, 1) + + -- Dry grasses + + register_dry_grass_decoration(0.01, 0.05, 5) + register_dry_grass_decoration(0.03, 0.03, 4) + register_dry_grass_decoration(0.05, 0.01, 3) + register_dry_grass_decoration(0.07, -0.01, 2) + register_dry_grass_decoration(0.09, -0.03, 1) + + -- Ferns + + register_fern_decoration(14936, 3) + register_fern_decoration(801, 2) + register_fern_decoration(5, 1) + + -- Junglegrass + + minetest.register_decoration({ + name = "default:junglegrass", + deco_type = "simple", + place_on = {"default:dirt_with_rainforest_litter"}, + sidelen = 80, + fill_ratio = 0.1, + biomes = {"rainforest"}, + y_max = 31000, + y_min = 1, + decoration = "default:junglegrass", + }) + + -- Dry shrub + + minetest.register_decoration({ + name = "default:dry_shrub", + deco_type = "simple", + place_on = {"default:desert_sand", + "default:sand", "default:silver_sand"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.02, + spread = {x = 200, y = 200, z = 200}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + biomes = {"desert", "sandstone_desert", "cold_desert"}, + y_max = 31000, + y_min = 2, + decoration = "default:dry_shrub", + param2 = 4, + }) + + -- Marram grass + + minetest.register_decoration({ + name = "default:marram_grass", + deco_type = "simple", + place_on = {"default:sand"}, + sidelen = 4, + noise_params = { + offset = -0.7, + scale = 4.0, + spread = {x = 16, y = 16, z = 16}, + seed = 513337, + octaves = 1, + persist = 0.0, + flags = "absvalue, eased" + }, + biomes = {"coniferous_forest_dunes", "grassland_dunes"}, + y_max = 6, + y_min = 4, + decoration = { + "default:marram_grass_1", + "default:marram_grass_2", + "default:marram_grass_3", + }, + }) + + -- Tundra moss + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:permafrost_with_stones"}, + sidelen = 4, + noise_params = { + offset = -0.8, + scale = 2.0, + spread = {x = 100, y = 100, z = 100}, + seed = 53995, + octaves = 3, + persist = 1.0 + }, + biomes = {"tundra"}, + y_max = 50, + y_min = 2, + decoration = "default:permafrost_with_moss", + place_offset_y = -1, + flags = "force_placement", + }) + + -- Tundra patchy snow + + minetest.register_decoration({ + deco_type = "simple", + place_on = { + "default:permafrost_with_moss", + "default:permafrost_with_stones", + "default:stone", + "default:gravel" + }, + sidelen = 4, + noise_params = { + offset = 0, + scale = 1.0, + spread = {x = 100, y = 100, z = 100}, + seed = 172555, + octaves = 3, + persist = 1.0 + }, + biomes = {"tundra", "tundra_beach"}, + y_max = 50, + y_min = 1, + decoration = "default:snow", + }) + + -- Coral reef + + minetest.register_decoration({ + name = "default:corals", + deco_type = "simple", + place_on = {"default:sand"}, + place_offset_y = -1, + sidelen = 4, + noise_params = { + offset = -4, + scale = 4, + spread = {x = 50, y = 50, z = 50}, + seed = 7013, + octaves = 3, + persist = 0.7, + }, + biomes = { + "desert_ocean", + "savanna_ocean", + "rainforest_ocean", + }, + y_max = -2, + y_min = -8, + flags = "force_placement", + decoration = { + "default:coral_green", "default:coral_pink", + "default:coral_cyan", "default:coral_brown", + "default:coral_orange", "default:coral_skeleton", + }, + }) + + -- Kelp + + minetest.register_decoration({ + name = "default:kelp", + deco_type = "simple", + place_on = {"default:sand"}, + place_offset_y = -1, + sidelen = 16, + noise_params = { + offset = -0.04, + scale = 0.1, + spread = {x = 200, y = 200, z = 200}, + seed = 87112, + octaves = 3, + persist = 0.7 + }, + biomes = { + "taiga_ocean", + "snowy_grassland_ocean", + "grassland_ocean", + "coniferous_forest_ocean", + "deciduous_forest_ocean", + "sandstone_desert_ocean", + "cold_desert_ocean"}, + y_max = -5, + y_min = -10, + flags = "force_placement", + decoration = "default:sand_with_kelp", + param2 = 48, + param2_max = 96, + }) +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_ores() + default.register_mgv6_decorations() +else + default.register_biomes() + default.register_ores() + default.register_decorations() +end diff --git a/mods/default/mod.conf b/mods/default/mod.conf new file mode 100644 index 0000000..c9e7468 --- /dev/null +++ b/mods/default/mod.conf @@ -0,0 +1,3 @@ +name = default +description = Minetest Game mod: default +optional_depends = player_api diff --git a/mods/default/models/chest_open.obj b/mods/default/models/chest_open.obj new file mode 100644 index 0000000..72ba175 --- /dev/null +++ b/mods/default/models/chest_open.obj @@ -0,0 +1,79 @@ +# Blender v2.78 (sub 0) OBJ File: 'chest-open.blend' +# www.blender.org +o Top_Cube.002_None_Top_Cube.002_None_bottom +v -0.500000 0.408471 0.720970 +v -0.500000 1.115578 0.013863 +v -0.500000 0.894607 -0.207108 +v -0.500000 0.187501 0.499999 +v 0.500000 1.115578 0.013863 +v 0.500000 0.408471 0.720970 +v 0.500000 0.187501 0.499999 +v 0.500000 0.894607 -0.207108 +v -0.500000 0.187500 -0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 0.187500 -0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +vt 0.0000 1.0000 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.0000 +vt 0.0000 1.0000 +vt 1.0000 1.0000 +vt 1.0000 0.6875 +vt 0.0000 0.6875 +vt 1.0000 1.0000 +vt 0.0000 0.6875 +vt 1.0000 0.6875 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 0.0000 0.0000 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 1.0000 1.0000 +vt 1.0000 0.6875 +vt 1.0000 0.0000 +vt 0.0000 1.0000 +vt 0.0000 0.6875 +vt 0.0000 0.6875 +vt 0.0000 0.0000 +vt 1.0000 0.5000 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.5000 +vt 0.0000 0.0000 +vt 1.0000 0.0000 +vn 0.0000 0.7071 0.7071 +vn -0.0000 -1.0000 -0.0000 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 -0.0000 +vn 0.0000 -0.7071 0.7071 +vn 0.0000 0.0000 1.0000 +vn -0.0000 0.7071 -0.7071 +vn -0.0000 0.0000 -1.0000 +vn -0.0000 -0.7071 -0.7071 +vn -0.0000 1.0000 -0.0000 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Top +s off +f 6/1/1 5/2/1 2/3/1 1/4/1 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Bottom +f 11/5/2 10/6/2 14/7/2 13/8/2 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Right-Left +f 1/9/3 2/10/3 3/11/3 4/12/3 +f 5/13/4 6/1/4 7/14/4 8/15/4 +f 4/12/3 9/16/3 10/17/3 11/18/3 +f 12/19/4 7/14/4 13/8/4 14/20/4 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Back +f 6/21/5 1/9/5 4/12/5 7/22/5 +f 7/22/6 4/12/6 11/18/6 13/23/6 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Front +f 2/10/7 5/24/7 8/25/7 3/11/7 +f 9/16/8 12/26/8 14/27/8 10/17/8 +g Top_Cube.002_None_Top_Cube.002_None_bottom_Top_Cube.002_None_Top_Cube.002_None_bottom_Inside +f 4/28/9 3/29/9 8/30/9 7/31/9 +f 7/31/10 12/32/10 9/33/10 4/28/10 diff --git a/mods/default/models/torch_ceiling.obj b/mods/default/models/torch_ceiling.obj new file mode 100644 index 0000000..ea51f3c --- /dev/null +++ b/mods/default/models/torch_ceiling.obj @@ -0,0 +1,58 @@ +# Blender v2.77 (sub 0) OBJ File: 'torch_ceiling.blend' +# www.blender.org +mtllib torch_ceiling.mtl +o Cube_Cube.001 +v -0.062469 -0.047331 0.068152 +v -0.062469 -0.559515 -0.164388 +v -0.062469 0.004344 -0.045667 +v -0.062469 -0.507839 -0.278206 +v 0.062531 -0.047331 0.068152 +v 0.062531 -0.559515 -0.164388 +v 0.062531 0.004344 -0.045667 +v 0.062531 -0.507839 -0.278206 +v 0.353584 0.040000 0.363553 +v 0.353584 -0.397500 0.363553 +v -0.353522 0.040000 -0.343553 +v -0.353522 -0.397500 -0.343553 +v 0.353584 0.040000 -0.343553 +v -0.353522 0.040000 0.363553 +v 0.353584 -0.397500 -0.343553 +v -0.353522 -0.397500 0.363553 +vt 0.5625 0.5000 +vt 0.5625 0.6250 +vt 0.4375 0.6250 +vt 0.4375 0.5000 +vt 0.4375 0.0000 +vt 0.5625 0.0000 +vt 0.5625 0.1250 +vt 0.4375 0.1250 +vt 0.5625 0.6250 +vt 0.4375 0.6250 +vt 0.4375 0.6250 +vt 0.4375 0.0000 +vt 0.5625 0.6250 +vt 0.5625 0.0000 +vt 1.0000 0.5625 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.5625 +vt 0.0000 0.5625 +vt 1.0000 0.5625 +vt 1.0000 1.0000 +vt 0.0000 1.0000 +vn 0.0000 0.9105 0.4134 +vn -0.0000 -0.4134 0.9105 +vn -1.0000 0.0000 0.0000 +vn 0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 0.7071 +usemtl Material.001 +s off +f 3/1/1 1/2/1 5/3/1 7/4/1 +f 8/5/1 4/6/1 2/7/1 6/8/1 +f 3/9/2 4/6/2 8/5/2 7/10/2 +f 1/11/3 3/9/3 4/6/3 2/12/3 +f 5/13/2 1/11/2 2/12/2 6/14/2 +f 7/10/3 8/5/3 6/14/3 5/13/3 +usemtl Material.002 +f 9/15/4 10/16/4 12/17/4 11/18/4 +f 13/19/5 14/20/5 16/21/5 15/22/5 diff --git a/mods/default/models/torch_floor.obj b/mods/default/models/torch_floor.obj new file mode 100644 index 0000000..e2487ef --- /dev/null +++ b/mods/default/models/torch_floor.obj @@ -0,0 +1,50 @@ +# Blender v2.76 (sub 11) OBJ File: 'torch_floor.blend' +# www.blender.org +mtllib torch_floor.mtl +o Cube_Cube.001 +v 0.062500 0.062500 -0.062500 +v 0.062500 -0.500000 -0.062500 +v 0.062500 0.062500 0.062500 +v 0.062500 -0.500000 0.062500 +v -0.062500 0.062500 -0.062500 +v -0.062500 -0.500000 -0.062500 +v -0.062500 0.062500 0.062500 +v -0.062500 -0.500000 0.062500 +v -0.353553 -0.500000 0.353553 +v -0.353553 0.500000 0.353553 +v 0.353553 -0.500000 -0.353553 +v 0.353553 0.500000 -0.353553 +v -0.353553 -0.500000 -0.353553 +v 0.353553 -0.500000 0.353553 +v -0.353553 0.500000 -0.353553 +v 0.353553 0.500000 0.353553 +vt 0.562500 0.500000 +vt 0.562500 0.625000 +vt 0.437500 0.625000 +vt 0.437500 0.500000 +vt 0.437500 0.000000 +vt 0.562500 0.000000 +vt 0.562500 0.125000 +vt 0.437500 0.125000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 1.000000 0.000000 0.000000 +vn -0.707100 0.000000 -0.707100 +vn -0.707100 -0.000000 0.707100 +g Cube_Cube.001_Cube_Cube.001_Material.001 +usemtl Material.001 +s off +f 3/1/1 1/2/1 5/3/1 7/4/1 +f 8/5/1 4/6/1 2/7/1 6/8/1 +f 3/2/2 4/6/2 8/5/2 7/3/2 +f 1/3/3 3/2/3 4/6/3 2/5/3 +f 5/2/2 1/3/2 2/5/2 6/6/2 +f 7/3/3 8/5/3 6/6/3 5/2/3 +g Cube_Cube.001_Cube_Cube.001_Material.002 +usemtl Material.002 +f 9/9/4 10/10/4 12/11/4 11/12/4 +f 13/12/5 14/9/5 16/10/5 15/11/5 diff --git a/mods/default/models/torch_wall.obj b/mods/default/models/torch_wall.obj new file mode 100644 index 0000000..57baa9e --- /dev/null +++ b/mods/default/models/torch_wall.obj @@ -0,0 +1,64 @@ +# Blender v2.76 (sub 11) OBJ File: 'torch_wall.blend' +# www.blender.org +mtllib torch_wall.mtl +o Cube_Cube.001 +v 0.062469 -0.195248 0.023570 +v 0.062469 -0.476498 -0.463570 +v 0.062469 -0.303502 0.086070 +v 0.062469 -0.584752 -0.401070 +v -0.062531 -0.195248 0.023570 +v -0.062531 -0.476498 -0.463570 +v -0.062531 -0.303502 0.086070 +v -0.062531 -0.584752 -0.401070 +v -0.353584 -0.613553 0.022500 +v -0.353584 -0.613553 0.460000 +v 0.353522 0.093553 0.022500 +v 0.353522 0.093553 0.460000 +v -0.353584 0.093553 0.022500 +v 0.353522 -0.613553 0.022500 +v -0.353584 0.093553 0.460000 +v 0.353522 -0.613553 0.460000 +v 0.353553 0.056811 -0.121957 +v 0.353553 -0.224439 -0.609096 +v -0.353553 -0.555561 0.231596 +v -0.353553 -0.836811 -0.255543 +v -0.353553 0.056811 -0.121957 +v -0.353553 -0.224439 -0.609096 +v 0.353553 -0.555561 0.231596 +v 0.353553 -0.836811 -0.255543 +vt 0.562500 0.500000 +vt 0.562500 0.625000 +vt 0.437500 0.625000 +vt 0.437500 0.500000 +vt 0.437500 0.000000 +vt 0.562500 0.000000 +vt 0.562500 0.125000 +vt 0.437500 0.125000 +vt 0.000000 0.562500 +vt 0.000000 -0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.562500 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn -0.000000 0.500000 0.866000 +vn -0.000000 0.866000 -0.500000 +vn 1.000000 0.000000 0.000000 +vn -0.707100 0.612400 -0.353600 +vn -0.707100 -0.612400 0.353600 +vn -0.707100 0.707100 -0.000000 +vn -0.707100 -0.707100 -0.000000 +g Cube_Cube.001_Cube_Cube.001_Material.001 +usemtl Material.001 +s off +f 3/1/1 1/2/1 5/3/1 7/4/1 +f 8/5/1 4/6/1 2/7/1 6/8/1 +f 3/2/2 4/6/2 8/5/2 7/3/2 +f 1/3/3 3/2/3 4/6/3 2/5/3 +f 5/2/2 1/3/2 2/5/2 6/6/2 +f 7/3/3 8/5/3 6/6/3 5/2/3 +f 17/9/4 18/10/4 20/11/4 19/12/4 +f 21/9/5 22/10/5 24/11/5 23/12/5 +g Cube_Cube.001_Cube_Cube.001_Material.002 +usemtl Material.002 +f 9/12/6 10/13/6 12/14/6 11/9/6 +f 13/9/7 14/12/7 16/13/7 15/14/7 diff --git a/mods/default/nodes.lua b/mods/default/nodes.lua new file mode 100644 index 0000000..aa7d482 --- /dev/null +++ b/mods/default/nodes.lua @@ -0,0 +1,2936 @@ +-- mods/default/nodes.lua + +-- support for MT game translation. +local S = default.get_translator + +--[[ Node name convention: + +Although many node names are in combined-word form, the required form for new +node names is words separated by underscores. If both forms are used in written +language (for example pinewood and pine wood) the underscore form should be used. + +--]] + + +--[[ Index: + +Stone +----- +(1. Material 2. Cobble variant 3. Brick variant 4. Modified forms) + +default:stone +default:cobble +default:stonebrick +default:stone_block +default:mossycobble + +default:desert_stone +default:desert_cobble +default:desert_stonebrick +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 +default:obsidian_block + +Soft / Non-Stone +---------------- +(1. Material 2. Modified forms) + +default:dirt +default:dirt_with_grass +default:dirt_with_grass_footsteps +default:dirt_with_dry_grass +default:dirt_with_snow +default:dirt_with_rainforest_litter +default:dirt_with_coniferous_litter +default:dry_dirt +default:dry_dirt_with_dry_grass + +default:permafrost +default:permafrost_with_stones +default:permafrost_with_moss + +default:sand +default:desert_sand +default:silver_sand + +default:gravel + +default:clay + +default:snow +default:snowblock +default:ice +default:cave_ice + +Trees +----- +(1. Trunk 2. Fabricated trunk 3. Leaves 4. Sapling 5. Fruits) + +default:tree +default:wood +default:leaves +default:sapling +default:apple + +default:jungletree +default:junglewood +default:jungleleaves +default:junglesapling +default:emergent_jungle_sapling + +default:pine_tree +default:pine_wood +default:pine_needles +default:pine_sapling + +default:acacia_tree +default:acacia_wood +default:acacia_leaves +default:acacia_sapling + +default:aspen_tree +default:aspen_wood +default:aspen_leaves +default:aspen_sapling + +Ores +---- +(1. In stone 2. Blocks) + +default:stone_with_coal +default:coalblock + +default:stone_with_iron +default:steelblock + +default:stone_with_copper +default:copperblock + +default:stone_with_tin +default:tinblock + +default:bronzeblock + +default:stone_with_gold +default:goldblock + +default:stone_with_mese +default:mese + +default:stone_with_diamond +default:diamondblock + +Plantlife +--------- + +default:cactus +default:large_cactus_seedling + +default:papyrus +default:dry_shrub +default:junglegrass + +default:grass_1 +default:grass_2 +default:grass_3 +default:grass_4 +default:grass_5 + +default:dry_grass_1 +default:dry_grass_2 +default:dry_grass_3 +default:dry_grass_4 +default:dry_grass_5 + +default:fern_1 +default:fern_2 +default:fern_3 + +default:marram_grass_1 +default:marram_grass_2 +default:marram_grass_3 + +default:bush_stem +default:bush_leaves +default:bush_sapling +default:acacia_bush_stem +default:acacia_bush_leaves +default:acacia_bush_sapling +default:pine_bush_stem +default:pine_bush_needles +default:pine_bush_sapling +default:blueberry_bush_leaves_with_berries +default:blueberry_bush_leaves +default:blueberry_bush_sapling + +default:sand_with_kelp + +Corals +------ + +default:coral_brown +default:coral_orange +default:coral_skeleton + +Liquids +------- +(1. Source 2. Flowing) + +default:water_source +default:water_flowing + +default:river_water_source +default:river_water_flowing + +default:lava_source +default:lava_flowing + +Tools / "Advanced" crafting / Non-"natural" +------------------------------------------- + +default:bookshelf + +default:sign_wall_wood +default:sign_wall_steel + +default:ladder_wood +default:ladder_steel + +default:fence_wood +default:fence_acacia_wood +default:fence_junglewood +default:fence_pine_wood +default:fence_aspen_wood + +default:glass +default:obsidian_glass + +default:brick + +default:meselamp +default:mese_post_light + +Misc +---- + +default:cloud + +--]] + +-- Required wrapper to allow customization of default.after_place_leaves +local function after_place_leaves(...) + return default.after_place_leaves(...) +end + +-- Required wrapper to allow customization of default.grow_sapling +local function grow_sapling(...) + return default.grow_sapling(...) +end + +-- +-- Stone +-- + +minetest.register_node("default:stone", { + description = S("Stone"), + tiles = {"default_stone.png"}, + groups = {cracky = 3, stone = 1}, + drop = "default:cobble", + legacy_mineral = true, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:cobble", { + description = S("Cobblestone"), + tiles = {"default_cobble.png"}, + is_ground_content = false, + groups = {cracky = 3, stone = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:stonebrick", { + description = S("Stone Brick"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_stone_brick.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:stone_block", { + description = S("Stone Block"), + tiles = {"default_stone_block.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:mossycobble", { + description = S("Mossy Cobblestone"), + tiles = {"default_mossycobble.png"}, + is_ground_content = false, + groups = {cracky = 3, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + + +minetest.register_node("default:desert_stone", { + description = S("Desert Stone"), + tiles = {"default_desert_stone.png"}, + groups = {cracky = 3, stone = 1}, + drop = "default:desert_cobble", + legacy_mineral = true, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:desert_cobble", { + description = S("Desert Cobblestone"), + tiles = {"default_desert_cobble.png"}, + is_ground_content = false, + groups = {cracky = 3, stone = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:desert_stonebrick", { + description = S("Desert Stone Brick"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_desert_stone_brick.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:desert_stone_block", { + description = S("Desert Stone Block"), + tiles = {"default_desert_stone_block.png"}, + is_ground_content = false, + groups = {cracky = 2, stone = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:sandstone", { + description = S("Sandstone"), + tiles = {"default_sandstone.png"}, + groups = {crumbly = 1, cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:sandstonebrick", { + description = S("Sandstone Brick"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_sandstone_brick.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:sandstone_block", { + description = S("Sandstone Block"), + tiles = {"default_sandstone_block.png"}, + is_ground_content = false, + groups = {cracky = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:desert_sandstone", { + description = S("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 = S("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 = S("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 = S("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 = S("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 = S("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 = S("Obsidian"), + tiles = {"default_obsidian.png"}, + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 1, level = 2}, +}) + +minetest.register_node("default:obsidianbrick", { + description = S("Obsidian Brick"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_obsidian_brick.png"}, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 1, level = 2}, +}) + +minetest.register_node("default:obsidian_block", { + description = S("Obsidian Block"), + tiles = {"default_obsidian_block.png"}, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 1, level = 2}, +}) + +-- +-- Soft / Non-Stone +-- + +minetest.register_node("default:dirt", { + description = S("Dirt"), + tiles = {"default_dirt.png"}, + groups = {crumbly = 3, soil = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_node("default:dirt_with_grass", { + description = S("Dirt with Grass"), + tiles = {"default_grass.png", "default_dirt.png", + {name = "default_dirt.png^default_grass_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.25}, + }), +}) + +minetest.register_node("default:dirt_with_grass_footsteps", { + description = S("Dirt with Grass and Footsteps"), + tiles = {"default_grass.png^default_footprint.png", "default_dirt.png", + {name = "default_dirt.png^default_grass_side.png", + tileable_vertical = false}}, + groups = {crumbly = 3, soil = 1, not_in_creative_inventory = 1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name = "default_grass_footstep", gain = 0.25}, + }), +}) + +minetest.register_node("default:dirt_with_dry_grass", { + description = S("Dirt with Savanna Grass"), + tiles = {"default_dry_grass.png", + "default_dirt.png", + {name = "default_dirt.png^default_dry_grass_side.png", + tileable_vertical = false}}, + groups = {crumbly = 3, soil = 1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name = "default_grass_footstep", gain = 0.4}, + }), +}) + +minetest.register_node("default:dirt_with_snow", { + description = S("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, snowy = 1}, + drop = "default:dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name = "default_snow_footstep", gain = 0.2}, + }), +}) + +minetest.register_node("default:dirt_with_rainforest_litter", { + description = S("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:dirt_with_coniferous_litter", { + description = S("Dirt with Coniferous Litter"), + tiles = { + "default_coniferous_litter.png", + "default_dirt.png", + {name = "default_dirt.png^default_coniferous_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:dry_dirt", { + description = S("Savanna Dirt"), + tiles = {"default_dry_dirt.png"}, + groups = {crumbly = 3, soil = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_node("default:dry_dirt_with_dry_grass", { + description = S("Savanna Dirt with Savanna Grass"), + tiles = {"default_dry_grass.png", "default_dry_dirt.png", + {name = "default_dry_dirt.png^default_dry_grass_side.png", + tileable_vertical = false}}, + groups = {crumbly = 3, soil = 1}, + drop = "default:dry_dirt", + sounds = default.node_sound_dirt_defaults({ + footstep = {name = "default_grass_footstep", gain = 0.4}, + }), +}) + +minetest.register_node("default:permafrost", { + description = S("Permafrost"), + tiles = {"default_permafrost.png"}, + groups = {cracky = 3}, + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_node("default:permafrost_with_stones", { + description = S("Permafrost with Stones"), + tiles = {"default_permafrost.png^default_stones.png", + "default_permafrost.png", + "default_permafrost.png^default_stones_side.png"}, + groups = {cracky = 3}, + sounds = default.node_sound_gravel_defaults(), +}) + +minetest.register_node("default:permafrost_with_moss", { + description = S("Permafrost with Moss"), + tiles = {"default_moss.png", "default_permafrost.png", + {name = "default_permafrost.png^default_moss_side.png", + tileable_vertical = false}}, + groups = {cracky = 3}, + sounds = default.node_sound_dirt_defaults({ + footstep = {name = "default_grass_footstep", gain = 0.25}, + }), +}) + +minetest.register_node("default:sand", { + description = S("Sand"), + tiles = {"default_sand.png"}, + groups = {crumbly = 3, falling_node = 1, sand = 1}, + sounds = default.node_sound_sand_defaults(), +}) + +minetest.register_node("default:desert_sand", { + description = S("Desert Sand"), + tiles = {"default_desert_sand.png"}, + groups = {crumbly = 3, falling_node = 1, sand = 1}, + sounds = default.node_sound_sand_defaults(), +}) + +minetest.register_node("default:silver_sand", { + description = S("Silver Sand"), + tiles = {"default_silver_sand.png"}, + groups = {crumbly = 3, falling_node = 1, sand = 1}, + sounds = default.node_sound_sand_defaults(), +}) + + +minetest.register_node("default:gravel", { + description = S("Gravel"), + tiles = {"default_gravel.png"}, + groups = {crumbly = 2, falling_node = 1}, + sounds = default.node_sound_gravel_defaults(), + drop = { + max_items = 1, + items = { + {items = {"default:flint"}, rarity = 16}, + {items = {"default:gravel"}} + } + } +}) + +minetest.register_node("default:clay", { + description = S("Clay"), + tiles = {"default_clay.png"}, + groups = {crumbly = 3}, + drop = "default:clay_lump 4", + sounds = default.node_sound_dirt_defaults(), +}) + + +minetest.register_node("default:snow", { + description = S("Snow"), + tiles = {"default_snow.png"}, + inventory_image = "default_snowball.png", + wield_image = "default_snowball.png", + paramtype = "light", + buildable_to = true, + floodable = true, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + }, + }, + collision_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -6 / 16, 0.5}, + }, + }, + groups = {crumbly = 3, falling_node = 1, snowy = 1}, + sounds = default.node_sound_snow_defaults(), + + on_construct = function(pos) + pos.y = pos.y - 1 + if minetest.get_node(pos).name == "default:dirt_with_grass" then + minetest.set_node(pos, {name = "default:dirt_with_snow"}) + end + end, +}) + +minetest.register_node("default:snowblock", { + description = S("Snow Block"), + tiles = {"default_snow.png"}, + groups = {crumbly = 3, cools_lava = 1, snowy = 1}, + sounds = default.node_sound_snow_defaults(), + + on_construct = function(pos) + pos.y = pos.y - 1 + if minetest.get_node(pos).name == "default:dirt_with_grass" then + minetest.set_node(pos, {name = "default:dirt_with_snow"}) + end + end, +}) + +-- 'is ground content = false' to avoid tunnels in sea ice or ice rivers +minetest.register_node("default:ice", { + description = S("Ice"), + tiles = {"default_ice.png"}, + is_ground_content = false, + paramtype = "light", + groups = {cracky = 3, cools_lava = 1, slippery = 3}, + sounds = default.node_sound_glass_defaults(), +}) + +-- Mapgen-placed ice with 'is ground content = true' to contain tunnels +minetest.register_node("default:cave_ice", { + description = S("Cave Ice"), + tiles = {"default_ice.png"}, + paramtype = "light", + groups = {cracky = 3, cools_lava = 1, slippery = 3, + not_in_creative_inventory = 1}, + drop = "default:ice", + sounds = default.node_sound_glass_defaults(), +}) + +-- +-- Trees +-- + +minetest.register_node("default:tree", { + description = S("Apple Tree"), + tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + + on_place = minetest.rotate_node +}) + +minetest.register_node("default:wood", { + description = S("Apple Wood Planks"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_wood.png"}, + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("default:sapling", { + description = S("Apple Tree Sapling"), + drawtype = "plantlike", + tiles = {"default_sapling.png"}, + inventory_image = "default_sapling.png", + wield_image = "default_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -3, y = 1, z = -3}, + {x = 3, y = 6, z = 3}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, +}) + +minetest.register_node("default:leaves", { + description = S("Apple Tree Leaves"), + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_leaves.png"}, + special_tiles = {"default_leaves_simple.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy = 3, leafdecay = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + { + -- player will get sapling with 1/20 chance + items = {"default:sapling"}, + rarity = 20, + }, + { + -- player will get leaves only if he get no saplings, + -- this is because max_items is 1 + items = {"default:leaves"}, + } + } + }, + sounds = default.node_sound_leaves_defaults(), + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:apple", { + description = S("Apple"), + drawtype = "plantlike", + tiles = {"default_apple.png"}, + inventory_image = "default_apple.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + is_ground_content = false, + selection_box = { + type = "fixed", + fixed = {-3 / 16, -7 / 16, -3 / 16, 3 / 16, 4 / 16, 3 / 16} + }, + groups = {fleshy = 3, dig_immediate = 3, flammable = 2, + leafdecay = 3, leafdecay_drop = 1, food_apple = 1}, + on_use = minetest.item_eat(2), + sounds = default.node_sound_leaves_defaults(), + + after_place_node = function(pos, placer, itemstack) + minetest.set_node(pos, {name = "default:apple", param2 = 1}) + end, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + if oldnode.param2 == 0 then + minetest.set_node(pos, {name = "default:apple_mark"}) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end + end, +}) + +minetest.register_node("default:apple_mark", { + description = S("Apple Marker"), + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + groups = {not_in_creative_inventory = 1}, + on_timer = function(pos, elapsed) + if not minetest.find_node_near(pos, 1, "default:leaves") then + minetest.remove_node(pos) + elseif minetest.get_node_light(pos) < 11 then + minetest.get_node_timer(pos):start(200) + else + minetest.set_node(pos, {name = "default:apple"}) + end + end +}) + + +minetest.register_node("default:jungletree", { + description = S("Jungle Tree"), + tiles = {"default_jungletree_top.png", "default_jungletree_top.png", + "default_jungletree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + + on_place = minetest.rotate_node +}) + +minetest.register_node("default:junglewood", { + description = S("Jungle Wood Planks"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_junglewood.png"}, + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("default:jungleleaves", { + description = S("Jungle Tree Leaves"), + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_jungleleaves.png"}, + special_tiles = {"default_jungleleaves_simple.png"}, + paramtype = "light", + is_ground_content = false, + groups = {snappy = 3, leafdecay = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + {items = {"default:junglesapling"}, rarity = 20}, + {items = {"default:jungleleaves"}} + } + }, + sounds = default.node_sound_leaves_defaults(), + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:junglesapling", { + description = S("Jungle Tree Sapling"), + drawtype = "plantlike", + tiles = {"default_junglesapling.png"}, + inventory_image = "default_junglesapling.png", + wield_image = "default_junglesapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:junglesapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 15, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, +}) + +minetest.register_node("default:emergent_jungle_sapling", { + description = S("Emergent Jungle Tree Sapling"), + drawtype = "plantlike", + tiles = {"default_emergent_jungle_sapling.png"}, + inventory_image = "default_emergent_jungle_sapling.png", + wield_image = "default_emergent_jungle_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:emergent_jungle_sapling", + -- minp, maxp to be checked, relative to sapling pos + {x = -3, y = -5, z = -3}, + {x = 3, y = 31, z = 3}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, +}) + + +minetest.register_node("default:pine_tree", { + description = S("Pine Tree"), + tiles = {"default_pine_tree_top.png", "default_pine_tree_top.png", + "default_pine_tree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree = 1, choppy = 3, oddly_breakable_by_hand = 1, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + + on_place = minetest.rotate_node +}) + +minetest.register_node("default:pine_wood", { + description = S("Pine Wood Planks"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_pine_wood.png"}, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("default:pine_needles",{ + description = S("Pine Needles"), + drawtype = "allfaces_optional", + tiles = {"default_pine_needles.png"}, + waving = 1, + paramtype = "light", + is_ground_content = false, + groups = {snappy = 3, leafdecay = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + {items = {"default:pine_sapling"}, rarity = 20}, + {items = {"default:pine_needles"}} + } + }, + sounds = default.node_sound_leaves_defaults(), + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:pine_sapling", { + description = S("Pine Tree Sapling"), + drawtype = "plantlike", + tiles = {"default_pine_sapling.png"}, + inventory_image = "default_pine_sapling.png", + wield_image = "default_pine_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 3, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:pine_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 14, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, +}) + + +minetest.register_node("default:acacia_tree", { + description = S("Acacia Tree"), + tiles = {"default_acacia_tree_top.png", "default_acacia_tree_top.png", + "default_acacia_tree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + + on_place = minetest.rotate_node +}) + +minetest.register_node("default:acacia_wood", { + description = S("Acacia Wood Planks"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_acacia_wood.png"}, + is_ground_content = false, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, wood = 1}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("default:acacia_leaves", { + description = S("Acacia Tree Leaves"), + drawtype = "allfaces_optional", + tiles = {"default_acacia_leaves.png"}, + special_tiles = {"default_acacia_leaves_simple.png"}, + waving = 1, + paramtype = "light", + is_ground_content = false, + groups = {snappy = 3, leafdecay = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + {items = {"default:acacia_sapling"}, rarity = 20}, + {items = {"default:acacia_leaves"}} + } + }, + sounds = default.node_sound_leaves_defaults(), + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:acacia_sapling", { + description = S("Acacia Tree Sapling"), + drawtype = "plantlike", + tiles = {"default_acacia_sapling.png"}, + inventory_image = "default_acacia_sapling.png", + wield_image = "default_acacia_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 7 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:acacia_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -4, y = 1, z = -4}, + {x = 4, y = 7, z = 4}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, +}) + +minetest.register_node("default:aspen_tree", { + description = S("Aspen Tree"), + tiles = {"default_aspen_tree_top.png", "default_aspen_tree_top.png", + "default_aspen_tree.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {tree = 1, choppy = 3, oddly_breakable_by_hand = 1, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + + on_place = minetest.rotate_node +}) + +minetest.register_node("default:aspen_wood", { + description = S("Aspen Wood Planks"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = {"default_aspen_wood.png"}, + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3, wood = 1}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("default:aspen_leaves", { + description = S("Aspen Tree Leaves"), + drawtype = "allfaces_optional", + tiles = {"default_aspen_leaves.png"}, + waving = 1, + paramtype = "light", + is_ground_content = false, + groups = {snappy = 3, leafdecay = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + {items = {"default:aspen_sapling"}, rarity = 20}, + {items = {"default:aspen_leaves"}} + } + }, + sounds = default.node_sound_leaves_defaults(), + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:aspen_sapling", { + description = S("Aspen Tree Sapling"), + drawtype = "plantlike", + tiles = {"default_aspen_sapling.png"}, + inventory_image = "default_aspen_sapling.png", + wield_image = "default_aspen_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-3 / 16, -0.5, -3 / 16, 3 / 16, 0.5, 3 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 3, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:aspen_sapling", + -- minp, maxp to be checked, relative to sapling pos + -- minp_relative.y = 1 because sapling pos has been checked + {x = -2, y = 1, z = -2}, + {x = 2, y = 12, z = 2}, + -- maximum interval of interior volume check + 4) + + return itemstack + end, +}) + +-- +-- Ores +-- + +minetest.register_node("default:stone_with_coal", { + description = S("Coal Ore"), + tiles = {"default_stone.png^default_mineral_coal.png"}, + groups = {cracky = 3}, + drop = "default:coal_lump", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:coalblock", { + description = S("Coal Block"), + tiles = {"default_coal_block.png"}, + is_ground_content = false, + groups = {cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + + +minetest.register_node("default:stone_with_iron", { + description = S("Iron Ore"), + tiles = {"default_stone.png^default_mineral_iron.png"}, + groups = {cracky = 2}, + drop = "default:iron_lump", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:steelblock", { + description = S("Steel Block"), + tiles = {"default_steel_block.png"}, + is_ground_content = false, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), +}) + + +minetest.register_node("default:stone_with_copper", { + description = S("Copper Ore"), + tiles = {"default_stone.png^default_mineral_copper.png"}, + groups = {cracky = 2}, + drop = "default:copper_lump", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:copperblock", { + description = S("Copper Block"), + tiles = {"default_copper_block.png"}, + is_ground_content = false, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), +}) + + +minetest.register_node("default:stone_with_tin", { + description = S("Tin Ore"), + tiles = {"default_stone.png^default_mineral_tin.png"}, + groups = {cracky = 2}, + drop = "default:tin_lump", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:tinblock", { + description = S("Tin Block"), + tiles = {"default_tin_block.png"}, + is_ground_content = false, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), +}) + + +minetest.register_node("default:bronzeblock", { + description = S("Bronze Block"), + tiles = {"default_bronze_block.png"}, + is_ground_content = false, + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), +}) + + +minetest.register_node("default:stone_with_mese", { + description = S("Mese Ore"), + tiles = {"default_stone.png^default_mineral_mese.png"}, + groups = {cracky = 1}, + drop = "default:mese_crystal", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:mese", { + description = S("Mese Block"), + tiles = {"default_mese_block.png"}, + paramtype = "light", + groups = {cracky = 1, level = 2}, + sounds = default.node_sound_stone_defaults(), + light_source = 3, +}) + + +minetest.register_node("default:stone_with_gold", { + description = S("Gold Ore"), + tiles = {"default_stone.png^default_mineral_gold.png"}, + groups = {cracky = 2}, + drop = "default:gold_lump", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:goldblock", { + description = S("Gold Block"), + tiles = {"default_gold_block.png"}, + is_ground_content = false, + groups = {cracky = 1}, + sounds = default.node_sound_metal_defaults(), +}) + + +minetest.register_node("default:stone_with_diamond", { + description = S("Diamond Ore"), + tiles = {"default_stone.png^default_mineral_diamond.png"}, + groups = {cracky = 1}, + drop = "default:diamond", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:diamondblock", { + description = S("Diamond Block"), + tiles = {"default_diamond_block.png"}, + is_ground_content = false, + groups = {cracky = 1, level = 3}, + sounds = default.node_sound_stone_defaults(), +}) + +-- +-- Plantlife (non-cubic) +-- + +minetest.register_node("default:cactus", { + description = S("Cactus"), + tiles = {"default_cactus_top.png", "default_cactus_top.png", + "default_cactus_side.png"}, + paramtype2 = "facedir", + groups = {choppy = 3}, + sounds = default.node_sound_wood_defaults(), + on_place = minetest.rotate_node, +}) + +minetest.register_node("default:large_cactus_seedling", { + description = S("Large Cactus Seedling"), + drawtype = "plantlike", + tiles = {"default_large_cactus_seedling.png"}, + inventory_image = "default_large_cactus_seedling.png", + wield_image = "default_large_cactus_seedling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + selection_box = { + type = "fixed", + fixed = { + -5 / 16, -0.5, -5 / 16, + 5 / 16, 0.5, 5 / 16 + } + }, + groups = {choppy = 3, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_wood_defaults(), + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:large_cactus_seedling", + {x = -2, y = -1, z = -2}, + {x = 2, y = 5, z = 2}, + 4) + + return itemstack + end, + + on_construct = function(pos) + -- Normal cactus farming adds 1 cactus node by ABM, + -- interval 12s, chance 83. + -- Consider starting with 5 cactus nodes. We make sure that growing a + -- large cactus is not a faster way to produce new cactus nodes. + -- Confirmed by experiment, when farming 5 cacti, on average 1 new + -- cactus node is added on average every + -- 83 / 5 = 16.6 intervals = 16.6 * 12 = 199.2s. + -- Large cactus contains on average 14 cactus nodes. + -- 14 * 199.2 = 2788.8s. + -- Set random range to average to 2789s. + minetest.get_node_timer(pos):start(math.random(1859, 3719)) + end, + + on_timer = function(pos) + local node_under = minetest.get_node_or_nil( + {x = pos.x, y = pos.y - 1, z = pos.z}) + if not node_under then + -- Node under not yet loaded, try later + minetest.get_node_timer(pos):start(300) + return + end + + if minetest.get_item_group(node_under.name, "sand") == 0 then + -- Seedling dies + minetest.remove_node(pos) + return + end + + local light_level = minetest.get_node_light(pos) + if not light_level or light_level < 13 then + -- Too dark for growth, try later in case it's night + minetest.get_node_timer(pos):start(300) + return + end + + minetest.log("action", "A large cactus seedling grows into a large" .. + "cactus at ".. minetest.pos_to_string(pos)) + default.grow_large_cactus(pos) + end, +}) + +minetest.register_node("default:papyrus", { + description = S("Papyrus"), + drawtype = "plantlike", + tiles = {"default_papyrus.png"}, + inventory_image = "default_papyrus.png", + wield_image = "default_papyrus.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, 0.5, 6 / 16}, + }, + groups = {snappy = 3, flammable = 2}, + sounds = default.node_sound_leaves_defaults(), + + after_dig_node = function(pos, node, metadata, digger) + default.dig_up(pos, node, digger) + end, +}) + +minetest.register_node("default:dry_shrub", { + description = S("Dry Shrub"), + drawtype = "plantlike", + waving = 1, + tiles = {"default_dry_shrub.png"}, + inventory_image = "default_dry_shrub.png", + wield_image = "default_dry_shrub.png", + paramtype = "light", + paramtype2 = "meshoptions", + place_param2 = 4, + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flammable = 3, attached_node = 1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, 4 / 16, 6 / 16}, + }, +}) + +minetest.register_node("default:junglegrass", { + description = S("Jungle Grass"), + drawtype = "plantlike", + waving = 1, + visual_scale = 1.69, + tiles = {"default_junglegrass.png"}, + inventory_image = "default_junglegrass.png", + wield_image = "default_junglegrass.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flora = 1, attached_node = 1, flammable = 1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, 0.5, 6 / 16}, + }, +}) + + +minetest.register_node("default:grass_1", { + description = S("Grass"), + drawtype = "plantlike", + waving = 1, + tiles = {"default_grass_1.png"}, + -- Use texture of a taller grass stage in inventory + inventory_image = "default_grass_3.png", + wield_image = "default_grass_3.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flora = 1, attached_node = 1, grass = 1, flammable = 1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -5 / 16, 6 / 16}, + }, + + on_place = function(itemstack, placer, pointed_thing) + -- place a random grass node + local stack = ItemStack("default:grass_" .. math.random(1,5)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("default:grass_1 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +for i = 2, 5 do + minetest.register_node("default:grass_" .. i, { + description = S("Grass"), + drawtype = "plantlike", + waving = 1, + tiles = {"default_grass_" .. i .. ".png"}, + inventory_image = "default_grass_" .. i .. ".png", + wield_image = "default_grass_" .. i .. ".png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "default:grass_1", + groups = {snappy = 3, flora = 1, attached_node = 1, + not_in_creative_inventory = 1, grass = 1, flammable = 1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -3 / 16, 6 / 16}, + }, + }) +end + + +minetest.register_node("default:dry_grass_1", { + description = S("Savanna Grass"), + drawtype = "plantlike", + waving = 1, + tiles = {"default_dry_grass_1.png"}, + inventory_image = "default_dry_grass_3.png", + wield_image = "default_dry_grass_3.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flammable = 3, flora = 1, + attached_node = 1, dry_grass = 1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -3 / 16, 6 / 16}, + }, + + on_place = function(itemstack, placer, pointed_thing) + -- place a random dry grass node + local stack = ItemStack("default:dry_grass_" .. math.random(1, 5)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("default:dry_grass_1 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +for i = 2, 5 do + minetest.register_node("default:dry_grass_" .. i, { + description = S("Savanna Grass"), + drawtype = "plantlike", + waving = 1, + tiles = {"default_dry_grass_" .. i .. ".png"}, + inventory_image = "default_dry_grass_" .. i .. ".png", + wield_image = "default_dry_grass_" .. i .. ".png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flammable = 3, flora = 1, attached_node = 1, + not_in_creative_inventory=1, dry_grass = 1}, + drop = "default:dry_grass_1", + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -1 / 16, 6 / 16}, + }, + }) +end + + +minetest.register_node("default:fern_1", { + description = S("Fern"), + drawtype = "plantlike", + waving = 1, + tiles = {"default_fern_1.png"}, + inventory_image = "default_fern_1.png", + wield_image = "default_fern_1.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flammable = 3, flora = 1, attached_node = 1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -0.25, 6 / 16}, + }, + + on_place = function(itemstack, placer, pointed_thing) + -- place a random fern node + local stack = ItemStack("default:fern_" .. math.random(1, 3)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("default:fern_1 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +for i = 2, 3 do + minetest.register_node("default:fern_" .. i, { + description = S("Fern"), + drawtype = "plantlike", + waving = 1, + visual_scale = 2, + tiles = {"default_fern_" .. i .. ".png"}, + inventory_image = "default_fern_" .. i .. ".png", + wield_image = "default_fern_" .. i .. ".png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flammable = 3, flora = 1, attached_node = 1, + not_in_creative_inventory=1}, + drop = "default:fern_1", + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -0.25, 6 / 16}, + }, + }) +end + + +minetest.register_node("default:marram_grass_1", { + description = S("Marram Grass"), + drawtype = "plantlike", + waving = 1, + tiles = {"default_marram_grass_1.png"}, + inventory_image = "default_marram_grass_1.png", + wield_image = "default_marram_grass_1.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flammable = 3, attached_node = 1}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -0.25, 6 / 16}, + }, + + on_place = function(itemstack, placer, pointed_thing) + -- place a random marram grass node + local stack = ItemStack("default:marram_grass_" .. math.random(1, 3)) + local ret = minetest.item_place(stack, placer, pointed_thing) + return ItemStack("default:marram_grass_1 " .. + itemstack:get_count() - (1 - ret:get_count())) + end, +}) + +for i = 2, 3 do + minetest.register_node("default:marram_grass_" .. i, { + description = S("Marram Grass"), + drawtype = "plantlike", + waving = 1, + tiles = {"default_marram_grass_" .. i .. ".png"}, + inventory_image = "default_marram_grass_" .. i .. ".png", + wield_image = "default_marram_grass_" .. i .. ".png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {snappy = 3, flammable = 3, attached_node = 1, + not_in_creative_inventory=1}, + drop = "default:marram_grass_1", + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, -0.25, 6 / 16}, + }, + }) +end + + +minetest.register_node("default:bush_stem", { + description = S("Bush Stem"), + drawtype = "plantlike", + visual_scale = 1.41, + tiles = {"default_bush_stem.png"}, + inventory_image = "default_bush_stem.png", + wield_image = "default_bush_stem.png", + paramtype = "light", + sunlight_propagates = true, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + selection_box = { + type = "fixed", + fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, 0.5, 7 / 16}, + }, +}) + +minetest.register_node("default:bush_leaves", { + description = S("Bush Leaves"), + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_leaves_simple.png"}, + paramtype = "light", + groups = {snappy = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + {items = {"default:bush_sapling"}, rarity = 5}, + {items = {"default:bush_leaves"}} + } + }, + sounds = default.node_sound_leaves_defaults(), + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:bush_sapling", { + description = S("Bush Sapling"), + drawtype = "plantlike", + tiles = {"default_bush_sapling.png"}, + inventory_image = "default_bush_sapling.png", + wield_image = "default_bush_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 2 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:bush_sapling", + -- minp, maxp to be checked, relative to sapling pos + {x = -1, y = 0, z = -1}, + {x = 1, y = 1, z = 1}, + -- maximum interval of interior volume check + 2) + + return itemstack + end, +}) + +minetest.register_node("default:blueberry_bush_leaves_with_berries", { + description = S("Blueberry Bush Leaves with Berries"), + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_blueberry_bush_leaves.png^default_blueberry_overlay.png"}, + paramtype = "light", + groups = {snappy = 3, flammable = 2, leaves = 1, dig_immediate = 3}, + drop = "default:blueberries", + sounds = default.node_sound_leaves_defaults(), + node_dig_prediction = "default:blueberry_bush_leaves", + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + minetest.set_node(pos, {name = "default:blueberry_bush_leaves"}) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, +}) + +minetest.register_node("default:blueberry_bush_leaves", { + description = S("Blueberry Bush Leaves"), + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_blueberry_bush_leaves.png"}, + paramtype = "light", + groups = {snappy = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + {items = {"default:blueberry_bush_sapling"}, rarity = 5}, + {items = {"default:blueberry_bush_leaves"}} + } + }, + sounds = default.node_sound_leaves_defaults(), + + on_timer = function(pos, elapsed) + if minetest.get_node_light(pos) < 11 then + minetest.get_node_timer(pos):start(200) + else + minetest.set_node(pos, {name = "default:blueberry_bush_leaves_with_berries"}) + end + end, + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:blueberry_bush_sapling", { + description = S("Blueberry Bush Sapling"), + drawtype = "plantlike", + tiles = {"default_blueberry_bush_sapling.png"}, + inventory_image = "default_blueberry_bush_sapling.png", + wield_image = "default_blueberry_bush_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 2 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:blueberry_bush_sapling", + -- minp, maxp to be checked, relative to sapling pos + {x = -1, y = 0, z = -1}, + {x = 1, y = 1, z = 1}, + -- maximum interval of interior volume check + 2) + + return itemstack + end, +}) + +minetest.register_node("default:acacia_bush_stem", { + description = S("Acacia Bush Stem"), + drawtype = "plantlike", + visual_scale = 1.41, + tiles = {"default_acacia_bush_stem.png"}, + inventory_image = "default_acacia_bush_stem.png", + wield_image = "default_acacia_bush_stem.png", + paramtype = "light", + sunlight_propagates = true, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + selection_box = { + type = "fixed", + fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, 0.5, 7 / 16}, + }, +}) + +minetest.register_node("default:acacia_bush_leaves", { + description = S("Acacia Bush Leaves"), + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_acacia_leaves_simple.png"}, + paramtype = "light", + groups = {snappy = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + {items = {"default:acacia_bush_sapling"}, rarity = 5}, + {items = {"default:acacia_bush_leaves"}} + } + }, + sounds = default.node_sound_leaves_defaults(), + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:acacia_bush_sapling", { + description = S("Acacia Bush Sapling"), + drawtype = "plantlike", + tiles = {"default_acacia_bush_sapling.png"}, + inventory_image = "default_acacia_bush_sapling.png", + wield_image = "default_acacia_bush_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-3 / 16, -0.5, -3 / 16, 3 / 16, 2 / 16, 3 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:acacia_bush_sapling", + -- minp, maxp to be checked, relative to sapling pos + {x = -1, y = 0, z = -1}, + {x = 1, y = 1, z = 1}, + -- maximum interval of interior volume check + 2) + + return itemstack + end, +}) + +minetest.register_node("default:pine_bush_stem", { + description = S("Pine Bush Stem"), + drawtype = "plantlike", + visual_scale = 1.41, + tiles = {"default_pine_bush_stem.png"}, + inventory_image = "default_pine_bush_stem.png", + wield_image = "default_pine_bush_stem.png", + paramtype = "light", + sunlight_propagates = true, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + selection_box = { + type = "fixed", + fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, 0.5, 7 / 16}, + }, +}) + +minetest.register_node("default:pine_bush_needles", { + description = S("Pine Bush Needles"), + drawtype = "allfaces_optional", + waving = 1, + tiles = {"default_pine_needles.png"}, + paramtype = "light", + groups = {snappy = 3, flammable = 2, leaves = 1}, + drop = { + max_items = 1, + items = { + {items = {"default:pine_bush_sapling"}, rarity = 5}, + {items = {"default:pine_bush_needles"}} + } + }, + sounds = default.node_sound_leaves_defaults(), + + after_place_node = after_place_leaves, +}) + +minetest.register_node("default:pine_bush_sapling", { + description = S("Pine Bush Sapling"), + drawtype = "plantlike", + tiles = {"default_pine_bush_sapling.png"}, + inventory_image = "default_pine_bush_sapling.png", + wield_image = "default_pine_bush_sapling.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + on_timer = grow_sapling, + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, 2 / 16, 4 / 16} + }, + groups = {snappy = 2, dig_immediate = 3, flammable = 2, + attached_node = 1, sapling = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end, + + on_place = function(itemstack, placer, pointed_thing) + itemstack = default.sapling_on_place(itemstack, placer, pointed_thing, + "default:pine_bush_sapling", + -- minp, maxp to be checked, relative to sapling pos + {x = -1, y = 0, z = -1}, + {x = 1, y = 1, z = 1}, + -- maximum interval of interior volume check + 2) + + return itemstack + end, +}) + +minetest.register_node("default:sand_with_kelp", { + description = S("Kelp"), + drawtype = "plantlike_rooted", + waving = 1, + tiles = {"default_sand.png"}, + special_tiles = {{name = "default_kelp.png", tileable_vertical = true}}, + inventory_image = "default_kelp.png", + paramtype = "light", + paramtype2 = "leveled", + groups = {snappy = 3}, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + {-2/16, 0.5, -2/16, 2/16, 3.5, 2/16}, + }, + }, + node_dig_prediction = "default:sand", + node_placement_prediction = "", + sounds = default.node_sound_sand_defaults({ + dig = {name = "default_dig_snappy", gain = 0.2}, + dug = {name = "default_grass_footstep", gain = 0.25}, + }), + + on_place = function(itemstack, placer, pointed_thing) + -- Call on_rightclick if the pointed node defines it + if pointed_thing.type == "node" and placer and + not placer:get_player_control().sneak then + local node_ptu = minetest.get_node(pointed_thing.under) + local def_ptu = minetest.registered_nodes[node_ptu.name] + if def_ptu and def_ptu.on_rightclick then + return def_ptu.on_rightclick(pointed_thing.under, node_ptu, placer, + itemstack, pointed_thing) + end + end + + local pos = pointed_thing.under + if minetest.get_node(pos).name ~= "default:sand" then + return itemstack + end + + local height = math.random(4, 6) + local pos_top = {x = pos.x, y = pos.y + height, z = pos.z} + local node_top = minetest.get_node(pos_top) + local def_top = minetest.registered_nodes[node_top.name] + local player_name = placer:get_player_name() + + if def_top and def_top.liquidtype == "source" and + minetest.get_item_group(node_top.name, "water") > 0 then + if not minetest.is_protected(pos, player_name) and + not minetest.is_protected(pos_top, player_name) then + minetest.set_node(pos, {name = "default:sand_with_kelp", + param2 = height * 16}) + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(player_name)) then + itemstack:take_item() + end + else + minetest.chat_send_player(player_name, "Node is protected") + minetest.record_protection_violation(pos, player_name) + end + end + + return itemstack + end, + + after_destruct = function(pos, oldnode) + minetest.set_node(pos, {name = "default:sand"}) + end +}) + + +-- +-- Corals +-- + +local function coral_on_place(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" or not placer then + return itemstack + end + + local player_name = placer:get_player_name() + local pos_under = pointed_thing.under + local pos_above = pointed_thing.above + local node_under = minetest.get_node(pos_under) + local def_under = minetest.registered_nodes[node_under.name] + + if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then + return def_under.on_rightclick(pos_under, node_under, + placer, itemstack, pointed_thing) or itemstack + end + + if node_under.name ~= "default:coral_skeleton" or + minetest.get_node(pos_above).name ~= "default:water_source" then + return itemstack + end + + if minetest.is_protected(pos_under, player_name) or + minetest.is_protected(pos_above, player_name) then + minetest.log("action", player_name + .. " tried to place " .. itemstack:get_name() + .. " at protected position " + .. minetest.pos_to_string(pos_under)) + minetest.record_protection_violation(pos_under, player_name) + return itemstack + end + + node_under.name = itemstack:get_name() + minetest.set_node(pos_under, node_under) + if not (creative and creative.is_enabled_for(player_name)) then + itemstack:take_item() + end + + return itemstack +end + +minetest.register_node("default:coral_green", { + description = S("Green Coral"), + drawtype = "plantlike_rooted", + waving = 1, + paramtype = "light", + tiles = {"default_coral_skeleton.png"}, + special_tiles = {{name = "default_coral_green.png", tileable_vertical = true}}, + inventory_image = "default_coral_green.png", + groups = {snappy = 3}, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + {-4/16, 0.5, -4/16, 4/16, 1.5, 4/16}, + }, + }, + node_dig_prediction = "default:coral_skeleton", + node_placement_prediction = "", + sounds = default.node_sound_stone_defaults({ + dig = {name = "default_dig_snappy", gain = 0.2}, + dug = {name = "default_grass_footstep", gain = 0.25}, + }), + + on_place = coral_on_place, + + after_destruct = function(pos, oldnode) + minetest.set_node(pos, {name = "default:coral_skeleton"}) + end, +}) + +minetest.register_node("default:coral_pink", { + description = S("Pink Coral"), + drawtype = "plantlike_rooted", + waving = 1, + paramtype = "light", + tiles = {"default_coral_skeleton.png"}, + special_tiles = {{name = "default_coral_pink.png", tileable_vertical = true}}, + inventory_image = "default_coral_pink.png", + groups = {snappy = 3}, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + {-4/16, 0.5, -4/16, 4/16, 1.5, 4/16}, + }, + }, + node_dig_prediction = "default:coral_skeleton", + node_placement_prediction = "", + sounds = default.node_sound_stone_defaults({ + dig = {name = "default_dig_snappy", gain = 0.2}, + dug = {name = "default_grass_footstep", gain = 0.25}, + }), + + on_place = coral_on_place, + + after_destruct = function(pos, oldnode) + minetest.set_node(pos, {name = "default:coral_skeleton"}) + end, +}) + +minetest.register_node("default:coral_cyan", { + description = S("Cyan Coral"), + drawtype = "plantlike_rooted", + waving = 1, + paramtype = "light", + tiles = {"default_coral_skeleton.png"}, + special_tiles = {{name = "default_coral_cyan.png", tileable_vertical = true}}, + inventory_image = "default_coral_cyan.png", + groups = {snappy = 3}, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + {-4/16, 0.5, -4/16, 4/16, 1.5, 4/16}, + }, + }, + node_dig_prediction = "default:coral_skeleton", + node_placement_prediction = "", + sounds = default.node_sound_stone_defaults({ + dig = {name = "default_dig_snappy", gain = 0.2}, + dug = {name = "default_grass_footstep", gain = 0.25}, + }), + + on_place = coral_on_place, + + after_destruct = function(pos, oldnode) + minetest.set_node(pos, {name = "default:coral_skeleton"}) + end, +}) + +minetest.register_node("default:coral_brown", { + description = S("Brown Coral"), + tiles = {"default_coral_brown.png"}, + groups = {cracky = 3}, + drop = "default:coral_skeleton", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:coral_orange", { + description = S("Orange Coral"), + tiles = {"default_coral_orange.png"}, + groups = {cracky = 3}, + drop = "default:coral_skeleton", + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("default:coral_skeleton", { + description = S("Coral Skeleton"), + tiles = {"default_coral_skeleton.png"}, + groups = {cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + + +-- +-- Liquids +-- + +minetest.register_node("default:water_source", { + description = S("Water Source"), + drawtype = "liquid", + waving = 3, + tiles = { + { + name = "default_water_source_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + { + name = "default_water_source_animated.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + alpha = 191, + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "default:water_flowing", + liquid_alternative_source = "default:water_source", + liquid_viscosity = 1, + post_effect_color = {a = 103, r = 30, g = 60, b = 90}, + groups = {water = 3, liquid = 3, cools_lava = 1}, + sounds = default.node_sound_water_defaults(), +}) + +minetest.register_node("default:water_flowing", { + description = S("Flowing Water"), + drawtype = "flowingliquid", + waving = 3, + tiles = {"default_water.png"}, + special_tiles = { + { + name = "default_water_flowing_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.5, + }, + }, + { + name = "default_water_flowing_animated.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.5, + }, + }, + }, + alpha = 191, + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "default:water_flowing", + liquid_alternative_source = "default:water_source", + liquid_viscosity = 1, + post_effect_color = {a = 103, r = 30, g = 60, b = 90}, + groups = {water = 3, liquid = 3, not_in_creative_inventory = 1, + cools_lava = 1}, + sounds = default.node_sound_water_defaults(), +}) + + +minetest.register_node("default:river_water_source", { + description = S("River Water Source"), + drawtype = "liquid", + tiles = { + { + name = "default_river_water_source_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + { + name = "default_river_water_source_animated.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + alpha = 160, + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "default:river_water_flowing", + liquid_alternative_source = "default:river_water_source", + liquid_viscosity = 1, + -- Not renewable to avoid horizontal spread of water sources in sloping + -- rivers that can cause water to overflow riverbanks and cause floods. + -- River water source is instead made renewable by the 'force renew' + -- option used in the 'bucket' mod by the river water bucket. + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + groups = {water = 3, liquid = 3, cools_lava = 1}, + sounds = default.node_sound_water_defaults(), +}) + +minetest.register_node("default:river_water_flowing", { + description = S("Flowing River Water"), + drawtype = "flowingliquid", + tiles = {"default_river_water.png"}, + special_tiles = { + { + name = "default_river_water_flowing_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.5, + }, + }, + { + name = "default_river_water_flowing_animated.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.5, + }, + }, + }, + alpha = 160, + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "default:river_water_flowing", + liquid_alternative_source = "default:river_water_source", + liquid_viscosity = 1, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a = 103, r = 30, g = 76, b = 90}, + groups = {water = 3, liquid = 3, not_in_creative_inventory = 1, + cools_lava = 1}, + sounds = default.node_sound_water_defaults(), +}) + + +minetest.register_node("default:lava_source", { + description = S("Lava Source"), + drawtype = "liquid", + tiles = { + { + name = "default_lava_source_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 3.0, + }, + }, + { + name = "default_lava_source_animated.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 3.0, + }, + }, + }, + paramtype = "light", + light_source = default.LIGHT_MAX - 1, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "default:lava_flowing", + liquid_alternative_source = "default:lava_source", + liquid_viscosity = 7, + liquid_renewable = false, + damage_per_second = 4 * 2, + post_effect_color = {a = 191, r = 255, g = 64, b = 0}, + groups = {lava = 3, liquid = 2, igniter = 1}, +}) + +minetest.register_node("default:lava_flowing", { + description = S("Flowing Lava"), + drawtype = "flowingliquid", + tiles = {"default_lava.png"}, + special_tiles = { + { + name = "default_lava_flowing_animated.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 3.3, + }, + }, + { + name = "default_lava_flowing_animated.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 3.3, + }, + }, + }, + paramtype = "light", + paramtype2 = "flowingliquid", + light_source = default.LIGHT_MAX - 1, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "default:lava_flowing", + liquid_alternative_source = "default:lava_source", + liquid_viscosity = 7, + liquid_renewable = false, + damage_per_second = 4 * 2, + post_effect_color = {a = 191, r = 255, g = 64, b = 0}, + groups = {lava = 3, liquid = 2, igniter = 1, + not_in_creative_inventory = 1}, +}) + +-- +-- Tools / "Advanced" crafting / Non-"natural" +-- + +local bookshelf_formspec = + "size[8,7;]" .. + "list[context;books;0,0.3;8,2;]" .. + "list[current_player;main;0,2.85;8,1;]" .. + "list[current_player;main;0,4.08;8,3;8]" .. + "listring[context;books]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,2.85) + +local function update_bookshelf(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local invlist = inv:get_list("books") + + local formspec = bookshelf_formspec + -- Inventory slots overlay + local bx, by = 0, 0.3 + local n_written, n_empty = 0, 0 + for i = 1, 16 do + if i == 9 then + bx = 0 + by = by + 1 + end + local stack = invlist[i] + if stack:is_empty() then + formspec = formspec .. + "image[" .. bx .. "," .. by .. ";1,1;default_bookshelf_slot.png]" + else + local metatable = stack:get_meta():to_table() or {} + if metatable.fields and metatable.fields.text then + n_written = n_written + stack:get_count() + else + n_empty = n_empty + stack:get_count() + end + end + bx = bx + 1 + end + meta:set_string("formspec", formspec) + if n_written + n_empty == 0 then + meta:set_string("infotext", S("Empty Bookshelf")) + else + meta:set_string("infotext", S("Bookshelf (@1 written, @2 empty books)", n_written, n_empty)) + end +end + +minetest.register_node("default:bookshelf", { + description = S("Bookshelf"), + tiles = {"default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "default_bookshelf.png", "default_bookshelf.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + update_bookshelf(pos) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack) + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + end + return 0 + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + update_bookshelf(pos) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " puts stuff to bookshelf at " .. minetest.pos_to_string(pos)) + update_bookshelf(pos) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + update_bookshelf(pos) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "default:bookshelf" + minetest.remove_node(pos) + return drops + end, +}) + +local function register_sign(material, desc, def) + minetest.register_node("default:sign_wall_" .. material, { + description = desc, + drawtype = "nodebox", + tiles = {"default_sign_wall_" .. material .. ".png"}, + inventory_image = "default_sign_" .. material .. ".png", + wield_image = "default_sign_" .. material .. ".png", + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + node_box = { + type = "wallmounted", + wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}, + wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, + wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375}, + }, + groups = def.groups, + legacy_wallmounted = true, + sounds = def.sounds, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", "field[text;;${text}]") + end, + on_receive_fields = function(pos, formname, fields, sender) + local player_name = sender:get_player_name() + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return + end + local text = fields.text + if not text then + return + end + if string.len(text) > 512 then + minetest.chat_send_player(player_name, S("Text too long")) + return + end + minetest.log("action", player_name .. " wrote \"" .. text .. + "\" to the sign at " .. minetest.pos_to_string(pos)) + local meta = minetest.get_meta(pos) + meta:set_string("text", text) + + if #text > 0 then + meta:set_string("infotext", S('"@1"', text)) + else + meta:set_string("infotext", '') + end + end, + }) +end + +register_sign("wood", S("Wooden Sign"), { + sounds = default.node_sound_wood_defaults(), + groups = {choppy = 2, attached_node = 1, flammable = 2, oddly_breakable_by_hand = 3} +}) + +register_sign("steel", S("Steel Sign"), { + sounds = default.node_sound_metal_defaults(), + groups = {cracky = 2, attached_node = 1} +}) + +minetest.register_node("default:ladder_wood", { + description = S("Wooden Ladder"), + drawtype = "signlike", + tiles = {"default_ladder_wood.png"}, + inventory_image = "default_ladder_wood.png", + wield_image = "default_ladder_wood.png", + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + climbable = true, + is_ground_content = false, + selection_box = { + type = "wallmounted", + --wall_top = = + --wall_bottom = = + --wall_side = = + }, + groups = {choppy = 2, oddly_breakable_by_hand = 3, flammable = 2}, + legacy_wallmounted = true, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node("default:ladder_steel", { + description = S("Steel Ladder"), + drawtype = "signlike", + tiles = {"default_ladder_steel.png"}, + inventory_image = "default_ladder_steel.png", + wield_image = "default_ladder_steel.png", + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + climbable = true, + is_ground_content = false, + selection_box = { + type = "wallmounted", + --wall_top = = + --wall_bottom = = + --wall_side = = + }, + groups = {cracky = 2}, + sounds = default.node_sound_metal_defaults(), +}) + +default.register_fence("default:fence_wood", { + description = S("Apple Wood Fence"), + texture = "default_fence_wood.png", + inventory_image = "default_fence_overlay.png^default_wood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_wood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + material = "default:wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence("default:fence_acacia_wood", { + description = S("Acacia Wood Fence"), + texture = "default_fence_acacia_wood.png", + inventory_image = "default_fence_overlay.png^default_acacia_wood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_acacia_wood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + material = "default:acacia_wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence("default:fence_junglewood", { + description = S("Jungle Wood Fence"), + texture = "default_fence_junglewood.png", + inventory_image = "default_fence_overlay.png^default_junglewood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_junglewood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + material = "default:junglewood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence("default:fence_pine_wood", { + description = S("Pine Wood Fence"), + texture = "default_fence_pine_wood.png", + inventory_image = "default_fence_overlay.png^default_pine_wood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_pine_wood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + material = "default:pine_wood", + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence("default:fence_aspen_wood", { + description = S("Aspen Wood Fence"), + texture = "default_fence_aspen_wood.png", + inventory_image = "default_fence_overlay.png^default_aspen_wood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_overlay.png^default_aspen_wood.png^" .. + "default_fence_overlay.png^[makealpha:255,126,126", + material = "default:aspen_wood", + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence_rail("default:fence_rail_wood", { + description = S("Apple Wood Fence Rail"), + texture = "default_fence_rail_wood.png", + inventory_image = "default_fence_rail_overlay.png^default_wood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_rail_overlay.png^default_wood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + material = "default:wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence_rail("default:fence_rail_acacia_wood", { + description = S("Acacia Wood Fence Rail"), + texture = "default_fence_rail_acacia_wood.png", + inventory_image = "default_fence_rail_overlay.png^default_acacia_wood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_rail_overlay.png^default_acacia_wood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + material = "default:acacia_wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence_rail("default:fence_rail_junglewood", { + description = S("Jungle Wood Fence Rail"), + texture = "default_fence_rail_junglewood.png", + inventory_image = "default_fence_rail_overlay.png^default_junglewood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_rail_overlay.png^default_junglewood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + material = "default:junglewood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence_rail("default:fence_rail_pine_wood", { + description = S("Pine Wood Fence Rail"), + texture = "default_fence_rail_pine_wood.png", + inventory_image = "default_fence_rail_overlay.png^default_pine_wood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_rail_overlay.png^default_pine_wood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + material = "default:pine_wood", + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults() +}) + +default.register_fence_rail("default:fence_rail_aspen_wood", { + description = S("Aspen Wood Fence Rail"), + texture = "default_fence_rail_aspen_wood.png", + inventory_image = "default_fence_rail_overlay.png^default_aspen_wood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + wield_image = "default_fence_rail_overlay.png^default_aspen_wood.png^" .. + "default_fence_rail_overlay.png^[makealpha:255,126,126", + material = "default:aspen_wood", + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 2}, + sounds = default.node_sound_wood_defaults() +}) + +minetest.register_node("default:glass", { + description = S("Glass"), + drawtype = "glasslike_framed_optional", + tiles = {"default_glass.png", "default_glass_detail.png"}, + paramtype = "light", + paramtype2 = "glasslikeliquidlevel", + sunlight_propagates = true, + is_ground_content = false, + groups = {cracky = 3, oddly_breakable_by_hand = 3}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_node("default:obsidian_glass", { + description = S("Obsidian Glass"), + drawtype = "glasslike_framed_optional", + tiles = {"default_obsidian_glass.png", "default_obsidian_glass_detail.png"}, + paramtype = "light", + paramtype2 = "glasslikeliquidlevel", + is_ground_content = false, + sunlight_propagates = true, + sounds = default.node_sound_glass_defaults(), + groups = {cracky = 3}, +}) + + +minetest.register_node("default:brick", { + description = S("Brick Block"), + paramtype2 = "facedir", + place_param2 = 0, + tiles = { + "default_brick.png^[transformFX", + "default_brick.png", + }, + is_ground_content = false, + groups = {cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + + +minetest.register_node("default:meselamp", { + description = S("Mese Lamp"), + drawtype = "glasslike", + tiles = {"default_meselamp.png"}, + paramtype = "light", + sunlight_propagates = true, + is_ground_content = false, + groups = {cracky = 3, oddly_breakable_by_hand = 3}, + sounds = default.node_sound_glass_defaults(), + light_source = default.LIGHT_MAX, +}) + +minetest.register_node("default:mese_post_light", { + description = S("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 +-- + +minetest.register_node("default:cloud", { + description = S("Cloud"), + tiles = {"default_cloud.png"}, + is_ground_content = false, + 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, + }) +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, + }) +end + +default.register_leafdecay({ + trunks = {"default:pine_tree"}, + leaves = {"default:pine_needles"}, + radius = 3, +}) + +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 = 3, +}) + +default.register_leafdecay({ + trunks = {"default:bush_stem"}, + leaves = {"default:bush_leaves"}, + radius = 1, +}) + +default.register_leafdecay({ + trunks = {"default:acacia_bush_stem"}, + leaves = {"default:acacia_bush_leaves"}, + radius = 1, +}) + +default.register_leafdecay({ + trunks = {"default:pine_bush_stem"}, + leaves = {"default:pine_bush_needles"}, + radius = 1, +}) diff --git a/mods/default/schematics/acacia_bush.mts b/mods/default/schematics/acacia_bush.mts new file mode 100644 index 0000000..3322e3b Binary files /dev/null and b/mods/default/schematics/acacia_bush.mts differ diff --git a/mods/default/schematics/acacia_log.mts b/mods/default/schematics/acacia_log.mts new file mode 100644 index 0000000..aff3bd6 Binary files /dev/null and b/mods/default/schematics/acacia_log.mts differ diff --git a/mods/default/schematics/acacia_tree.mts b/mods/default/schematics/acacia_tree.mts new file mode 100644 index 0000000..9b23498 Binary files /dev/null and b/mods/default/schematics/acacia_tree.mts differ diff --git a/mods/default/schematics/acacia_tree_from_sapling.mts b/mods/default/schematics/acacia_tree_from_sapling.mts new file mode 100644 index 0000000..c32a995 Binary files /dev/null and b/mods/default/schematics/acacia_tree_from_sapling.mts differ diff --git a/mods/default/schematics/apple_log.mts b/mods/default/schematics/apple_log.mts new file mode 100644 index 0000000..92fb900 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 new file mode 100644 index 0000000..d56cd54 Binary files /dev/null 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 new file mode 100644 index 0000000..2325100 Binary files /dev/null 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 0000000..d0c723d 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 new file mode 100644 index 0000000..429a831 Binary files /dev/null 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 new file mode 100644 index 0000000..b7ab3ee Binary files /dev/null and b/mods/default/schematics/aspen_tree_from_sapling.mts differ diff --git a/mods/default/schematics/blueberry_bush.mts b/mods/default/schematics/blueberry_bush.mts new file mode 100644 index 0000000..cf4d8ef Binary files /dev/null and b/mods/default/schematics/blueberry_bush.mts differ diff --git a/mods/default/schematics/bush.mts b/mods/default/schematics/bush.mts new file mode 100644 index 0000000..d08cf5f Binary files /dev/null and b/mods/default/schematics/bush.mts differ diff --git a/mods/default/schematics/emergent_jungle_tree.mts b/mods/default/schematics/emergent_jungle_tree.mts new file mode 100644 index 0000000..b526430 Binary files /dev/null and b/mods/default/schematics/emergent_jungle_tree.mts differ diff --git a/mods/default/schematics/emergent_jungle_tree_from_sapling.mts b/mods/default/schematics/emergent_jungle_tree_from_sapling.mts new file mode 100644 index 0000000..cb4e4e9 Binary files /dev/null and b/mods/default/schematics/emergent_jungle_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 0000000..34dca43 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 new file mode 100644 index 0000000..fe93c8c Binary files /dev/null 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 new file mode 100644 index 0000000..f32d312 Binary files /dev/null and b/mods/default/schematics/jungle_tree_from_sapling.mts differ diff --git a/mods/default/schematics/large_cactus.mts b/mods/default/schematics/large_cactus.mts new file mode 100644 index 0000000..cadcdcc Binary files /dev/null and b/mods/default/schematics/large_cactus.mts differ diff --git a/mods/default/schematics/papyrus_on_dirt.mts b/mods/default/schematics/papyrus_on_dirt.mts new file mode 100644 index 0000000..1333a7c Binary files /dev/null and b/mods/default/schematics/papyrus_on_dirt.mts differ diff --git a/mods/default/schematics/papyrus_on_dry_dirt.mts b/mods/default/schematics/papyrus_on_dry_dirt.mts new file mode 100644 index 0000000..3626580 Binary files /dev/null and b/mods/default/schematics/papyrus_on_dry_dirt.mts differ diff --git a/mods/default/schematics/pine_bush.mts b/mods/default/schematics/pine_bush.mts new file mode 100644 index 0000000..ca572a7 Binary files /dev/null and b/mods/default/schematics/pine_bush.mts differ diff --git a/mods/default/schematics/pine_log.mts b/mods/default/schematics/pine_log.mts new file mode 100644 index 0000000..d51a489 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 new file mode 100644 index 0000000..c80532a Binary files /dev/null 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 new file mode 100644 index 0000000..0800387 Binary files /dev/null and b/mods/default/schematics/pine_tree_from_sapling.mts differ diff --git a/mods/default/schematics/small_pine_tree.mts b/mods/default/schematics/small_pine_tree.mts new file mode 100644 index 0000000..b283226 Binary files /dev/null and b/mods/default/schematics/small_pine_tree.mts differ diff --git a/mods/default/schematics/small_pine_tree_from_sapling.mts b/mods/default/schematics/small_pine_tree_from_sapling.mts new file mode 100644 index 0000000..a1b1170 Binary files /dev/null and b/mods/default/schematics/small_pine_tree_from_sapling.mts differ diff --git a/mods/default/schematics/snowy_pine_tree_from_sapling.mts b/mods/default/schematics/snowy_pine_tree_from_sapling.mts new file mode 100644 index 0000000..3d502a3 Binary files /dev/null and b/mods/default/schematics/snowy_pine_tree_from_sapling.mts differ diff --git a/mods/default/schematics/snowy_small_pine_tree_from_sapling.mts b/mods/default/schematics/snowy_small_pine_tree_from_sapling.mts new file mode 100644 index 0000000..d017c9e Binary files /dev/null and b/mods/default/schematics/snowy_small_pine_tree_from_sapling.mts differ diff --git a/mods/default/sounds/default_break_glass.1.ogg b/mods/default/sounds/default_break_glass.1.ogg new file mode 100644 index 0000000..b1ccc5f Binary files /dev/null and b/mods/default/sounds/default_break_glass.1.ogg differ diff --git a/mods/default/sounds/default_break_glass.2.ogg b/mods/default/sounds/default_break_glass.2.ogg new file mode 100644 index 0000000..b6cc9e8 Binary files /dev/null and b/mods/default/sounds/default_break_glass.2.ogg differ diff --git a/mods/default/sounds/default_break_glass.3.ogg b/mods/default/sounds/default_break_glass.3.ogg new file mode 100644 index 0000000..ae6a6bf Binary files /dev/null and b/mods/default/sounds/default_break_glass.3.ogg differ diff --git a/mods/default/sounds/default_chest_close.ogg b/mods/default/sounds/default_chest_close.ogg new file mode 100644 index 0000000..068d900 Binary files /dev/null and b/mods/default/sounds/default_chest_close.ogg differ diff --git a/mods/default/sounds/default_chest_open.ogg b/mods/default/sounds/default_chest_open.ogg new file mode 100644 index 0000000..40b0b93 Binary files /dev/null and b/mods/default/sounds/default_chest_open.ogg differ diff --git a/mods/default/sounds/default_cool_lava.1.ogg b/mods/default/sounds/default_cool_lava.1.ogg new file mode 100644 index 0000000..42506dd Binary files /dev/null and b/mods/default/sounds/default_cool_lava.1.ogg differ diff --git a/mods/default/sounds/default_cool_lava.2.ogg b/mods/default/sounds/default_cool_lava.2.ogg new file mode 100644 index 0000000..2747ab8 Binary files /dev/null and b/mods/default/sounds/default_cool_lava.2.ogg differ diff --git a/mods/default/sounds/default_cool_lava.3.ogg b/mods/default/sounds/default_cool_lava.3.ogg new file mode 100644 index 0000000..8baeac3 Binary files /dev/null and b/mods/default/sounds/default_cool_lava.3.ogg differ diff --git a/mods/default/sounds/default_dig_choppy.ogg b/mods/default/sounds/default_dig_choppy.ogg new file mode 100644 index 0000000..e2ecd84 Binary files /dev/null and b/mods/default/sounds/default_dig_choppy.ogg differ diff --git a/mods/default/sounds/default_dig_cracky.ogg b/mods/default/sounds/default_dig_cracky.ogg new file mode 100644 index 0000000..da11679 Binary files /dev/null and b/mods/default/sounds/default_dig_cracky.ogg differ diff --git a/mods/default/sounds/default_dig_crumbly.ogg b/mods/default/sounds/default_dig_crumbly.ogg new file mode 100644 index 0000000..a0b2a1f Binary files /dev/null and b/mods/default/sounds/default_dig_crumbly.ogg differ diff --git a/mods/default/sounds/default_dig_dig_immediate.ogg b/mods/default/sounds/default_dig_dig_immediate.ogg new file mode 100644 index 0000000..e65d766 Binary files /dev/null and b/mods/default/sounds/default_dig_dig_immediate.ogg differ diff --git a/mods/default/sounds/default_dig_metal.ogg b/mods/default/sounds/default_dig_metal.ogg new file mode 100644 index 0000000..0b58509 Binary files /dev/null and b/mods/default/sounds/default_dig_metal.ogg differ diff --git a/mods/default/sounds/default_dig_oddly_breakable_by_hand.ogg b/mods/default/sounds/default_dig_oddly_breakable_by_hand.ogg new file mode 100644 index 0000000..ef4d7b1 Binary files /dev/null and b/mods/default/sounds/default_dig_oddly_breakable_by_hand.ogg differ diff --git a/mods/default/sounds/default_dig_snappy.ogg b/mods/default/sounds/default_dig_snappy.ogg new file mode 100644 index 0000000..3686fcd Binary files /dev/null and b/mods/default/sounds/default_dig_snappy.ogg differ diff --git a/mods/default/sounds/default_dirt_footstep.1.ogg b/mods/default/sounds/default_dirt_footstep.1.ogg new file mode 100644 index 0000000..201aa3b Binary files /dev/null and b/mods/default/sounds/default_dirt_footstep.1.ogg differ diff --git a/mods/default/sounds/default_dirt_footstep.2.ogg b/mods/default/sounds/default_dirt_footstep.2.ogg new file mode 100644 index 0000000..2667dbc Binary files /dev/null and b/mods/default/sounds/default_dirt_footstep.2.ogg differ diff --git a/mods/default/sounds/default_dug_metal.1.ogg b/mods/default/sounds/default_dug_metal.1.ogg new file mode 100644 index 0000000..5d6cb5b Binary files /dev/null and b/mods/default/sounds/default_dug_metal.1.ogg differ diff --git a/mods/default/sounds/default_dug_metal.2.ogg b/mods/default/sounds/default_dug_metal.2.ogg new file mode 100644 index 0000000..63567fc Binary files /dev/null and b/mods/default/sounds/default_dug_metal.2.ogg differ diff --git a/mods/default/sounds/default_dug_node.1.ogg b/mods/default/sounds/default_dug_node.1.ogg new file mode 100644 index 0000000..c04975d Binary files /dev/null and b/mods/default/sounds/default_dug_node.1.ogg differ diff --git a/mods/default/sounds/default_dug_node.2.ogg b/mods/default/sounds/default_dug_node.2.ogg new file mode 100644 index 0000000..9f20926 Binary files /dev/null and b/mods/default/sounds/default_dug_node.2.ogg differ diff --git a/mods/default/sounds/default_glass_footstep.ogg b/mods/default/sounds/default_glass_footstep.ogg new file mode 100644 index 0000000..191287a Binary files /dev/null and b/mods/default/sounds/default_glass_footstep.ogg differ diff --git a/mods/default/sounds/default_grass_footstep.1.ogg b/mods/default/sounds/default_grass_footstep.1.ogg new file mode 100644 index 0000000..a04cdb4 Binary files /dev/null and b/mods/default/sounds/default_grass_footstep.1.ogg differ diff --git a/mods/default/sounds/default_grass_footstep.2.ogg b/mods/default/sounds/default_grass_footstep.2.ogg new file mode 100644 index 0000000..d193068 Binary files /dev/null and b/mods/default/sounds/default_grass_footstep.2.ogg differ diff --git a/mods/default/sounds/default_grass_footstep.3.ogg b/mods/default/sounds/default_grass_footstep.3.ogg new file mode 100644 index 0000000..e1897ea Binary files /dev/null and b/mods/default/sounds/default_grass_footstep.3.ogg differ diff --git a/mods/default/sounds/default_gravel_footstep.1.ogg b/mods/default/sounds/default_gravel_footstep.1.ogg new file mode 100644 index 0000000..8d260ce Binary files /dev/null and b/mods/default/sounds/default_gravel_footstep.1.ogg differ diff --git a/mods/default/sounds/default_gravel_footstep.2.ogg b/mods/default/sounds/default_gravel_footstep.2.ogg new file mode 100644 index 0000000..2aba2c6 Binary files /dev/null and b/mods/default/sounds/default_gravel_footstep.2.ogg differ diff --git a/mods/default/sounds/default_gravel_footstep.3.ogg b/mods/default/sounds/default_gravel_footstep.3.ogg new file mode 100644 index 0000000..1bcd8a1 Binary files /dev/null and b/mods/default/sounds/default_gravel_footstep.3.ogg differ diff --git a/mods/default/sounds/default_gravel_footstep.4.ogg b/mods/default/sounds/default_gravel_footstep.4.ogg new file mode 100644 index 0000000..696c9ff Binary files /dev/null and b/mods/default/sounds/default_gravel_footstep.4.ogg differ diff --git a/mods/default/sounds/default_hard_footstep.1.ogg b/mods/default/sounds/default_hard_footstep.1.ogg new file mode 100644 index 0000000..1748bc5 Binary files /dev/null and b/mods/default/sounds/default_hard_footstep.1.ogg differ diff --git a/mods/default/sounds/default_hard_footstep.2.ogg b/mods/default/sounds/default_hard_footstep.2.ogg new file mode 100644 index 0000000..fe39fd7 Binary files /dev/null and b/mods/default/sounds/default_hard_footstep.2.ogg differ diff --git a/mods/default/sounds/default_hard_footstep.3.ogg b/mods/default/sounds/default_hard_footstep.3.ogg new file mode 100644 index 0000000..5030e06 Binary files /dev/null and b/mods/default/sounds/default_hard_footstep.3.ogg differ diff --git a/mods/default/sounds/default_item_smoke.ogg b/mods/default/sounds/default_item_smoke.ogg new file mode 100644 index 0000000..038a46e Binary files /dev/null and b/mods/default/sounds/default_item_smoke.ogg differ diff --git a/mods/default/sounds/default_metal_footstep.1.ogg b/mods/default/sounds/default_metal_footstep.1.ogg new file mode 100644 index 0000000..841286b Binary files /dev/null and b/mods/default/sounds/default_metal_footstep.1.ogg differ diff --git a/mods/default/sounds/default_metal_footstep.2.ogg b/mods/default/sounds/default_metal_footstep.2.ogg new file mode 100644 index 0000000..aa61ed3 Binary files /dev/null and b/mods/default/sounds/default_metal_footstep.2.ogg differ diff --git a/mods/default/sounds/default_metal_footstep.3.ogg b/mods/default/sounds/default_metal_footstep.3.ogg new file mode 100644 index 0000000..4cc1ca4 Binary files /dev/null and b/mods/default/sounds/default_metal_footstep.3.ogg differ diff --git a/mods/default/sounds/default_place_node.1.ogg b/mods/default/sounds/default_place_node.1.ogg new file mode 100644 index 0000000..46b9756 Binary files /dev/null and b/mods/default/sounds/default_place_node.1.ogg differ diff --git a/mods/default/sounds/default_place_node.2.ogg b/mods/default/sounds/default_place_node.2.ogg new file mode 100644 index 0000000..d34c01a Binary files /dev/null and b/mods/default/sounds/default_place_node.2.ogg differ diff --git a/mods/default/sounds/default_place_node.3.ogg b/mods/default/sounds/default_place_node.3.ogg new file mode 100644 index 0000000..fc29365 Binary files /dev/null and b/mods/default/sounds/default_place_node.3.ogg differ diff --git a/mods/default/sounds/default_place_node_hard.1.ogg b/mods/default/sounds/default_place_node_hard.1.ogg new file mode 100644 index 0000000..9f97fac Binary files /dev/null and b/mods/default/sounds/default_place_node_hard.1.ogg differ diff --git a/mods/default/sounds/default_place_node_hard.2.ogg b/mods/default/sounds/default_place_node_hard.2.ogg new file mode 100644 index 0000000..1d3b3de Binary files /dev/null and b/mods/default/sounds/default_place_node_hard.2.ogg differ diff --git a/mods/default/sounds/default_place_node_metal.1.ogg b/mods/default/sounds/default_place_node_metal.1.ogg new file mode 100644 index 0000000..5da085e Binary files /dev/null and b/mods/default/sounds/default_place_node_metal.1.ogg differ diff --git a/mods/default/sounds/default_place_node_metal.2.ogg b/mods/default/sounds/default_place_node_metal.2.ogg new file mode 100644 index 0000000..5ee67fc Binary files /dev/null and b/mods/default/sounds/default_place_node_metal.2.ogg differ diff --git a/mods/default/sounds/default_sand_footstep.1.ogg b/mods/default/sounds/default_sand_footstep.1.ogg new file mode 100644 index 0000000..65b68c7 Binary files /dev/null and b/mods/default/sounds/default_sand_footstep.1.ogg differ diff --git a/mods/default/sounds/default_sand_footstep.2.ogg b/mods/default/sounds/default_sand_footstep.2.ogg new file mode 100644 index 0000000..57f35f3 Binary files /dev/null and b/mods/default/sounds/default_sand_footstep.2.ogg differ diff --git a/mods/default/sounds/default_snow_footstep.1.ogg b/mods/default/sounds/default_snow_footstep.1.ogg new file mode 100644 index 0000000..97cc825 Binary files /dev/null and b/mods/default/sounds/default_snow_footstep.1.ogg differ diff --git a/mods/default/sounds/default_snow_footstep.2.ogg b/mods/default/sounds/default_snow_footstep.2.ogg new file mode 100644 index 0000000..97a6baa Binary files /dev/null and b/mods/default/sounds/default_snow_footstep.2.ogg differ diff --git a/mods/default/sounds/default_snow_footstep.3.ogg b/mods/default/sounds/default_snow_footstep.3.ogg new file mode 100644 index 0000000..bde1f21 Binary files /dev/null and b/mods/default/sounds/default_snow_footstep.3.ogg differ diff --git a/mods/default/sounds/default_snow_footstep.4.ogg b/mods/default/sounds/default_snow_footstep.4.ogg new file mode 100644 index 0000000..8ca6a59 Binary files /dev/null and b/mods/default/sounds/default_snow_footstep.4.ogg differ diff --git a/mods/default/sounds/default_snow_footstep.5.ogg b/mods/default/sounds/default_snow_footstep.5.ogg new file mode 100644 index 0000000..220d60c Binary files /dev/null and b/mods/default/sounds/default_snow_footstep.5.ogg differ diff --git a/mods/default/sounds/default_tool_breaks.1.ogg b/mods/default/sounds/default_tool_breaks.1.ogg new file mode 100644 index 0000000..2a571ae Binary files /dev/null and b/mods/default/sounds/default_tool_breaks.1.ogg differ diff --git a/mods/default/sounds/default_tool_breaks.2.ogg b/mods/default/sounds/default_tool_breaks.2.ogg new file mode 100644 index 0000000..1789352 Binary files /dev/null and b/mods/default/sounds/default_tool_breaks.2.ogg differ diff --git a/mods/default/sounds/default_tool_breaks.3.ogg b/mods/default/sounds/default_tool_breaks.3.ogg new file mode 100644 index 0000000..a99c4b7 Binary files /dev/null and b/mods/default/sounds/default_tool_breaks.3.ogg differ diff --git a/mods/default/sounds/default_water_footstep.1.ogg b/mods/default/sounds/default_water_footstep.1.ogg new file mode 100644 index 0000000..63b9744 Binary files /dev/null and b/mods/default/sounds/default_water_footstep.1.ogg differ diff --git a/mods/default/sounds/default_water_footstep.2.ogg b/mods/default/sounds/default_water_footstep.2.ogg new file mode 100644 index 0000000..8d79c1f Binary files /dev/null and b/mods/default/sounds/default_water_footstep.2.ogg differ diff --git a/mods/default/sounds/default_water_footstep.3.ogg b/mods/default/sounds/default_water_footstep.3.ogg new file mode 100644 index 0000000..f889150 Binary files /dev/null and b/mods/default/sounds/default_water_footstep.3.ogg differ diff --git a/mods/default/sounds/default_water_footstep.4.ogg b/mods/default/sounds/default_water_footstep.4.ogg new file mode 100644 index 0000000..6f1eab8 Binary files /dev/null and b/mods/default/sounds/default_water_footstep.4.ogg differ diff --git a/mods/default/sounds/default_wood_footstep.1.ogg b/mods/default/sounds/default_wood_footstep.1.ogg new file mode 100644 index 0000000..34f63a1 Binary files /dev/null and b/mods/default/sounds/default_wood_footstep.1.ogg differ diff --git a/mods/default/sounds/default_wood_footstep.2.ogg b/mods/default/sounds/default_wood_footstep.2.ogg new file mode 100644 index 0000000..124fc29 Binary files /dev/null and b/mods/default/sounds/default_wood_footstep.2.ogg differ diff --git a/mods/default/sounds/player_damage.ogg b/mods/default/sounds/player_damage.ogg new file mode 100644 index 0000000..7888087 Binary files /dev/null and b/mods/default/sounds/player_damage.ogg differ diff --git a/mods/default/textures/bubble.png b/mods/default/textures/bubble.png new file mode 100644 index 0000000..30170d2 Binary files /dev/null and b/mods/default/textures/bubble.png differ diff --git a/mods/default/textures/crack_anylength.png b/mods/default/textures/crack_anylength.png new file mode 100644 index 0000000..297eced Binary files /dev/null and b/mods/default/textures/crack_anylength.png differ diff --git a/mods/default/textures/default_acacia_bush_sapling.png b/mods/default/textures/default_acacia_bush_sapling.png new file mode 100644 index 0000000..940b3aa Binary files /dev/null and b/mods/default/textures/default_acacia_bush_sapling.png differ diff --git a/mods/default/textures/default_acacia_bush_stem.png b/mods/default/textures/default_acacia_bush_stem.png new file mode 100644 index 0000000..2903915 Binary files /dev/null and b/mods/default/textures/default_acacia_bush_stem.png differ diff --git a/mods/default/textures/default_acacia_leaves.png b/mods/default/textures/default_acacia_leaves.png new file mode 100644 index 0000000..626e1b3 Binary files /dev/null and b/mods/default/textures/default_acacia_leaves.png differ diff --git a/mods/default/textures/default_acacia_leaves_simple.png b/mods/default/textures/default_acacia_leaves_simple.png new file mode 100644 index 0000000..3c7015b Binary files /dev/null and b/mods/default/textures/default_acacia_leaves_simple.png differ diff --git a/mods/default/textures/default_acacia_sapling.png b/mods/default/textures/default_acacia_sapling.png new file mode 100644 index 0000000..07170a0 Binary files /dev/null and b/mods/default/textures/default_acacia_sapling.png differ diff --git a/mods/default/textures/default_acacia_tree.png b/mods/default/textures/default_acacia_tree.png new file mode 100644 index 0000000..58bb3c4 Binary files /dev/null and b/mods/default/textures/default_acacia_tree.png differ diff --git a/mods/default/textures/default_acacia_tree_top.png b/mods/default/textures/default_acacia_tree_top.png new file mode 100644 index 0000000..a8a0ce0 Binary files /dev/null and b/mods/default/textures/default_acacia_tree_top.png differ diff --git a/mods/default/textures/default_acacia_wood.png b/mods/default/textures/default_acacia_wood.png new file mode 100644 index 0000000..b5abf1e Binary files /dev/null and b/mods/default/textures/default_acacia_wood.png differ diff --git a/mods/default/textures/default_apple.png b/mods/default/textures/default_apple.png new file mode 100644 index 0000000..7549bfd Binary files /dev/null and b/mods/default/textures/default_apple.png differ diff --git a/mods/default/textures/default_aspen_leaves.png b/mods/default/textures/default_aspen_leaves.png new file mode 100644 index 0000000..7306423 Binary files /dev/null and b/mods/default/textures/default_aspen_leaves.png differ diff --git a/mods/default/textures/default_aspen_sapling.png b/mods/default/textures/default_aspen_sapling.png new file mode 100644 index 0000000..f8d9136 Binary files /dev/null and b/mods/default/textures/default_aspen_sapling.png differ diff --git a/mods/default/textures/default_aspen_tree.png b/mods/default/textures/default_aspen_tree.png new file mode 100644 index 0000000..cfb05fc Binary files /dev/null and b/mods/default/textures/default_aspen_tree.png differ diff --git a/mods/default/textures/default_aspen_tree_top.png b/mods/default/textures/default_aspen_tree_top.png new file mode 100644 index 0000000..fcca038 Binary files /dev/null and b/mods/default/textures/default_aspen_tree_top.png differ diff --git a/mods/default/textures/default_aspen_wood.png b/mods/default/textures/default_aspen_wood.png new file mode 100644 index 0000000..2b584b3 Binary files /dev/null and b/mods/default/textures/default_aspen_wood.png differ diff --git a/mods/default/textures/default_blueberries.png b/mods/default/textures/default_blueberries.png new file mode 100644 index 0000000..1dbb0d6 Binary files /dev/null and b/mods/default/textures/default_blueberries.png differ diff --git a/mods/default/textures/default_blueberry_bush_leaves.png b/mods/default/textures/default_blueberry_bush_leaves.png new file mode 100644 index 0000000..2cd112c Binary files /dev/null and b/mods/default/textures/default_blueberry_bush_leaves.png differ diff --git a/mods/default/textures/default_blueberry_bush_sapling.png b/mods/default/textures/default_blueberry_bush_sapling.png new file mode 100644 index 0000000..5d7393f Binary files /dev/null and b/mods/default/textures/default_blueberry_bush_sapling.png differ diff --git a/mods/default/textures/default_blueberry_overlay.png b/mods/default/textures/default_blueberry_overlay.png new file mode 100644 index 0000000..de9de62 Binary files /dev/null and b/mods/default/textures/default_blueberry_overlay.png differ diff --git a/mods/default/textures/default_book.png b/mods/default/textures/default_book.png new file mode 100644 index 0000000..bcf1e6a Binary files /dev/null and b/mods/default/textures/default_book.png differ diff --git a/mods/default/textures/default_book_written.png b/mods/default/textures/default_book_written.png new file mode 100644 index 0000000..f23d122 Binary files /dev/null and b/mods/default/textures/default_book_written.png differ diff --git a/mods/default/textures/default_bookshelf.png b/mods/default/textures/default_bookshelf.png new file mode 100644 index 0000000..10d6483 Binary files /dev/null and b/mods/default/textures/default_bookshelf.png differ diff --git a/mods/default/textures/default_bookshelf_slot.png b/mods/default/textures/default_bookshelf_slot.png new file mode 100644 index 0000000..cd2c8bc Binary files /dev/null and b/mods/default/textures/default_bookshelf_slot.png differ diff --git a/mods/default/textures/default_brick.png b/mods/default/textures/default_brick.png new file mode 100644 index 0000000..ab19121 Binary files /dev/null and b/mods/default/textures/default_brick.png differ diff --git a/mods/default/textures/default_bronze_block.png b/mods/default/textures/default_bronze_block.png new file mode 100644 index 0000000..1d0c9d5 Binary files /dev/null and b/mods/default/textures/default_bronze_block.png differ diff --git a/mods/default/textures/default_bronze_ingot.png b/mods/default/textures/default_bronze_ingot.png new file mode 100644 index 0000000..6cccdf6 Binary files /dev/null and b/mods/default/textures/default_bronze_ingot.png differ diff --git a/mods/default/textures/default_bush_sapling.png b/mods/default/textures/default_bush_sapling.png new file mode 100644 index 0000000..905ba4b Binary files /dev/null and b/mods/default/textures/default_bush_sapling.png differ diff --git a/mods/default/textures/default_bush_stem.png b/mods/default/textures/default_bush_stem.png new file mode 100644 index 0000000..18b615f Binary files /dev/null and b/mods/default/textures/default_bush_stem.png differ diff --git a/mods/default/textures/default_cactus_side.png b/mods/default/textures/default_cactus_side.png new file mode 100644 index 0000000..8d6c40c Binary files /dev/null and b/mods/default/textures/default_cactus_side.png differ diff --git a/mods/default/textures/default_cactus_top.png b/mods/default/textures/default_cactus_top.png new file mode 100644 index 0000000..cf46aa2 Binary files /dev/null and b/mods/default/textures/default_cactus_top.png differ diff --git a/mods/default/textures/default_chest_front.png b/mods/default/textures/default_chest_front.png new file mode 100644 index 0000000..85227d8 Binary files /dev/null and b/mods/default/textures/default_chest_front.png differ diff --git a/mods/default/textures/default_chest_inside.png b/mods/default/textures/default_chest_inside.png new file mode 100644 index 0000000..5f7b6b1 Binary files /dev/null and b/mods/default/textures/default_chest_inside.png differ diff --git a/mods/default/textures/default_chest_lock.png b/mods/default/textures/default_chest_lock.png new file mode 100644 index 0000000..73f46c7 Binary files /dev/null and b/mods/default/textures/default_chest_lock.png differ diff --git a/mods/default/textures/default_chest_side.png b/mods/default/textures/default_chest_side.png new file mode 100644 index 0000000..44a65a4 Binary files /dev/null and b/mods/default/textures/default_chest_side.png differ diff --git a/mods/default/textures/default_chest_top.png b/mods/default/textures/default_chest_top.png new file mode 100644 index 0000000..f4a92ee Binary files /dev/null and b/mods/default/textures/default_chest_top.png differ diff --git a/mods/default/textures/default_clay.png b/mods/default/textures/default_clay.png new file mode 100644 index 0000000..76e5a40 Binary files /dev/null and b/mods/default/textures/default_clay.png differ diff --git a/mods/default/textures/default_clay_brick.png b/mods/default/textures/default_clay_brick.png new file mode 100644 index 0000000..b288ef0 Binary files /dev/null and b/mods/default/textures/default_clay_brick.png differ diff --git a/mods/default/textures/default_clay_lump.png b/mods/default/textures/default_clay_lump.png new file mode 100644 index 0000000..c1d0220 Binary files /dev/null and b/mods/default/textures/default_clay_lump.png differ diff --git a/mods/default/textures/default_cloud.png b/mods/default/textures/default_cloud.png new file mode 100644 index 0000000..faf0ec1 Binary files /dev/null and b/mods/default/textures/default_cloud.png differ diff --git a/mods/default/textures/default_coal_block.png b/mods/default/textures/default_coal_block.png new file mode 100644 index 0000000..6fe9ed9 Binary files /dev/null and b/mods/default/textures/default_coal_block.png differ diff --git a/mods/default/textures/default_coal_lump.png b/mods/default/textures/default_coal_lump.png new file mode 100644 index 0000000..792961d Binary files /dev/null and b/mods/default/textures/default_coal_lump.png differ diff --git a/mods/default/textures/default_cobble.png b/mods/default/textures/default_cobble.png new file mode 100644 index 0000000..d379840 Binary files /dev/null and b/mods/default/textures/default_cobble.png differ diff --git a/mods/default/textures/default_coniferous_litter.png b/mods/default/textures/default_coniferous_litter.png new file mode 100644 index 0000000..da340e0 Binary files /dev/null and b/mods/default/textures/default_coniferous_litter.png differ diff --git a/mods/default/textures/default_coniferous_litter_side.png b/mods/default/textures/default_coniferous_litter_side.png new file mode 100644 index 0000000..0701461 Binary files /dev/null and b/mods/default/textures/default_coniferous_litter_side.png differ diff --git a/mods/default/textures/default_copper_block.png b/mods/default/textures/default_copper_block.png new file mode 100644 index 0000000..8533754 Binary files /dev/null and b/mods/default/textures/default_copper_block.png differ diff --git a/mods/default/textures/default_copper_ingot.png b/mods/default/textures/default_copper_ingot.png new file mode 100644 index 0000000..bcad9c0 Binary files /dev/null and b/mods/default/textures/default_copper_ingot.png differ diff --git a/mods/default/textures/default_copper_lump.png b/mods/default/textures/default_copper_lump.png new file mode 100644 index 0000000..998c592 Binary files /dev/null and b/mods/default/textures/default_copper_lump.png differ diff --git a/mods/default/textures/default_coral_brown.png b/mods/default/textures/default_coral_brown.png new file mode 100644 index 0000000..8a775fe Binary files /dev/null and b/mods/default/textures/default_coral_brown.png differ diff --git a/mods/default/textures/default_coral_cyan.png b/mods/default/textures/default_coral_cyan.png new file mode 100644 index 0000000..11cc7bf Binary files /dev/null and b/mods/default/textures/default_coral_cyan.png differ diff --git a/mods/default/textures/default_coral_green.png b/mods/default/textures/default_coral_green.png new file mode 100644 index 0000000..847c572 Binary files /dev/null and b/mods/default/textures/default_coral_green.png differ diff --git a/mods/default/textures/default_coral_orange.png b/mods/default/textures/default_coral_orange.png new file mode 100644 index 0000000..cefac62 Binary files /dev/null and b/mods/default/textures/default_coral_orange.png differ diff --git a/mods/default/textures/default_coral_pink.png b/mods/default/textures/default_coral_pink.png new file mode 100644 index 0000000..62d70c6 Binary files /dev/null and b/mods/default/textures/default_coral_pink.png differ diff --git a/mods/default/textures/default_coral_skeleton.png b/mods/default/textures/default_coral_skeleton.png new file mode 100644 index 0000000..fa48f15 Binary files /dev/null and b/mods/default/textures/default_coral_skeleton.png differ diff --git a/mods/default/textures/default_desert_cobble.png b/mods/default/textures/default_desert_cobble.png new file mode 100644 index 0000000..fa1af5d Binary files /dev/null and b/mods/default/textures/default_desert_cobble.png differ diff --git a/mods/default/textures/default_desert_sand.png b/mods/default/textures/default_desert_sand.png new file mode 100644 index 0000000..371b8c7 Binary files /dev/null and b/mods/default/textures/default_desert_sand.png differ diff --git a/mods/default/textures/default_desert_sandstone.png b/mods/default/textures/default_desert_sandstone.png new file mode 100644 index 0000000..52e445f 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 0000000..8fc54e7 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 0000000..ab58db5 Binary files /dev/null and b/mods/default/textures/default_desert_sandstone_brick.png differ diff --git a/mods/default/textures/default_desert_stone.png b/mods/default/textures/default_desert_stone.png new file mode 100644 index 0000000..5d3aded Binary files /dev/null and b/mods/default/textures/default_desert_stone.png differ diff --git a/mods/default/textures/default_desert_stone_block.png b/mods/default/textures/default_desert_stone_block.png new file mode 100644 index 0000000..9eb8e92 Binary files /dev/null and b/mods/default/textures/default_desert_stone_block.png differ diff --git a/mods/default/textures/default_desert_stone_brick.png b/mods/default/textures/default_desert_stone_brick.png new file mode 100644 index 0000000..a603d18 Binary files /dev/null and b/mods/default/textures/default_desert_stone_brick.png differ diff --git a/mods/default/textures/default_diamond.png b/mods/default/textures/default_diamond.png new file mode 100644 index 0000000..a8dac74 Binary files /dev/null and b/mods/default/textures/default_diamond.png differ diff --git a/mods/default/textures/default_diamond_block.png b/mods/default/textures/default_diamond_block.png new file mode 100644 index 0000000..20c33ed Binary files /dev/null and b/mods/default/textures/default_diamond_block.png differ diff --git a/mods/default/textures/default_dirt.png b/mods/default/textures/default_dirt.png new file mode 100644 index 0000000..afe4a2e Binary files /dev/null and b/mods/default/textures/default_dirt.png differ diff --git a/mods/default/textures/default_dry_dirt.png b/mods/default/textures/default_dry_dirt.png new file mode 100644 index 0000000..8ee5398 Binary files /dev/null and b/mods/default/textures/default_dry_dirt.png differ diff --git a/mods/default/textures/default_dry_grass.png b/mods/default/textures/default_dry_grass.png new file mode 100644 index 0000000..03455c3 Binary files /dev/null and b/mods/default/textures/default_dry_grass.png differ diff --git a/mods/default/textures/default_dry_grass_1.png b/mods/default/textures/default_dry_grass_1.png new file mode 100644 index 0000000..5cf68a3 Binary files /dev/null and b/mods/default/textures/default_dry_grass_1.png differ diff --git a/mods/default/textures/default_dry_grass_2.png b/mods/default/textures/default_dry_grass_2.png new file mode 100644 index 0000000..c925ace Binary files /dev/null and b/mods/default/textures/default_dry_grass_2.png differ diff --git a/mods/default/textures/default_dry_grass_3.png b/mods/default/textures/default_dry_grass_3.png new file mode 100644 index 0000000..4e4d84e Binary files /dev/null and b/mods/default/textures/default_dry_grass_3.png differ diff --git a/mods/default/textures/default_dry_grass_4.png b/mods/default/textures/default_dry_grass_4.png new file mode 100644 index 0000000..d315849 Binary files /dev/null and b/mods/default/textures/default_dry_grass_4.png differ diff --git a/mods/default/textures/default_dry_grass_5.png b/mods/default/textures/default_dry_grass_5.png new file mode 100644 index 0000000..871d04c Binary files /dev/null and b/mods/default/textures/default_dry_grass_5.png differ diff --git a/mods/default/textures/default_dry_grass_side.png b/mods/default/textures/default_dry_grass_side.png new file mode 100644 index 0000000..ef375b7 Binary files /dev/null and b/mods/default/textures/default_dry_grass_side.png differ diff --git a/mods/default/textures/default_dry_shrub.png b/mods/default/textures/default_dry_shrub.png new file mode 100644 index 0000000..82c9cc5 Binary files /dev/null and b/mods/default/textures/default_dry_shrub.png differ diff --git a/mods/default/textures/default_emergent_jungle_sapling.png b/mods/default/textures/default_emergent_jungle_sapling.png new file mode 100644 index 0000000..b363b3c Binary files /dev/null and b/mods/default/textures/default_emergent_jungle_sapling.png differ diff --git a/mods/default/textures/default_fence_acacia_wood.png b/mods/default/textures/default_fence_acacia_wood.png new file mode 100644 index 0000000..3b973f3 Binary files /dev/null and b/mods/default/textures/default_fence_acacia_wood.png differ diff --git a/mods/default/textures/default_fence_aspen_wood.png b/mods/default/textures/default_fence_aspen_wood.png new file mode 100644 index 0000000..0a6558e Binary files /dev/null and b/mods/default/textures/default_fence_aspen_wood.png differ diff --git a/mods/default/textures/default_fence_junglewood.png b/mods/default/textures/default_fence_junglewood.png new file mode 100644 index 0000000..c390941 Binary files /dev/null and b/mods/default/textures/default_fence_junglewood.png differ diff --git a/mods/default/textures/default_fence_overlay.png b/mods/default/textures/default_fence_overlay.png new file mode 100644 index 0000000..718184c Binary files /dev/null and b/mods/default/textures/default_fence_overlay.png differ diff --git a/mods/default/textures/default_fence_pine_wood.png b/mods/default/textures/default_fence_pine_wood.png new file mode 100644 index 0000000..74609d9 Binary files /dev/null and b/mods/default/textures/default_fence_pine_wood.png differ diff --git a/mods/default/textures/default_fence_rail_acacia_wood.png b/mods/default/textures/default_fence_rail_acacia_wood.png new file mode 100644 index 0000000..64dc90f Binary files /dev/null and b/mods/default/textures/default_fence_rail_acacia_wood.png differ diff --git a/mods/default/textures/default_fence_rail_aspen_wood.png b/mods/default/textures/default_fence_rail_aspen_wood.png new file mode 100644 index 0000000..ab16a60 Binary files /dev/null and b/mods/default/textures/default_fence_rail_aspen_wood.png differ diff --git a/mods/default/textures/default_fence_rail_junglewood.png b/mods/default/textures/default_fence_rail_junglewood.png new file mode 100644 index 0000000..ebc1ef0 Binary files /dev/null and b/mods/default/textures/default_fence_rail_junglewood.png differ diff --git a/mods/default/textures/default_fence_rail_overlay.png b/mods/default/textures/default_fence_rail_overlay.png new file mode 100644 index 0000000..4da47ae Binary files /dev/null and b/mods/default/textures/default_fence_rail_overlay.png differ diff --git a/mods/default/textures/default_fence_rail_pine_wood.png b/mods/default/textures/default_fence_rail_pine_wood.png new file mode 100644 index 0000000..fd8d99d Binary files /dev/null and b/mods/default/textures/default_fence_rail_pine_wood.png differ diff --git a/mods/default/textures/default_fence_rail_wood.png b/mods/default/textures/default_fence_rail_wood.png new file mode 100644 index 0000000..f84b755 Binary files /dev/null and b/mods/default/textures/default_fence_rail_wood.png differ diff --git a/mods/default/textures/default_fence_wood.png b/mods/default/textures/default_fence_wood.png new file mode 100644 index 0000000..1e76430 Binary files /dev/null and b/mods/default/textures/default_fence_wood.png differ diff --git a/mods/default/textures/default_fern_1.png b/mods/default/textures/default_fern_1.png new file mode 100644 index 0000000..b307986 Binary files /dev/null and b/mods/default/textures/default_fern_1.png differ diff --git a/mods/default/textures/default_fern_2.png b/mods/default/textures/default_fern_2.png new file mode 100644 index 0000000..6c5f7d5 Binary files /dev/null and b/mods/default/textures/default_fern_2.png differ diff --git a/mods/default/textures/default_fern_3.png b/mods/default/textures/default_fern_3.png new file mode 100644 index 0000000..2c1f605 Binary files /dev/null and b/mods/default/textures/default_fern_3.png differ diff --git a/mods/default/textures/default_flint.png b/mods/default/textures/default_flint.png new file mode 100644 index 0000000..226c740 Binary files /dev/null and b/mods/default/textures/default_flint.png differ diff --git a/mods/default/textures/default_footprint.png b/mods/default/textures/default_footprint.png new file mode 100644 index 0000000..41d9546 Binary files /dev/null and b/mods/default/textures/default_footprint.png differ diff --git a/mods/default/textures/default_furnace_bottom.png b/mods/default/textures/default_furnace_bottom.png new file mode 100644 index 0000000..b79ed06 Binary files /dev/null and b/mods/default/textures/default_furnace_bottom.png differ diff --git a/mods/default/textures/default_furnace_fire_bg.png b/mods/default/textures/default_furnace_fire_bg.png new file mode 100644 index 0000000..126204a Binary files /dev/null and b/mods/default/textures/default_furnace_fire_bg.png differ diff --git a/mods/default/textures/default_furnace_fire_fg.png b/mods/default/textures/default_furnace_fire_fg.png new file mode 100644 index 0000000..63888f3 Binary files /dev/null and b/mods/default/textures/default_furnace_fire_fg.png differ diff --git a/mods/default/textures/default_furnace_front.png b/mods/default/textures/default_furnace_front.png new file mode 100644 index 0000000..8c1798e Binary files /dev/null and b/mods/default/textures/default_furnace_front.png differ diff --git a/mods/default/textures/default_furnace_front_active.png b/mods/default/textures/default_furnace_front_active.png new file mode 100644 index 0000000..ea43ed9 Binary files /dev/null and b/mods/default/textures/default_furnace_front_active.png differ diff --git a/mods/default/textures/default_furnace_side.png b/mods/default/textures/default_furnace_side.png new file mode 100644 index 0000000..33408cf Binary files /dev/null and b/mods/default/textures/default_furnace_side.png differ diff --git a/mods/default/textures/default_furnace_top.png b/mods/default/textures/default_furnace_top.png new file mode 100644 index 0000000..b79ed06 Binary files /dev/null and b/mods/default/textures/default_furnace_top.png differ diff --git a/mods/default/textures/default_glass.png b/mods/default/textures/default_glass.png new file mode 100644 index 0000000..74d6a02 Binary files /dev/null and b/mods/default/textures/default_glass.png differ diff --git a/mods/default/textures/default_glass_detail.png b/mods/default/textures/default_glass_detail.png new file mode 100644 index 0000000..811a4db Binary files /dev/null and b/mods/default/textures/default_glass_detail.png differ diff --git a/mods/default/textures/default_gold_block.png b/mods/default/textures/default_gold_block.png new file mode 100644 index 0000000..170d50b Binary files /dev/null and b/mods/default/textures/default_gold_block.png differ diff --git a/mods/default/textures/default_gold_ingot.png b/mods/default/textures/default_gold_ingot.png new file mode 100644 index 0000000..ba66471 Binary files /dev/null and b/mods/default/textures/default_gold_ingot.png differ diff --git a/mods/default/textures/default_gold_lump.png b/mods/default/textures/default_gold_lump.png new file mode 100644 index 0000000..d5a1be7 Binary files /dev/null and b/mods/default/textures/default_gold_lump.png differ diff --git a/mods/default/textures/default_grass.png b/mods/default/textures/default_grass.png new file mode 100644 index 0000000..5778caa Binary files /dev/null and b/mods/default/textures/default_grass.png differ diff --git a/mods/default/textures/default_grass_1.png b/mods/default/textures/default_grass_1.png new file mode 100644 index 0000000..e9faa2c Binary files /dev/null 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 new file mode 100644 index 0000000..03729a0 Binary files /dev/null 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 new file mode 100644 index 0000000..92ca1b5 Binary files /dev/null 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 new file mode 100644 index 0000000..c782a33 Binary files /dev/null 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 new file mode 100644 index 0000000..b727e9c Binary files /dev/null and b/mods/default/textures/default_grass_5.png differ diff --git a/mods/default/textures/default_grass_side.png b/mods/default/textures/default_grass_side.png new file mode 100644 index 0000000..079d96a Binary files /dev/null and b/mods/default/textures/default_grass_side.png differ diff --git a/mods/default/textures/default_gravel.png b/mods/default/textures/default_gravel.png new file mode 100644 index 0000000..8852d38 Binary files /dev/null and b/mods/default/textures/default_gravel.png differ diff --git a/mods/default/textures/default_ice.png b/mods/default/textures/default_ice.png new file mode 100644 index 0000000..2874e1e Binary files /dev/null and b/mods/default/textures/default_ice.png differ diff --git a/mods/default/textures/default_iron_lump.png b/mods/default/textures/default_iron_lump.png new file mode 100644 index 0000000..db61a94 Binary files /dev/null and b/mods/default/textures/default_iron_lump.png differ diff --git a/mods/default/textures/default_item_smoke.png b/mods/default/textures/default_item_smoke.png new file mode 100644 index 0000000..d62fb3b Binary files /dev/null and b/mods/default/textures/default_item_smoke.png differ diff --git a/mods/default/textures/default_junglegrass.png b/mods/default/textures/default_junglegrass.png new file mode 100644 index 0000000..25abb71 Binary files /dev/null and b/mods/default/textures/default_junglegrass.png differ diff --git a/mods/default/textures/default_jungleleaves.png b/mods/default/textures/default_jungleleaves.png new file mode 100644 index 0000000..5afcc36 Binary files /dev/null and b/mods/default/textures/default_jungleleaves.png differ diff --git a/mods/default/textures/default_jungleleaves_simple.png b/mods/default/textures/default_jungleleaves_simple.png new file mode 100644 index 0000000..7165100 Binary files /dev/null and b/mods/default/textures/default_jungleleaves_simple.png differ diff --git a/mods/default/textures/default_junglesapling.png b/mods/default/textures/default_junglesapling.png new file mode 100644 index 0000000..05e1e50 Binary files /dev/null and b/mods/default/textures/default_junglesapling.png differ diff --git a/mods/default/textures/default_jungletree.png b/mods/default/textures/default_jungletree.png new file mode 100644 index 0000000..2cf77a6 Binary files /dev/null and b/mods/default/textures/default_jungletree.png differ diff --git a/mods/default/textures/default_jungletree_top.png b/mods/default/textures/default_jungletree_top.png new file mode 100644 index 0000000..439f078 Binary files /dev/null and b/mods/default/textures/default_jungletree_top.png differ diff --git a/mods/default/textures/default_junglewood.png b/mods/default/textures/default_junglewood.png new file mode 100644 index 0000000..8d17917 Binary files /dev/null and b/mods/default/textures/default_junglewood.png differ diff --git a/mods/default/textures/default_kelp.png b/mods/default/textures/default_kelp.png new file mode 100644 index 0000000..70b743d Binary files /dev/null and b/mods/default/textures/default_kelp.png differ diff --git a/mods/default/textures/default_key.png b/mods/default/textures/default_key.png new file mode 100644 index 0000000..783d313 Binary files /dev/null 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 new file mode 100644 index 0000000..2b3497d Binary files /dev/null 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 new file mode 100644 index 0000000..a312f3e Binary files /dev/null and b/mods/default/textures/default_ladder_steel.png differ diff --git a/mods/default/textures/default_ladder_wood.png b/mods/default/textures/default_ladder_wood.png new file mode 100644 index 0000000..c167fff Binary files /dev/null and b/mods/default/textures/default_ladder_wood.png differ diff --git a/mods/default/textures/default_large_cactus_seedling.png b/mods/default/textures/default_large_cactus_seedling.png new file mode 100644 index 0000000..378351a Binary files /dev/null and b/mods/default/textures/default_large_cactus_seedling.png differ diff --git a/mods/default/textures/default_lava.png b/mods/default/textures/default_lava.png new file mode 100644 index 0000000..e8958de Binary files /dev/null and b/mods/default/textures/default_lava.png differ diff --git a/mods/default/textures/default_lava_flowing_animated.png b/mods/default/textures/default_lava_flowing_animated.png new file mode 100644 index 0000000..2ec0746 Binary files /dev/null and b/mods/default/textures/default_lava_flowing_animated.png differ diff --git a/mods/default/textures/default_lava_source_animated.png b/mods/default/textures/default_lava_source_animated.png new file mode 100644 index 0000000..32267a6 Binary files /dev/null and b/mods/default/textures/default_lava_source_animated.png differ diff --git a/mods/default/textures/default_leaves.png b/mods/default/textures/default_leaves.png new file mode 100644 index 0000000..ba09fe1 Binary files /dev/null and b/mods/default/textures/default_leaves.png differ diff --git a/mods/default/textures/default_leaves_simple.png b/mods/default/textures/default_leaves_simple.png new file mode 100644 index 0000000..eb60f9f Binary files /dev/null and b/mods/default/textures/default_leaves_simple.png differ diff --git a/mods/default/textures/default_marram_grass_1.png b/mods/default/textures/default_marram_grass_1.png new file mode 100644 index 0000000..73ec9e9 Binary files /dev/null and b/mods/default/textures/default_marram_grass_1.png differ diff --git a/mods/default/textures/default_marram_grass_2.png b/mods/default/textures/default_marram_grass_2.png new file mode 100644 index 0000000..2db75c7 Binary files /dev/null and b/mods/default/textures/default_marram_grass_2.png differ diff --git a/mods/default/textures/default_marram_grass_3.png b/mods/default/textures/default_marram_grass_3.png new file mode 100644 index 0000000..f6c155f Binary files /dev/null and b/mods/default/textures/default_marram_grass_3.png differ diff --git a/mods/default/textures/default_mese_block.png b/mods/default/textures/default_mese_block.png new file mode 100644 index 0000000..e30994e Binary files /dev/null and b/mods/default/textures/default_mese_block.png differ diff --git a/mods/default/textures/default_mese_crystal.png b/mods/default/textures/default_mese_crystal.png new file mode 100644 index 0000000..f1d71f1 Binary files /dev/null and b/mods/default/textures/default_mese_crystal.png differ diff --git a/mods/default/textures/default_mese_crystal_fragment.png b/mods/default/textures/default_mese_crystal_fragment.png new file mode 100644 index 0000000..d5416ab Binary files /dev/null and b/mods/default/textures/default_mese_crystal_fragment.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 0000000..c23b551 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 0000000..c4fc7ce 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 0000000..365c1a7 Binary files /dev/null and b/mods/default/textures/default_mese_post_light_top.png differ diff --git a/mods/default/textures/default_meselamp.png b/mods/default/textures/default_meselamp.png new file mode 100644 index 0000000..0c3a1a1 Binary files /dev/null and b/mods/default/textures/default_meselamp.png differ diff --git a/mods/default/textures/default_mineral_coal.png b/mods/default/textures/default_mineral_coal.png new file mode 100644 index 0000000..6d1386b Binary files /dev/null and b/mods/default/textures/default_mineral_coal.png differ diff --git a/mods/default/textures/default_mineral_copper.png b/mods/default/textures/default_mineral_copper.png new file mode 100644 index 0000000..c4c518e Binary files /dev/null and b/mods/default/textures/default_mineral_copper.png differ diff --git a/mods/default/textures/default_mineral_diamond.png b/mods/default/textures/default_mineral_diamond.png new file mode 100644 index 0000000..39c0f83 Binary files /dev/null and b/mods/default/textures/default_mineral_diamond.png differ diff --git a/mods/default/textures/default_mineral_gold.png b/mods/default/textures/default_mineral_gold.png new file mode 100644 index 0000000..2220add Binary files /dev/null and b/mods/default/textures/default_mineral_gold.png differ diff --git a/mods/default/textures/default_mineral_iron.png b/mods/default/textures/default_mineral_iron.png new file mode 100644 index 0000000..bfec8b1 Binary files /dev/null and b/mods/default/textures/default_mineral_iron.png differ diff --git a/mods/default/textures/default_mineral_mese.png b/mods/default/textures/default_mineral_mese.png new file mode 100644 index 0000000..6952670 Binary files /dev/null and b/mods/default/textures/default_mineral_mese.png differ diff --git a/mods/default/textures/default_mineral_tin.png b/mods/default/textures/default_mineral_tin.png new file mode 100644 index 0000000..232d4b5 Binary files /dev/null and b/mods/default/textures/default_mineral_tin.png differ diff --git a/mods/default/textures/default_moss.png b/mods/default/textures/default_moss.png new file mode 100644 index 0000000..479038e Binary files /dev/null and b/mods/default/textures/default_moss.png differ diff --git a/mods/default/textures/default_moss_side.png b/mods/default/textures/default_moss_side.png new file mode 100644 index 0000000..4a20345 Binary files /dev/null and b/mods/default/textures/default_moss_side.png differ diff --git a/mods/default/textures/default_mossycobble.png b/mods/default/textures/default_mossycobble.png new file mode 100644 index 0000000..1ae7c91 Binary files /dev/null and b/mods/default/textures/default_mossycobble.png differ diff --git a/mods/default/textures/default_obsidian.png b/mods/default/textures/default_obsidian.png new file mode 100644 index 0000000..8f4a49c Binary files /dev/null and b/mods/default/textures/default_obsidian.png differ diff --git a/mods/default/textures/default_obsidian_block.png b/mods/default/textures/default_obsidian_block.png new file mode 100644 index 0000000..7e1d4d3 Binary files /dev/null and b/mods/default/textures/default_obsidian_block.png differ diff --git a/mods/default/textures/default_obsidian_brick.png b/mods/default/textures/default_obsidian_brick.png new file mode 100644 index 0000000..30c67ca Binary files /dev/null and b/mods/default/textures/default_obsidian_brick.png differ diff --git a/mods/default/textures/default_obsidian_glass.png b/mods/default/textures/default_obsidian_glass.png new file mode 100644 index 0000000..d5ac83d Binary files /dev/null and b/mods/default/textures/default_obsidian_glass.png differ diff --git a/mods/default/textures/default_obsidian_glass_detail.png b/mods/default/textures/default_obsidian_glass_detail.png new file mode 100644 index 0000000..a8bbec9 Binary files /dev/null and b/mods/default/textures/default_obsidian_glass_detail.png differ diff --git a/mods/default/textures/default_obsidian_shard.png b/mods/default/textures/default_obsidian_shard.png new file mode 100644 index 0000000..a988d8c Binary files /dev/null and b/mods/default/textures/default_obsidian_shard.png differ diff --git a/mods/default/textures/default_paper.png b/mods/default/textures/default_paper.png new file mode 100644 index 0000000..8f23924 Binary files /dev/null and b/mods/default/textures/default_paper.png differ diff --git a/mods/default/textures/default_papyrus.png b/mods/default/textures/default_papyrus.png new file mode 100644 index 0000000..a85e809 Binary files /dev/null and b/mods/default/textures/default_papyrus.png differ diff --git a/mods/default/textures/default_permafrost.png b/mods/default/textures/default_permafrost.png new file mode 100644 index 0000000..6f2567e Binary files /dev/null and b/mods/default/textures/default_permafrost.png differ diff --git a/mods/default/textures/default_pine_bush_sapling.png b/mods/default/textures/default_pine_bush_sapling.png new file mode 100644 index 0000000..fadeff8 Binary files /dev/null and b/mods/default/textures/default_pine_bush_sapling.png differ diff --git a/mods/default/textures/default_pine_bush_stem.png b/mods/default/textures/default_pine_bush_stem.png new file mode 100644 index 0000000..e239f81 Binary files /dev/null and b/mods/default/textures/default_pine_bush_stem.png differ diff --git a/mods/default/textures/default_pine_needles.png b/mods/default/textures/default_pine_needles.png new file mode 100644 index 0000000..f699727 Binary files /dev/null and b/mods/default/textures/default_pine_needles.png differ diff --git a/mods/default/textures/default_pine_sapling.png b/mods/default/textures/default_pine_sapling.png new file mode 100644 index 0000000..c30131d Binary files /dev/null and b/mods/default/textures/default_pine_sapling.png differ diff --git a/mods/default/textures/default_pine_tree.png b/mods/default/textures/default_pine_tree.png new file mode 100644 index 0000000..4a5328f Binary files /dev/null and b/mods/default/textures/default_pine_tree.png differ diff --git a/mods/default/textures/default_pine_tree_top.png b/mods/default/textures/default_pine_tree_top.png new file mode 100644 index 0000000..8705710 Binary files /dev/null and b/mods/default/textures/default_pine_tree_top.png differ diff --git a/mods/default/textures/default_pine_wood.png b/mods/default/textures/default_pine_wood.png new file mode 100644 index 0000000..6844ceb Binary files /dev/null and b/mods/default/textures/default_pine_wood.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 0000000..d762deb 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 0000000..7ccb11d Binary files /dev/null and b/mods/default/textures/default_rainforest_litter_side.png differ diff --git a/mods/default/textures/default_river_water.png b/mods/default/textures/default_river_water.png new file mode 100644 index 0000000..3b55c5f Binary files /dev/null and b/mods/default/textures/default_river_water.png differ diff --git a/mods/default/textures/default_river_water_flowing_animated.png b/mods/default/textures/default_river_water_flowing_animated.png new file mode 100644 index 0000000..536acc5 Binary files /dev/null and b/mods/default/textures/default_river_water_flowing_animated.png differ diff --git a/mods/default/textures/default_river_water_source_animated.png b/mods/default/textures/default_river_water_source_animated.png new file mode 100644 index 0000000..daa5653 Binary files /dev/null and b/mods/default/textures/default_river_water_source_animated.png differ diff --git a/mods/default/textures/default_sand.png b/mods/default/textures/default_sand.png new file mode 100644 index 0000000..645a300 Binary files /dev/null and b/mods/default/textures/default_sand.png differ diff --git a/mods/default/textures/default_sandstone.png b/mods/default/textures/default_sandstone.png new file mode 100644 index 0000000..16e3d13 Binary files /dev/null and b/mods/default/textures/default_sandstone.png differ diff --git a/mods/default/textures/default_sandstone_block.png b/mods/default/textures/default_sandstone_block.png new file mode 100644 index 0000000..2e06491 Binary files /dev/null and b/mods/default/textures/default_sandstone_block.png differ diff --git a/mods/default/textures/default_sandstone_brick.png b/mods/default/textures/default_sandstone_brick.png new file mode 100644 index 0000000..e7150e5 Binary files /dev/null and b/mods/default/textures/default_sandstone_brick.png differ diff --git a/mods/default/textures/default_sapling.png b/mods/default/textures/default_sapling.png new file mode 100644 index 0000000..3fd64f0 Binary files /dev/null and b/mods/default/textures/default_sapling.png differ diff --git a/mods/default/textures/default_sign_steel.png b/mods/default/textures/default_sign_steel.png new file mode 100644 index 0000000..3ca0c59 Binary files /dev/null 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 new file mode 100644 index 0000000..2227477 Binary files /dev/null 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 new file mode 100644 index 0000000..40552c7 Binary files /dev/null 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 new file mode 100644 index 0000000..d0559da Binary files /dev/null and b/mods/default/textures/default_sign_wood.png differ diff --git a/mods/default/textures/default_silver_sand.png b/mods/default/textures/default_silver_sand.png new file mode 100644 index 0000000..c4a8f73 Binary files /dev/null and b/mods/default/textures/default_silver_sand.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 0000000..eac62cb 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 0000000..9997461 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 0000000..93d87a5 Binary files /dev/null and b/mods/default/textures/default_silver_sandstone_brick.png differ diff --git a/mods/default/textures/default_snow.png b/mods/default/textures/default_snow.png new file mode 100644 index 0000000..fcbef0e Binary files /dev/null and b/mods/default/textures/default_snow.png differ diff --git a/mods/default/textures/default_snow_side.png b/mods/default/textures/default_snow_side.png new file mode 100644 index 0000000..03456c8 Binary files /dev/null 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 new file mode 100644 index 0000000..3a4dc1f Binary files /dev/null and b/mods/default/textures/default_snowball.png differ diff --git a/mods/default/textures/default_steel_block.png b/mods/default/textures/default_steel_block.png new file mode 100644 index 0000000..7f49f61 Binary files /dev/null and b/mods/default/textures/default_steel_block.png differ diff --git a/mods/default/textures/default_steel_ingot.png b/mods/default/textures/default_steel_ingot.png new file mode 100644 index 0000000..8100b01 Binary files /dev/null and b/mods/default/textures/default_steel_ingot.png differ diff --git a/mods/default/textures/default_stick.png b/mods/default/textures/default_stick.png new file mode 100644 index 0000000..0378d07 Binary files /dev/null and b/mods/default/textures/default_stick.png differ diff --git a/mods/default/textures/default_stone.png b/mods/default/textures/default_stone.png new file mode 100644 index 0000000..63cb7c4 Binary files /dev/null and b/mods/default/textures/default_stone.png differ diff --git a/mods/default/textures/default_stone_block.png b/mods/default/textures/default_stone_block.png new file mode 100644 index 0000000..3b771e7 Binary files /dev/null and b/mods/default/textures/default_stone_block.png differ diff --git a/mods/default/textures/default_stone_brick.png b/mods/default/textures/default_stone_brick.png new file mode 100644 index 0000000..4dbb49d Binary files /dev/null and b/mods/default/textures/default_stone_brick.png differ diff --git a/mods/default/textures/default_stones.png b/mods/default/textures/default_stones.png new file mode 100644 index 0000000..4d3b6cf Binary files /dev/null and b/mods/default/textures/default_stones.png differ diff --git a/mods/default/textures/default_stones_side.png b/mods/default/textures/default_stones_side.png new file mode 100644 index 0000000..7ae823a Binary files /dev/null and b/mods/default/textures/default_stones_side.png differ diff --git a/mods/default/textures/default_tin_block.png b/mods/default/textures/default_tin_block.png new file mode 100644 index 0000000..72759b0 Binary files /dev/null and b/mods/default/textures/default_tin_block.png differ diff --git a/mods/default/textures/default_tin_ingot.png b/mods/default/textures/default_tin_ingot.png new file mode 100644 index 0000000..eed5361 Binary files /dev/null and b/mods/default/textures/default_tin_ingot.png differ diff --git a/mods/default/textures/default_tin_lump.png b/mods/default/textures/default_tin_lump.png new file mode 100644 index 0000000..72bd339 Binary files /dev/null and b/mods/default/textures/default_tin_lump.png differ diff --git a/mods/default/textures/default_tool_bronzeaxe.png b/mods/default/textures/default_tool_bronzeaxe.png new file mode 100644 index 0000000..8ae43b5 Binary files /dev/null and b/mods/default/textures/default_tool_bronzeaxe.png differ diff --git a/mods/default/textures/default_tool_bronzepick.png b/mods/default/textures/default_tool_bronzepick.png new file mode 100644 index 0000000..c88a5f0 Binary files /dev/null and b/mods/default/textures/default_tool_bronzepick.png differ diff --git a/mods/default/textures/default_tool_bronzeshovel.png b/mods/default/textures/default_tool_bronzeshovel.png new file mode 100644 index 0000000..d7d800e Binary files /dev/null and b/mods/default/textures/default_tool_bronzeshovel.png differ diff --git a/mods/default/textures/default_tool_bronzesword.png b/mods/default/textures/default_tool_bronzesword.png new file mode 100644 index 0000000..cdab898 Binary files /dev/null and b/mods/default/textures/default_tool_bronzesword.png differ diff --git a/mods/default/textures/default_tool_diamondaxe.png b/mods/default/textures/default_tool_diamondaxe.png new file mode 100644 index 0000000..e32a0bf Binary files /dev/null and b/mods/default/textures/default_tool_diamondaxe.png differ diff --git a/mods/default/textures/default_tool_diamondpick.png b/mods/default/textures/default_tool_diamondpick.png new file mode 100644 index 0000000..f9883c6 Binary files /dev/null and b/mods/default/textures/default_tool_diamondpick.png differ diff --git a/mods/default/textures/default_tool_diamondshovel.png b/mods/default/textures/default_tool_diamondshovel.png new file mode 100644 index 0000000..d0fe24d Binary files /dev/null and b/mods/default/textures/default_tool_diamondshovel.png differ diff --git a/mods/default/textures/default_tool_diamondsword.png b/mods/default/textures/default_tool_diamondsword.png new file mode 100644 index 0000000..dbccd0e Binary files /dev/null and b/mods/default/textures/default_tool_diamondsword.png differ diff --git a/mods/default/textures/default_tool_meseaxe.png b/mods/default/textures/default_tool_meseaxe.png new file mode 100644 index 0000000..c01fb4f Binary files /dev/null and b/mods/default/textures/default_tool_meseaxe.png differ diff --git a/mods/default/textures/default_tool_mesepick.png b/mods/default/textures/default_tool_mesepick.png new file mode 100644 index 0000000..1b2e25b Binary files /dev/null and b/mods/default/textures/default_tool_mesepick.png differ diff --git a/mods/default/textures/default_tool_meseshovel.png b/mods/default/textures/default_tool_meseshovel.png new file mode 100644 index 0000000..00813a2 Binary files /dev/null and b/mods/default/textures/default_tool_meseshovel.png differ diff --git a/mods/default/textures/default_tool_mesesword.png b/mods/default/textures/default_tool_mesesword.png new file mode 100644 index 0000000..d395d3a Binary files /dev/null and b/mods/default/textures/default_tool_mesesword.png differ diff --git a/mods/default/textures/default_tool_steelaxe.png b/mods/default/textures/default_tool_steelaxe.png new file mode 100644 index 0000000..1528cad Binary files /dev/null and b/mods/default/textures/default_tool_steelaxe.png differ diff --git a/mods/default/textures/default_tool_steelpick.png b/mods/default/textures/default_tool_steelpick.png new file mode 100644 index 0000000..a7543a1 Binary files /dev/null and b/mods/default/textures/default_tool_steelpick.png differ diff --git a/mods/default/textures/default_tool_steelshovel.png b/mods/default/textures/default_tool_steelshovel.png new file mode 100644 index 0000000..65e4045 Binary files /dev/null and b/mods/default/textures/default_tool_steelshovel.png differ diff --git a/mods/default/textures/default_tool_steelsword.png b/mods/default/textures/default_tool_steelsword.png new file mode 100644 index 0000000..630a339 Binary files /dev/null and b/mods/default/textures/default_tool_steelsword.png differ diff --git a/mods/default/textures/default_tool_stoneaxe.png b/mods/default/textures/default_tool_stoneaxe.png new file mode 100644 index 0000000..cc36054 Binary files /dev/null and b/mods/default/textures/default_tool_stoneaxe.png differ diff --git a/mods/default/textures/default_tool_stonepick.png b/mods/default/textures/default_tool_stonepick.png new file mode 100644 index 0000000..237d739 Binary files /dev/null and b/mods/default/textures/default_tool_stonepick.png differ diff --git a/mods/default/textures/default_tool_stoneshovel.png b/mods/default/textures/default_tool_stoneshovel.png new file mode 100644 index 0000000..11711bd Binary files /dev/null and b/mods/default/textures/default_tool_stoneshovel.png differ diff --git a/mods/default/textures/default_tool_stonesword.png b/mods/default/textures/default_tool_stonesword.png new file mode 100644 index 0000000..1a493ac Binary files /dev/null and b/mods/default/textures/default_tool_stonesword.png differ diff --git a/mods/default/textures/default_tool_woodaxe.png b/mods/default/textures/default_tool_woodaxe.png new file mode 100644 index 0000000..68f1fd8 Binary files /dev/null and b/mods/default/textures/default_tool_woodaxe.png differ diff --git a/mods/default/textures/default_tool_woodpick.png b/mods/default/textures/default_tool_woodpick.png new file mode 100644 index 0000000..0aed583 Binary files /dev/null and b/mods/default/textures/default_tool_woodpick.png differ diff --git a/mods/default/textures/default_tool_woodshovel.png b/mods/default/textures/default_tool_woodshovel.png new file mode 100644 index 0000000..dcef2b5 Binary files /dev/null and b/mods/default/textures/default_tool_woodshovel.png differ diff --git a/mods/default/textures/default_tool_woodsword.png b/mods/default/textures/default_tool_woodsword.png new file mode 100644 index 0000000..c78ba50 Binary files /dev/null and b/mods/default/textures/default_tool_woodsword.png differ diff --git a/mods/default/textures/default_torch_animated.png b/mods/default/textures/default_torch_animated.png new file mode 100644 index 0000000..cdf33ef Binary files /dev/null and b/mods/default/textures/default_torch_animated.png differ diff --git a/mods/default/textures/default_torch_on_ceiling_animated.png b/mods/default/textures/default_torch_on_ceiling_animated.png new file mode 100644 index 0000000..3a8b5ad Binary files /dev/null and b/mods/default/textures/default_torch_on_ceiling_animated.png differ diff --git a/mods/default/textures/default_torch_on_floor.png b/mods/default/textures/default_torch_on_floor.png new file mode 100644 index 0000000..bc4bdd6 Binary files /dev/null and b/mods/default/textures/default_torch_on_floor.png differ diff --git a/mods/default/textures/default_torch_on_floor_animated.png b/mods/default/textures/default_torch_on_floor_animated.png new file mode 100644 index 0000000..ad51c03 Binary files /dev/null and b/mods/default/textures/default_torch_on_floor_animated.png differ diff --git a/mods/default/textures/default_tree.png b/mods/default/textures/default_tree.png new file mode 100644 index 0000000..10e297b Binary files /dev/null and b/mods/default/textures/default_tree.png differ diff --git a/mods/default/textures/default_tree_top.png b/mods/default/textures/default_tree_top.png new file mode 100644 index 0000000..da99bce Binary files /dev/null and b/mods/default/textures/default_tree_top.png differ diff --git a/mods/default/textures/default_water.png b/mods/default/textures/default_water.png new file mode 100644 index 0000000..00500e9 Binary files /dev/null and b/mods/default/textures/default_water.png differ diff --git a/mods/default/textures/default_water_flowing_animated.png b/mods/default/textures/default_water_flowing_animated.png new file mode 100644 index 0000000..070d797 Binary files /dev/null and b/mods/default/textures/default_water_flowing_animated.png differ diff --git a/mods/default/textures/default_water_source_animated.png b/mods/default/textures/default_water_source_animated.png new file mode 100644 index 0000000..7e7f9ff Binary files /dev/null and b/mods/default/textures/default_water_source_animated.png differ diff --git a/mods/default/textures/default_wood.png b/mods/default/textures/default_wood.png new file mode 100644 index 0000000..af56d6c Binary files /dev/null and b/mods/default/textures/default_wood.png differ diff --git a/mods/default/textures/gui_formbg.png b/mods/default/textures/gui_formbg.png new file mode 100644 index 0000000..c543466 Binary files /dev/null and b/mods/default/textures/gui_formbg.png differ diff --git a/mods/default/textures/gui_furnace_arrow_bg.png b/mods/default/textures/gui_furnace_arrow_bg.png new file mode 100644 index 0000000..046d8cd Binary files /dev/null and b/mods/default/textures/gui_furnace_arrow_bg.png differ diff --git a/mods/default/textures/gui_furnace_arrow_fg.png b/mods/default/textures/gui_furnace_arrow_fg.png new file mode 100644 index 0000000..8d3c396 Binary files /dev/null and b/mods/default/textures/gui_furnace_arrow_fg.png differ diff --git a/mods/default/textures/gui_hb_bg.png b/mods/default/textures/gui_hb_bg.png new file mode 100644 index 0000000..99248e1 Binary files /dev/null and b/mods/default/textures/gui_hb_bg.png differ diff --git a/mods/default/textures/gui_hotbar.png b/mods/default/textures/gui_hotbar.png new file mode 100644 index 0000000..7bc7887 Binary files /dev/null and b/mods/default/textures/gui_hotbar.png differ diff --git a/mods/default/textures/gui_hotbar_selected.png b/mods/default/textures/gui_hotbar_selected.png new file mode 100644 index 0000000..7203e9a Binary files /dev/null and b/mods/default/textures/gui_hotbar_selected.png differ diff --git a/mods/default/textures/heart.png b/mods/default/textures/heart.png new file mode 100644 index 0000000..4412cab Binary files /dev/null and b/mods/default/textures/heart.png differ diff --git a/mods/default/textures/wieldhand.png b/mods/default/textures/wieldhand.png new file mode 100644 index 0000000..69f4b7b Binary files /dev/null and b/mods/default/textures/wieldhand.png differ diff --git a/mods/default/tools.lua b/mods/default/tools.lua new file mode 100644 index 0000000..e3c974c --- /dev/null +++ b/mods/default/tools.lua @@ -0,0 +1,518 @@ +-- mods/default/tools.lua + +-- support for MT game translation. +local S = default.get_translator + +-- The hand +minetest.register_item(":", { + type = "none", + wield_image = "wieldhand.png", + wield_scale = {x=1,y=1,z=2.5}, + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level = 0, + groupcaps = { + crumbly = {times={[2]=3.00, [3]=0.70}, uses=0, maxlevel=1}, + snappy = {times={[3]=0.40}, uses=0, maxlevel=1}, + oddly_breakable_by_hand = {times={[1]=3.50,[2]=2.00,[3]=0.70}, uses=0} + }, + damage_groups = {fleshy=1}, + } +}) + +-- +-- Picks +-- + +minetest.register_tool("default:pick_wood", { + description = S("Wooden Pickaxe"), + inventory_image = "default_tool_woodpick.png", + tool_capabilities = { + full_punch_interval = 1.2, + max_drop_level=0, + groupcaps={ + cracky = {times={[3]=1.60}, uses=10, maxlevel=1}, + }, + damage_groups = {fleshy=2}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {pickaxe = 1, flammable = 2} +}) + +minetest.register_tool("default:pick_stone", { + description = S("Stone Pickaxe"), + inventory_image = "default_tool_stonepick.png", + tool_capabilities = { + full_punch_interval = 1.3, + max_drop_level=0, + groupcaps={ + cracky = {times={[2]=2.0, [3]=1.00}, uses=20, maxlevel=1}, + }, + damage_groups = {fleshy=3}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {pickaxe = 1} +}) + +minetest.register_tool("default:pick_bronze", { + description = S("Bronze Pickaxe"), + inventory_image = "default_tool_bronzepick.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + cracky = {times={[1]=4.50, [2]=1.80, [3]=0.90}, uses=20, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {pickaxe = 1} +}) + +minetest.register_tool("default:pick_steel", { + description = S("Steel Pickaxe"), + inventory_image = "default_tool_steelpick.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + cracky = {times={[1]=4.00, [2]=1.60, [3]=0.80}, uses=20, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {pickaxe = 1} +}) + +minetest.register_tool("default:pick_mese", { + description = S("Mese Pickaxe"), + inventory_image = "default_tool_mesepick.png", + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level=3, + groupcaps={ + cracky = {times={[1]=2.4, [2]=1.2, [3]=0.60}, uses=20, maxlevel=3}, + }, + damage_groups = {fleshy=5}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {pickaxe = 1} +}) + +minetest.register_tool("default:pick_diamond", { + description = S("Diamond Pickaxe"), + inventory_image = "default_tool_diamondpick.png", + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level=3, + groupcaps={ + cracky = {times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=30, maxlevel=3}, + }, + damage_groups = {fleshy=5}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {pickaxe = 1} +}) + +-- +-- Shovels +-- + +minetest.register_tool("default:shovel_wood", { + description = S("Wooden Shovel"), + inventory_image = "default_tool_woodshovel.png", + wield_image = "default_tool_woodshovel.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1.2, + max_drop_level=0, + groupcaps={ + crumbly = {times={[1]=3.00, [2]=1.60, [3]=0.60}, uses=10, maxlevel=1}, + }, + damage_groups = {fleshy=2}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {shovel = 1, flammable = 2} +}) + +minetest.register_tool("default:shovel_stone", { + description = S("Stone Shovel"), + inventory_image = "default_tool_stoneshovel.png", + wield_image = "default_tool_stoneshovel.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1.4, + max_drop_level=0, + groupcaps={ + crumbly = {times={[1]=1.80, [2]=1.20, [3]=0.50}, uses=20, maxlevel=1}, + }, + damage_groups = {fleshy=2}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {shovel = 1} +}) + +minetest.register_tool("default:shovel_bronze", { + description = S("Bronze Shovel"), + inventory_image = "default_tool_bronzeshovel.png", + wield_image = "default_tool_bronzeshovel.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1.1, + max_drop_level=1, + groupcaps={ + crumbly = {times={[1]=1.65, [2]=1.05, [3]=0.45}, uses=25, maxlevel=2}, + }, + damage_groups = {fleshy=3}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {shovel = 1} +}) + +minetest.register_tool("default:shovel_steel", { + description = S("Steel Shovel"), + inventory_image = "default_tool_steelshovel.png", + wield_image = "default_tool_steelshovel.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1.1, + max_drop_level=1, + groupcaps={ + crumbly = {times={[1]=1.50, [2]=0.90, [3]=0.40}, uses=30, maxlevel=2}, + }, + damage_groups = {fleshy=3}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {shovel = 1} +}) + +minetest.register_tool("default:shovel_mese", { + description = S("Mese Shovel"), + inventory_image = "default_tool_meseshovel.png", + wield_image = "default_tool_meseshovel.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=3, + groupcaps={ + crumbly = {times={[1]=1.20, [2]=0.60, [3]=0.30}, uses=20, maxlevel=3}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {shovel = 1} +}) + +minetest.register_tool("default:shovel_diamond", { + description = S("Diamond Shovel"), + inventory_image = "default_tool_diamondshovel.png", + wield_image = "default_tool_diamondshovel.png^[transformR90", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + crumbly = {times={[1]=1.10, [2]=0.50, [3]=0.30}, uses=30, maxlevel=3}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {shovel = 1} +}) + +-- +-- Axes +-- + +minetest.register_tool("default:axe_wood", { + description = S("Wooden Axe"), + inventory_image = "default_tool_woodaxe.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=0, + groupcaps={ + choppy = {times={[2]=3.00, [3]=1.60}, uses=10, maxlevel=1}, + }, + damage_groups = {fleshy=2}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {axe = 1, flammable = 2} +}) + +minetest.register_tool("default:axe_stone", { + description = S("Stone Axe"), + inventory_image = "default_tool_stoneaxe.png", + tool_capabilities = { + full_punch_interval = 1.2, + max_drop_level=0, + groupcaps={ + choppy={times={[1]=3.00, [2]=2.00, [3]=1.30}, uses=20, maxlevel=1}, + }, + damage_groups = {fleshy=3}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {axe = 1} +}) + +minetest.register_tool("default:axe_bronze", { + description = S("Bronze Axe"), + inventory_image = "default_tool_bronzeaxe.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.75, [2]=1.70, [3]=1.15}, uses=20, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {axe = 1} +}) + +minetest.register_tool("default:axe_steel", { + description = S("Steel Axe"), + inventory_image = "default_tool_steelaxe.png", + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.50, [2]=1.40, [3]=1.00}, uses=20, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {axe = 1} +}) + +minetest.register_tool("default:axe_mese", { + description = S("Mese Axe"), + inventory_image = "default_tool_meseaxe.png", + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.20, [2]=1.00, [3]=0.60}, uses=20, maxlevel=3}, + }, + damage_groups = {fleshy=6}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {axe = 1} +}) + +minetest.register_tool("default:axe_diamond", { + description = S("Diamond Axe"), + inventory_image = "default_tool_diamondaxe.png", + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.10, [2]=0.90, [3]=0.50}, uses=30, maxlevel=3}, + }, + damage_groups = {fleshy=7}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {axe = 1} +}) + +-- +-- Swords +-- + +minetest.register_tool("default:sword_wood", { + description = S("Wooden Sword"), + inventory_image = "default_tool_woodsword.png", + tool_capabilities = { + full_punch_interval = 1, + max_drop_level=0, + groupcaps={ + snappy={times={[2]=1.6, [3]=0.40}, uses=10, maxlevel=1}, + }, + damage_groups = {fleshy=2}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {sword = 1, flammable = 2} +}) + +minetest.register_tool("default:sword_stone", { + description = S("Stone Sword"), + inventory_image = "default_tool_stonesword.png", + tool_capabilities = { + full_punch_interval = 1.2, + max_drop_level=0, + groupcaps={ + snappy={times={[2]=1.4, [3]=0.40}, uses=20, maxlevel=1}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {sword = 1} +}) + +minetest.register_tool("default:sword_bronze", { + description = S("Bronze Sword"), + inventory_image = "default_tool_bronzesword.png", + tool_capabilities = { + full_punch_interval = 0.8, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=2.75, [2]=1.30, [3]=0.375}, uses=25, maxlevel=2}, + }, + damage_groups = {fleshy=6}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {sword = 1} +}) + +minetest.register_tool("default:sword_steel", { + description = S("Steel Sword"), + inventory_image = "default_tool_steelsword.png", + tool_capabilities = { + full_punch_interval = 0.8, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=30, maxlevel=2}, + }, + damage_groups = {fleshy=6}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {sword = 1} +}) + +minetest.register_tool("default:sword_mese", { + description = S("Mese Sword"), + inventory_image = "default_tool_mesesword.png", + tool_capabilities = { + full_punch_interval = 0.7, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=2.0, [2]=1.00, [3]=0.35}, uses=30, maxlevel=3}, + }, + damage_groups = {fleshy=7}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {sword = 1} +}) + +minetest.register_tool("default:sword_diamond", { + description = S("Diamond Sword"), + inventory_image = "default_tool_diamondsword.png", + tool_capabilities = { + full_punch_interval = 0.7, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=1.90, [2]=0.90, [3]=0.30}, uses=40, maxlevel=3}, + }, + damage_groups = {fleshy=8}, + }, + sound = {breaks = "default_tool_breaks"}, + groups = {sword = 1} +}) + +-- +-- Register Craft Recipies +-- + +local craft_ingreds = { + wood = "group:wood", + stone = "group:stone", + steel = "default:steel_ingot", + bronze = "default:bronze_ingot", + mese = "default:mese_crystal", + diamond = "default:diamond" +} + +for name, mat in pairs(craft_ingreds) do + minetest.register_craft({ + output = "default:pick_".. name, + recipe = { + {mat, mat, mat}, + {"", "group:stick", ""}, + {"", "group:stick", ""} + } + }) + + minetest.register_craft({ + output = "default:shovel_".. name, + recipe = { + {mat}, + {"group:stick"}, + {"group:stick"} + } + }) + + minetest.register_craft({ + output = "default:axe_".. name, + recipe = { + {mat, mat}, + {mat, "group:stick"}, + {"", "group:stick"} + } + }) + + minetest.register_craft({ + output = "default:sword_".. name, + recipe = { + {mat}, + {mat}, + {"group:stick"} + } + }) +end + +minetest.register_tool("default:key", { + description = S("Key"), + inventory_image = "default_key.png", + 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:is_player() 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 + node = minetest.get_node(pos) + + if not node or node.name == "ignore" then + return itemstack + end + + local ndef = minetest.registered_nodes[node.name] + if not ndef then + return itemstack + end + + local on_key_use = ndef.on_key_use + if on_key_use then + on_key_use(pos, placer) + end + + return nil + end +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:pick_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:shovel_wood", + burntime = 4, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:axe_wood", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:sword_wood", + burntime = 5, +}) diff --git a/mods/default/torch.lua b/mods/default/torch.lua new file mode 100644 index 0000000..c06dee8 --- /dev/null +++ b/mods/default/torch.lua @@ -0,0 +1,154 @@ +-- default/torch.lua + +-- support for MT game translation. +local S = default.get_translator + +local function on_flood(pos, oldnode, newnode) + minetest.add_item(pos, ItemStack("default:torch 1")) + -- Play flame-extinguish sound if liquid is not an 'igniter' + local nodedef = minetest.registered_items[newnode.name] + if not (nodedef and nodedef.groups and + nodedef.groups.igniter and nodedef.groups.igniter > 0) then + minetest.sound_play( + "default_cool_lava", + {pos = pos, max_hear_distance = 16, gain = 0.1}, + true + ) + end + -- Remove the torch node + return false +end + +minetest.register_node("default:torch", { + description = S("Torch"), + drawtype = "mesh", + mesh = "torch_floor.obj", + inventory_image = "default_torch_on_floor.png", + wield_image = "default_torch_on_floor.png", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + liquids_pointable = false, + light_source = 12, + groups = {choppy=2, dig_immediate=3, flammable=1, attached_node=1, torch=1}, + drop = "default:torch", + selection_box = { + type = "wallmounted", + wall_bottom = {-1/8, -1/2, -1/8, 1/8, 2/16, 1/8}, + }, + sounds = default.node_sound_wood_defaults(), + 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:is_player() and + placer:get_player_control().sneak) then + return def.on_rightclick(under, node, placer, itemstack, + pointed_thing) or itemstack + end + + local above = pointed_thing.above + local wdir = minetest.dir_to_wallmounted(vector.subtract(under, above)) + local fakestack = itemstack + if wdir == 0 then + fakestack:set_name("default:torch_ceiling") + elseif wdir == 1 then + fakestack:set_name("default:torch") + else + fakestack:set_name("default:torch_wall") + end + + itemstack = minetest.item_place(fakestack, placer, pointed_thing, wdir) + itemstack:set_name("default:torch") + + return itemstack + end, + floodable = true, + on_flood = on_flood, + on_rotate = false +}) + +minetest.register_node("default:torch_wall", { + drawtype = "mesh", + mesh = "torch_wall.obj", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + 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 = { + type = "wallmounted", + wall_side = {-1/2, -1/2, -1/8, -1/8, 1/8, 1/8}, + }, + sounds = default.node_sound_wood_defaults(), + floodable = true, + on_flood = on_flood, + on_rotate = false +}) + +minetest.register_node("default:torch_ceiling", { + drawtype = "mesh", + mesh = "torch_ceiling.obj", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + walkable = false, + 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 = { + type = "wallmounted", + wall_top = {-1/8, -1/16, -5/16, 1/8, 1/2, 1/8}, + }, + sounds = default.node_sound_wood_defaults(), + floodable = true, + on_flood = on_flood, + on_rotate = false +}) + +minetest.register_lbm({ + name = "default:3dtorch", + nodenames = {"default:torch", "torches:floor", "torches:wall"}, + action = function(pos, node) + if node.param2 == 0 then + minetest.set_node(pos, {name = "default:torch_ceiling", + param2 = node.param2}) + elseif node.param2 == 1 then + minetest.set_node(pos, {name = "default:torch", + param2 = node.param2}) + else + minetest.set_node(pos, {name = "default:torch_wall", + param2 = node.param2}) + end + end +}) + +minetest.register_craft({ + output = "default:torch 4", + recipe = { + {"default:coal_lump"}, + {"group:stick"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "default:torch", + burntime = 4, +}) diff --git a/mods/default/trees.lua b/mods/default/trees.lua new file mode 100644 index 0000000..a850644 --- /dev/null +++ b/mods/default/trees.lua @@ -0,0 +1,608 @@ +-- default/trees.lua + +-- support for MT game translation. +local S = default.get_translator + +local random = math.random + +-- +-- Grow trees from saplings +-- + +-- 'can grow' function + +function default.can_grow(pos) + local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z}) + if not node_under then + return false + end + if minetest.get_item_group(node_under.name, "soil") == 0 then + return false + end + local light_level = minetest.get_node_light(pos) + if not light_level or light_level < 13 then + return false + end + return true +end + + +-- 'is snow nearby' function + +local function is_snow_nearby(pos) + return minetest.find_node_near(pos, 1, {"group:snowy"}) +end + + +-- Grow sapling + +function default.grow_sapling(pos) + if not default.can_grow(pos) then + -- try again 5 min later + minetest.get_node_timer(pos):start(300) + return + end + + local mg_name = minetest.get_mapgen_setting("mg_name") + local node = minetest.get_node(pos) + if node.name == "default:sapling" then + minetest.log("action", "A sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + if mg_name == "v6" then + default.grow_tree(pos, random(1, 4) == 1) + else + default.grow_new_apple_tree(pos) + end + elseif node.name == "default:junglesapling" then + minetest.log("action", "A jungle sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + if mg_name == "v6" then + default.grow_jungle_tree(pos) + else + default.grow_new_jungle_tree(pos) + end + elseif node.name == "default:pine_sapling" then + minetest.log("action", "A pine sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + local snow = is_snow_nearby(pos) + if mg_name == "v6" then + default.grow_pine_tree(pos, snow) + elseif snow then + default.grow_new_snowy_pine_tree(pos) + else + default.grow_new_pine_tree(pos) + end + elseif node.name == "default:acacia_sapling" then + minetest.log("action", "An acacia sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + default.grow_new_acacia_tree(pos) + elseif node.name == "default:aspen_sapling" then + minetest.log("action", "An aspen sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + default.grow_new_aspen_tree(pos) + elseif node.name == "default:bush_sapling" then + minetest.log("action", "A bush sapling grows into a bush at ".. + minetest.pos_to_string(pos)) + default.grow_bush(pos) + elseif node.name == "default:blueberry_bush_sapling" then + minetest.log("action", "A blueberry bush sapling grows into a bush at ".. + minetest.pos_to_string(pos)) + default.grow_blueberry_bush(pos) + elseif node.name == "default:acacia_bush_sapling" then + minetest.log("action", "An acacia bush sapling grows into a bush at ".. + minetest.pos_to_string(pos)) + default.grow_acacia_bush(pos) + elseif node.name == "default:pine_bush_sapling" then + minetest.log("action", "A pine bush sapling grows into a bush at ".. + minetest.pos_to_string(pos)) + default.grow_pine_bush(pos) + elseif node.name == "default:emergent_jungle_sapling" then + minetest.log("action", "An emergent jungle sapling grows into a tree at ".. + minetest.pos_to_string(pos)) + default.grow_new_emergent_jungle_tree(pos) + end +end + +minetest.register_lbm({ + name = "default:convert_saplings_to_node_timer", + nodenames = {"default:sapling", "default:junglesapling", + "default:pine_sapling", "default:acacia_sapling", + "default:aspen_sapling"}, + action = function(pos) + minetest.get_node_timer(pos):start(math.random(300, 1500)) + end +}) + +-- +-- Tree generation +-- + +-- Apple tree and jungle tree trunk and leaves function + +local function add_trunk_and_leaves(data, a, pos, tree_cid, leaves_cid, + height, size, iters, is_apple_tree) + local x, y, z = pos.x, pos.y, pos.z + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_apple = minetest.get_content_id("default:apple") + + -- Trunk + data[a:index(x, y, z)] = tree_cid -- Force-place lowest trunk node to replace sapling + for yy = y + 1, y + height - 1 do + local vi = a:index(x, yy, z) + local node_id = data[vi] + if node_id == c_air or node_id == c_ignore or node_id == leaves_cid then + data[vi] = tree_cid + end + end + + -- Force leaves near the trunk + for z_dist = -1, 1 do + for y_dist = -size, 1 do + local vi = a:index(x - 1, y + height + y_dist, z + z_dist) + for x_dist = -1, 1 do + if data[vi] == c_air or data[vi] == c_ignore then + if is_apple_tree and random(1, 8) == 1 then + data[vi] = c_apple + else + data[vi] = leaves_cid + end + end + vi = vi + 1 + end + end + end + + -- Randomly add leaves in 2x2x2 clusters. + for i = 1, iters do + local clust_x = x + random(-size, size - 1) + local clust_y = y + height + random(-size, 0) + local clust_z = z + random(-size, size - 1) + + for xi = 0, 1 do + for yi = 0, 1 do + for zi = 0, 1 do + local vi = a:index(clust_x + xi, clust_y + yi, clust_z + zi) + if data[vi] == c_air or data[vi] == c_ignore then + if is_apple_tree and random(1, 8) == 1 then + data[vi] = c_apple + else + data[vi] = leaves_cid + end + end + end + end + end + end +end + + +-- Apple tree + +function default.grow_tree(pos, is_apple_tree, bad) + --[[ + NOTE: Tree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + --]] + if bad then + error("Deprecated use of default.grow_tree") + end + + local x, y, z = pos.x, pos.y, pos.z + local height = random(4, 5) + local c_tree = minetest.get_content_id("default:tree") + local c_leaves = minetest.get_content_id("default:leaves") + + local vm = minetest.get_voxel_manip() + local minp, maxp = vm:read_from_map( + {x = x - 2, y = y, z = z - 2}, + {x = x + 2, y = y + height + 1, z = z + 2} + ) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree) + + vm:set_data(data) + vm:write_to_map() + vm:update_map() +end + + +-- Jungle tree + +function default.grow_jungle_tree(pos, bad) + --[[ + NOTE: Jungletree-placing code is currently duplicated in the engine + and in games that have saplings; both are deprecated but not + replaced yet + --]] + if bad then + error("Deprecated use of default.grow_jungle_tree") + end + + local x, y, z = pos.x, pos.y, pos.z + local height = random(8, 12) + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_jungletree = minetest.get_content_id("default:jungletree") + local c_jungleleaves = minetest.get_content_id("default:jungleleaves") + + local vm = minetest.get_voxel_manip() + local minp, maxp = vm:read_from_map( + {x = x - 3, y = y - 1, z = z - 3}, + {x = x + 3, y = y + height + 1, z = z + 3} + ) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves, + height, 3, 30, false) + + -- Roots + for z_dist = -1, 1 do + local vi_1 = a:index(x - 1, y - 1, z + z_dist) + local vi_2 = a:index(x - 1, y, z + z_dist) + for x_dist = -1, 1 do + if random(1, 3) >= 2 then + if data[vi_1] == c_air or data[vi_1] == c_ignore then + data[vi_1] = c_jungletree + elseif data[vi_2] == c_air or data[vi_2] == c_ignore then + data[vi_2] = c_jungletree + end + end + vi_1 = vi_1 + 1 + vi_2 = vi_2 + 1 + end + end + + vm:set_data(data) + vm:write_to_map() + vm:update_map() +end + + +-- Pine tree from mg mapgen mod, design by sfan5, pointy top added by paramat + +local function add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles) + local node_id = data[vi] + if node_id == c_air or node_id == c_ignore or node_id == c_snow then + data[vi] = c_pine_needles + end +end + +local function add_snow(data, vi, c_air, c_ignore, c_snow) + local node_id = data[vi] + if node_id == c_air or node_id == c_ignore then + data[vi] = c_snow + end +end + +function default.grow_pine_tree(pos, snow) + local x, y, z = pos.x, pos.y, pos.z + local maxy = y + random(9, 13) -- Trunk top + + local c_air = minetest.get_content_id("air") + local c_ignore = minetest.get_content_id("ignore") + local c_pine_tree = minetest.get_content_id("default:pine_tree") + local c_pine_needles = minetest.get_content_id("default:pine_needles") + local c_snow = minetest.get_content_id("default:snow") + + local vm = minetest.get_voxel_manip() + local minp, maxp = vm:read_from_map( + {x = x - 3, y = y, z = z - 3}, + {x = x + 3, y = maxy + 3, z = z + 3} + ) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + -- Upper branches layer + local dev = 3 + for yy = maxy - 1, maxy + 1 do + for zz = z - dev, z + dev do + local vi = a:index(x - dev, yy, zz) + local via = a:index(x - dev, yy + 1, zz) + for xx = x - dev, x + dev do + if random() < 0.95 - dev * 0.05 then + add_pine_needles(data, vi, c_air, c_ignore, c_snow, + c_pine_needles) + if snow then + add_snow(data, via, c_air, c_ignore, c_snow) + end + end + vi = vi + 1 + via = via + 1 + end + end + dev = dev - 1 + end + + -- Centre top nodes + add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow, + c_pine_needles) + add_pine_needles(data, a:index(x, maxy + 2, z), c_air, c_ignore, c_snow, + c_pine_needles) -- Paramat added a pointy top node + if snow then + add_snow(data, a:index(x, maxy + 3, z), c_air, c_ignore, c_snow) + end + + -- Lower branches layer + local my = 0 + for i = 1, 20 do -- Random 2x2 squares of needles + local xi = x + random(-3, 2) + local yy = maxy + random(-6, -5) + local zi = z + random(-3, 2) + if yy > my then + my = yy + end + for zz = zi, zi+1 do + local vi = a:index(xi, yy, zz) + local via = a:index(xi, yy + 1, zz) + for xx = xi, xi + 1 do + add_pine_needles(data, vi, c_air, c_ignore, c_snow, + c_pine_needles) + if snow then + add_snow(data, via, c_air, c_ignore, c_snow) + end + vi = vi + 1 + via = via + 1 + end + end + end + + dev = 2 + for yy = my + 1, my + 2 do + for zz = z - dev, z + dev do + local vi = a:index(x - dev, yy, zz) + local via = a:index(x - dev, yy + 1, zz) + for xx = x - dev, x + dev do + if random() < 0.95 - dev * 0.05 then + add_pine_needles(data, vi, c_air, c_ignore, c_snow, + c_pine_needles) + if snow then + add_snow(data, via, c_air, c_ignore, c_snow) + end + end + vi = vi + 1 + via = via + 1 + end + end + dev = dev - 1 + end + + -- Trunk + -- Force-place lowest trunk node to replace sapling + data[a:index(x, y, z)] = c_pine_tree + for yy = y + 1, maxy do + local vi = a:index(x, yy, z) + local node_id = data[vi] + if node_id == c_air or node_id == c_ignore or + node_id == c_pine_needles or node_id == c_snow then + data[vi] = c_pine_tree + end + end + + vm:set_data(data) + vm:write_to_map() + vm:update_map() +end + + +-- New apple tree + +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 - 3, y = pos.y - 1, z = pos.z - 3}, + path, "random", nil, false) +end + + +-- New jungle tree + +function default.grow_new_jungle_tree(pos) + local path = minetest.get_modpath("default") .. + "/schematics/jungle_tree_from_sapling.mts" + minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, + path, "random", nil, false) +end + + +-- New emergent jungle tree + +function default.grow_new_emergent_jungle_tree(pos) + local path = minetest.get_modpath("default") .. + "/schematics/emergent_jungle_tree_from_sapling.mts" + minetest.place_schematic({x = pos.x - 3, y = pos.y - 5, z = pos.z - 3}, + path, "random", nil, false) +end + + +-- New pine tree + +function default.grow_new_pine_tree(pos) + local path + if math.random() > 0.5 then + path = minetest.get_modpath("default") .. + "/schematics/pine_tree_from_sapling.mts" + else + path = minetest.get_modpath("default") .. + "/schematics/small_pine_tree_from_sapling.mts" + end + minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, + path, "0", nil, false) +end + + +-- New snowy pine tree + +function default.grow_new_snowy_pine_tree(pos) + local path + if math.random() > 0.5 then + path = minetest.get_modpath("default") .. + "/schematics/snowy_pine_tree_from_sapling.mts" + else + path = minetest.get_modpath("default") .. + "/schematics/snowy_small_pine_tree_from_sapling.mts" + end + minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, + path, "random", nil, false) +end + + +-- New acacia tree + +function default.grow_new_acacia_tree(pos) + local path = minetest.get_modpath("default") .. + "/schematics/acacia_tree_from_sapling.mts" + minetest.place_schematic({x = pos.x - 4, y = pos.y - 1, z = pos.z - 4}, + path, "random", nil, false) +end + + +-- New aspen tree + +function default.grow_new_aspen_tree(pos) + local path = minetest.get_modpath("default") .. + "/schematics/aspen_tree_from_sapling.mts" + minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, + path, "0", nil, false) +end + + +-- Bushes do not need 'from sapling' schematic variants because +-- only the stem node is force-placed in the schematic. + +-- Bush + +function default.grow_bush(pos) + local path = minetest.get_modpath("default") .. + "/schematics/bush.mts" + minetest.place_schematic({x = pos.x - 1, y = pos.y - 1, z = pos.z - 1}, + path, "0", nil, false) +end + +-- Blueberry bush + +function default.grow_blueberry_bush(pos) + local path = minetest.get_modpath("default") .. + "/schematics/blueberry_bush.mts" + minetest.place_schematic({x = pos.x - 1, y = pos.y, z = pos.z - 1}, + path, "0", nil, false) +end + + +-- Acacia bush + +function default.grow_acacia_bush(pos) + local path = minetest.get_modpath("default") .. + "/schematics/acacia_bush.mts" + minetest.place_schematic({x = pos.x - 1, y = pos.y - 1, z = pos.z - 1}, + path, "0", nil, false) +end + + +-- Pine bush + +function default.grow_pine_bush(pos) + local path = minetest.get_modpath("default") .. + "/schematics/pine_bush.mts" + minetest.place_schematic({x = pos.x - 1, y = pos.y - 1, z = pos.z - 1}, + path, "0", nil, false) +end + + +-- Large cactus + +function default.grow_large_cactus(pos) + local path = minetest.get_modpath("default") .. + "/schematics/large_cactus.mts" + minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, + path, "random", nil, false) +end + + +-- +-- Sapling 'on place' function to check protection of node and resulting tree volume +-- + +function default.sapling_on_place(itemstack, placer, pointed_thing, + sapling_name, minp_relative, maxp_relative, interval) + -- Position of sapling + local pos = pointed_thing.under + local node = minetest.get_node_or_nil(pos) + local pdef = node and minetest.registered_nodes[node.name] + + if pdef and pdef.on_rightclick and + not (placer and placer:is_player() and + placer:get_player_control().sneak) then + return pdef.on_rightclick(pos, node, placer, itemstack, pointed_thing) + end + + if not pdef or not pdef.buildable_to then + pos = pointed_thing.above + node = minetest.get_node_or_nil(pos) + pdef = node and minetest.registered_nodes[node.name] + if not pdef or not pdef.buildable_to then + return itemstack + end + end + + local player_name = placer and placer:get_player_name() or "" + -- Check sapling position for protection + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return itemstack + end + -- Check tree volume for protection + if minetest.is_area_protected( + vector.add(pos, minp_relative), + vector.add(pos, maxp_relative), + player_name, + interval) then + minetest.record_protection_violation(pos, player_name) + -- Print extra information to explain +-- minetest.chat_send_player(player_name, +-- itemstack:get_definition().description .. " will intersect protection " .. +-- "on growth") + minetest.chat_send_player(player_name, + S("@1 will intersect protection on growth.", + itemstack:get_definition().description)) + return itemstack + end + + minetest.log("action", player_name .. " places node " + .. sapling_name .. " at " .. minetest.pos_to_string(pos)) + + local take_item = not (creative and creative.is_enabled_for + and creative.is_enabled_for(player_name)) + local newnode = {name = sapling_name} + local ndef = minetest.registered_nodes[sapling_name] + minetest.set_node(pos, newnode) + + -- Run callback + if ndef and ndef.after_place_node then + -- Deepcopy place_to and pointed_thing because callback can modify it + if ndef.after_place_node(table.copy(pos), placer, + itemstack, table.copy(pointed_thing)) then + take_item = false + end + end + + -- Run script hook + for _, callback in ipairs(minetest.registered_on_placenodes) do + -- Deepcopy pos, node and pointed_thing because callback can modify them + if callback(table.copy(pos), table.copy(newnode), + placer, table.copy(node or {}), + itemstack, table.copy(pointed_thing)) then + take_item = false + end + end + + if take_item then + itemstack:take_item() + end + + return itemstack +end diff --git a/mods/desert_life/armadillo.lua b/mods/desert_life/armadillo.lua new file mode 100644 index 0000000..725772c --- /dev/null +++ b/mods/desert_life/armadillo.lua @@ -0,0 +1,63 @@ + +local S = mobs.intllib + +mobs:register_mob("desert_life:armadillo", { + type = "animal", + passive = false, + attack_type = "dogfight", + group_attack = true, + reach = 2, + damage = 1, + hp_min = 5, + hp_max = 10, + armor = 75, + collisionbox = {-0.35, -0.5, -0.35, 0.35, 0.0, 0.35}, + visual = "mesh", + mesh = "dl_armadillo.b3d", + textures = { + {'dl_armadillo_1.png'}, + {'dl_armadillo_2.png'}, + }, + visual_size = {x=9, y=9}, + makes_footstep_sound = true, +-- sounds = { +-- random = "mobs_chicken", +-- }, + walk_velocity = 1, + run_velocity = 3, + jump = true, + drops = { + {name = "mobs:meat_raw", chance = 1, min = 1, max =1}, + }, + water_damage = 1, + lava_damage = 5, + light_damage = 0, + fall_damage = 0, + fall_speed = -8, + fear_height = 5, + animation = { + speed_normal = 2, + speed_run = 8, + stand_start = 45, + stand_end = 70, + walk_start = 0, + walk_end = 40, + punch_start = 75, + punch_end = 95, + }, + follow = {"farming:seed_wheat", "farming:seed_cotton"}, + view_range = 5, + replace_what = {'group:flora', 'group:plant'}, + replace_with = 'air', + replace_rate = 10, +}) + +mobs:spawn({ + name = 'desert_life:armadillo', + nodes = {'default:desert_sand', 'default:desert_stone'}, + min_height = 0, + max_height = 100, + interval = 60, + chance = 8000, + active_object_count = 5, +}) diff --git a/mods/desert_life/barrel_cacti.lua b/mods/desert_life/barrel_cacti.lua new file mode 100644 index 0000000..d85ebc9 --- /dev/null +++ b/mods/desert_life/barrel_cacti.lua @@ -0,0 +1,92 @@ +local bc_col_box_1 = { + type = 'fixed', + fixed = {{-.3, -.5, -.3, .3, .0, .3}} +} +local bc_col_box_2 = { + type = 'fixed', + fixed = {{-.3, -.5, -.3, .3, .45, .3}} +} +local bc_col_box_3 = { + type = 'fixed', + fixed = {{-.3, -.5, -.3, .3, .8, .3}} +} + +local barrel_cacti_table = { --number, desc, col_box + {1, 'Small Barrel Cacti' ,bc_col_box_1}, + {2, 'Medium Barrel Cacti' ,bc_col_box_2}, + {3, 'Large Barrel Cacti' ,bc_col_box_3} +} + +for i in ipairs (barrel_cacti_table) do + local num = barrel_cacti_table[i][1] + local desc = barrel_cacti_table[i][2] + local col = barrel_cacti_table[i][3] + +minetest.register_node('desert_life:barrel_cacti_'..num, { + description = desc, + drawtype = 'mesh', + mesh = 'dl_barrel_cacti_'..num..'.obj', + tiles = {'dl_barrel_cacti.png'}, + groups = {oddly_breakable_by_hand=3, choppy=1}, + paramtype = 'light', + paramtype2 = 'facedir', + selection_box = col, + collision_box = col, + after_place_node = function(pos, placer, itemstack) + local under = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) + local node = minetest.get_node(pos) + if under.name == 'default:sand' or under.name == 'default:desert_sand' then + minetest.set_node(pos, {name = 'desert_life:barrel_cacti_'..num..'_sp', param2 = node.param2}) + end + end, +}) + +minetest.register_node('desert_life:barrel_cacti_'..num..'_sp', { + description = desc, + drawtype = 'mesh', + mesh = 'dl_barrel_cacti_'..num..'.obj', + tiles = {name='dl_barrel_cacti.png'}, + drop = 'desert_life:barrel_cacti_'..num, + groups = {oddly_breakable_by_hand=3, choppy=1, dl_bc=1, not_in_creative_inventory=1}, + paramtype = 'light', + paramtype2 = 'facedir', + selection_box = col, + collision_box = col, +}) +end + +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:desert_sand"}, + sidelen = 16, + noise_params = { + offset = .005, + scale = 0.002, + spread = {x = 150, y = 150, z = 150}, + seed = 35746584, + octaves = 3, + persist = 0.6 + }, + y_min = -10, + y_max = 60, + decoration = "desert_life:barrel_cacti_1_sp", + param2 = 0, + param2_max = 3, + biomes = {'desert'}, +}) + +minetest.register_abm{ + nodenames = {"group:dl_bc"}, + interval = 40, + chance = 30, + action = function(pos) + local node = minetest.get_node(pos) + if node.name == 'desert_life:barrel_cacti_1_sp' then + minetest.set_node(pos, {name = "desert_life:barrel_cacti_2_sp", param2 = node.param2}) + elseif node.name == 'desert_life:barrel_cacti_2_sp' then + minetest.set_node(pos, {name = "desert_life:barrel_cacti_3_sp", param2 = node.param2}) + elseif node.name == 'desert_life:barrel_cacti_3_sp' then + desert_life.spread('desert_life:barrel_cacti_1_sp', pos, 2, 'default:desert_sand', 'air', 48) + end +end, +} diff --git a/mods/desert_life/functions.lua b/mods/desert_life/functions.lua new file mode 100644 index 0000000..5cebb12 --- /dev/null +++ b/mods/desert_life/functions.lua @@ -0,0 +1,44 @@ +--nodename is the name of the node being placed. +--pos is pos, no surprises there. +--undernode is the node that needs to be below for the node to be placed. +--replacing is what nodes are allowed to be replaced, usualy probably just air. +function desert_life.spread(nodename, pos, spread, undernode, replacing, needed_air) + local ran_num = math.random(1,8) + local location = {} + if ran_num == 1 then + location = {x=pos.x+spread, y=pos.y, z=pos.z} + elseif ran_num == 2 then + location = {x=pos.x+spread, y=pos.y, z=pos.z+spread} + elseif ran_num == 3 then + location = {x=pos.x, y=pos.y, z=pos.z+spread} + elseif ran_num == 4 then + location = {x=pos.x-spread, y=pos.y, z=pos.z+spread} + elseif ran_num == 5 then + location = {x=pos.x-spread, y=pos.y, z=pos.z} + elseif ran_num == 6 then + location = {x=pos.x-spread, y=pos.y, z=pos.z-spread} + elseif ran_num == 7 then + location = {x=pos.x, y=pos.y, z=pos.z-spread} + elseif ran_num == 8 then + location = {x=pos.x+spread, y=pos.y, z=pos.z-spread} + end + local under_location = ({x=location.x, y=location.y-1, z=location.z}) + local under_name = minetest.get_node_or_nil(under_location) + local location_name = minetest.get_node_or_nil(location) + if under_name == nil then + return -- Should under_name somehow not be a node this will keep the script from crashing. + end + if under_name.name == undernode then + if location_name.name == replacing then + local diff = spread + 1 + local pos1 = {x=location.x+diff, y=location.y, z=location.z+diff} + local pos0 = {x=location.x-diff, y=location.y, z=location.z-diff} + local can_replace = minetest.find_nodes_in_area(pos0, pos1, replacing) + local replace_num = #can_replace + if replace_num >= needed_air then --increase to decrease number of plants. + local face_ran = math.random(0,3) + minetest.set_node(location, {name = nodename, param2 = face_ran}) + end + end + end +end diff --git a/mods/desert_life/init.lua b/mods/desert_life/init.lua new file mode 100644 index 0000000..23bdd09 --- /dev/null +++ b/mods/desert_life/init.lua @@ -0,0 +1,6 @@ +desert_life = {} +dofile(minetest.get_modpath('desert_life')..'/functions.lua') +dofile(minetest.get_modpath('desert_life')..'/prickly_pear.lua') +dofile(minetest.get_modpath('desert_life')..'/barrel_cacti.lua') +dofile(minetest.get_modpath('desert_life')..'/armadillo.lua') +dofile(minetest.get_modpath('desert_life')..'/ostrich.lua') diff --git a/mods/desert_life/license.txt b/mods/desert_life/license.txt new file mode 100644 index 0000000..48b27a3 --- /dev/null +++ b/mods/desert_life/license.txt @@ -0,0 +1,8 @@ +Models and Graphics by Nathan Salapat CC by SA 4.0 + +Code is licensed MIT, +Copyright 2020 Nathan Salapat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/desert_life/mod.conf b/mods/desert_life/mod.conf new file mode 100644 index 0000000..ae78e23 --- /dev/null +++ b/mods/desert_life/mod.conf @@ -0,0 +1,3 @@ +name = desert_life +depends = default +optional_depends = mobs, mymonths diff --git a/mods/desert_life/models/dl_armadillo.b3d b/mods/desert_life/models/dl_armadillo.b3d new file mode 100644 index 0000000..82625d3 Binary files /dev/null and b/mods/desert_life/models/dl_armadillo.b3d differ diff --git a/mods/desert_life/models/dl_barrel_cacti_1.obj b/mods/desert_life/models/dl_barrel_cacti_1.obj new file mode 100644 index 0000000..c4c7584 --- /dev/null +++ b/mods/desert_life/models/dl_barrel_cacti_1.obj @@ -0,0 +1,392 @@ +# Blender v2.77 (sub 1) OBJ File: 'Barrel_Cacti.blend' +# www.blender.org +o Barrel_Cacti_1_Plane.002 +v -0.340872 -0.440789 0.271836 +v -0.229420 -0.440789 0.182957 +v -0.340872 -0.040866 0.271836 +v -0.229420 -0.040866 0.182957 +v -0.425061 -0.440789 -0.097017 +v -0.286083 -0.440789 -0.065296 +v -0.425061 -0.040866 -0.097017 +v -0.286083 -0.040866 -0.065297 +v -0.189170 -0.440789 -0.392815 +v -0.127319 -0.440789 -0.264380 +v -0.189170 -0.040866 -0.392815 +v -0.127319 -0.040866 -0.264380 +v 0.189170 -0.440789 -0.392815 +v 0.127319 -0.440789 -0.264380 +v 0.189170 -0.040866 -0.392815 +v 0.127319 -0.040866 -0.264380 +v 0.425061 -0.440789 -0.097017 +v 0.286083 -0.440789 -0.065297 +v 0.425061 -0.040866 -0.097017 +v 0.286083 -0.040866 -0.065297 +v 0.340872 -0.440789 0.271836 +v 0.229421 -0.440789 0.182957 +v 0.340872 -0.040866 0.271837 +v 0.229421 -0.040866 0.182957 +v -0.000000 -0.440789 0.435992 +v 0.000000 -0.440789 0.293440 +v -0.000000 -0.040866 0.435992 +v -0.000000 -0.040866 0.293440 +v 0.000000 -0.499085 -0.202760 +v 0.000000 -0.029907 -0.195636 +v 0.126478 -0.499085 -0.262635 +v 0.122034 -0.029907 -0.253407 +v 0.158524 -0.499085 -0.126419 +v 0.152954 -0.029907 -0.121977 +v 0.284194 -0.499085 -0.064865 +v 0.274209 -0.029907 -0.062586 +v 0.197676 -0.499085 0.045118 +v 0.190731 -0.029907 0.043533 +v 0.227906 -0.499085 0.181749 +v 0.219899 -0.029907 0.175363 +v 0.087974 -0.499085 0.182680 +v 0.084883 -0.029907 0.176262 +v 0.000000 -0.499085 0.291503 +v 0.000000 -0.029907 0.281261 +v -0.087974 -0.499085 0.182680 +v -0.084883 -0.029907 0.176262 +v -0.227906 -0.499085 0.181749 +v -0.219898 -0.029907 0.175363 +v -0.197676 -0.499085 0.045118 +v -0.190731 -0.029907 0.043533 +v -0.284194 -0.499085 -0.064865 +v -0.274209 -0.029907 -0.062586 +v -0.158524 -0.499085 -0.126419 +v -0.152954 -0.029907 -0.121977 +v -0.126478 -0.499085 -0.262635 +v -0.122034 -0.029907 -0.253407 +v 0.000000 -0.408770 -0.231072 +v 0.000000 -0.147054 -0.234660 +v 0.146377 -0.147054 -0.303956 +v 0.144139 -0.408770 -0.299308 +v 0.183465 -0.147054 -0.146308 +v 0.180660 -0.408770 -0.144071 +v 0.328907 -0.147054 -0.075071 +v 0.323878 -0.408770 -0.073923 +v 0.228777 -0.147054 0.052217 +v 0.225279 -0.408770 0.051418 +v 0.263763 -0.147054 0.210344 +v 0.259730 -0.408770 0.207127 +v 0.101815 -0.147054 0.211422 +v 0.100259 -0.408770 0.208189 +v 0.000000 -0.147054 0.337365 +v 0.000000 -0.408770 0.332207 +v -0.101815 -0.147054 0.211422 +v -0.100258 -0.408770 0.208189 +v -0.263763 -0.147054 0.210344 +v -0.259730 -0.408770 0.207128 +v -0.228777 -0.147054 0.052217 +v -0.225279 -0.408770 0.051418 +v -0.328907 -0.147054 -0.075071 +v -0.323878 -0.408770 -0.073923 +v -0.183465 -0.147054 -0.146308 +v -0.180660 -0.408770 -0.144071 +v -0.146377 -0.147054 -0.303956 +v -0.144139 -0.408770 -0.299308 +v 0.000000 -0.001580 -0.013664 +v 0.008524 -0.001580 -0.017699 +v 0.010683 -0.001580 -0.008520 +v 0.019152 -0.001580 -0.004371 +v 0.013322 -0.001580 0.003041 +v 0.015359 -0.001580 0.012248 +v 0.005929 -0.001580 0.012311 +v 0.000000 -0.001580 0.019645 +v -0.005929 -0.001580 0.012311 +v -0.015359 -0.001580 0.012248 +v -0.013322 -0.001580 0.003041 +v -0.019152 -0.001580 -0.004371 +v -0.010683 -0.001580 -0.008520 +v -0.008524 -0.001580 -0.017699 +v 0.000000 -0.001580 -0.000000 +vt 0.8622 0.2724 +vt 1.0000 0.2724 +vt 1.0000 0.6678 +vt 0.8622 0.6678 +vt 0.8619 0.2722 +vt 0.9997 0.2722 +vt 0.9997 0.6676 +vt 0.8619 0.6676 +vt 0.8619 0.2722 +vt 0.9997 0.2722 +vt 0.9997 0.6676 +vt 0.8619 0.6676 +vt 0.8619 0.2722 +vt 0.9997 0.2722 +vt 0.9997 0.6676 +vt 0.8619 0.6676 +vt 0.8619 0.2722 +vt 0.9997 0.2722 +vt 0.9997 0.6676 +vt 0.8619 0.6676 +vt 0.8619 0.2722 +vt 0.9997 0.2722 +vt 0.9997 0.6676 +vt 0.8619 0.6676 +vt 0.8619 0.2722 +vt 0.9997 0.2722 +vt 0.9997 0.6676 +vt 0.8619 0.6676 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6276 0.6005 +vt 0.4947 0.7821 +vt 0.3154 0.7165 +vt 0.3153 0.5775 +vt 0.1349 0.7793 +vt 0.0185 0.6004 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3145 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.3209 0.9555 +vt 0.3092 0.9488 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3304 0.0639 +vt 0.3309 0.2107 +vt 0.0227 0.1898 +vt 0.0584 0.0353 +vt 0.5980 0.0384 +vt 0.6267 0.1901 +vt 0.3312 0.0643 +vt 0.3318 0.2111 +vt 0.0235 0.1901 +vt 0.0592 0.0357 +vt 0.5989 0.0388 +vt 0.6276 0.1905 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3210 0.9555 +vt 0.3093 0.9487 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3217 0.9559 +vt 0.3100 0.9491 +vt 0.2971 0.9554 +vt 0.3209 0.9555 +vt 0.2971 0.9554 +vt 0.3209 0.9555 +vt 0.2978 0.9558 +vt 0.3209 0.9555 +vt 0.3209 0.9555 +vt 0.2838 0.9515 +vt 0.3005 0.9515 +vt 0.3110 0.9619 +vt 0.3299 0.9692 +vt 0.3260 0.9770 +vt 0.2874 0.9593 +vt 0.3448 0.9656 +vt 0.2771 0.9656 +vt 0.3345 0.9593 +vt 0.2921 0.9692 +vt 0.3381 0.9515 +vt 0.2959 0.9770 +vt 0.3215 0.9515 +vt 0.3110 0.9735 +vt 0.3110 0.9452 +vn 0.6235 0.0000 0.7818 +vn -0.2225 0.0000 0.9749 +vn -0.9010 0.0000 0.4339 +vn -0.9010 0.0000 -0.4339 +vn -0.2225 0.0000 -0.9749 +vn 0.6235 0.0000 -0.7818 +vn 1.0000 0.0000 0.0000 +vn -0.4097 0.2883 -0.8655 +vn 0.9321 0.2883 -0.2193 +vn 0.4212 0.2883 -0.8599 +vn 0.7526 0.2883 0.5920 +vn 0.9349 0.2883 -0.2069 +vn 0.0064 0.2883 0.9575 +vn 0.7446 0.2883 0.6020 +vn -0.7446 0.2883 0.6020 +vn -0.0064 0.2883 0.9575 +vn -0.9349 0.2883 -0.2069 +vn -0.7526 0.2883 0.5920 +vn -0.4212 0.2883 -0.8599 +vn -0.1334 0.9855 0.1049 +vn -0.9321 0.2883 -0.2193 +vn 0.4097 0.2883 -0.8655 +vn 0.0011 0.9855 0.1697 +vn 0.4117 -0.2726 -0.8696 +vn 0.4278 -0.0124 -0.9038 +vn -0.9366 -0.2726 -0.2203 +vn -0.9734 -0.0124 -0.2290 +vn -0.4232 -0.2726 -0.8640 +vn -0.4398 -0.0124 -0.8980 +vn -0.7562 -0.2726 0.5949 +vn -0.7859 -0.0124 0.6182 +vn -0.9394 -0.2726 -0.2078 +vn -0.9763 -0.0124 -0.2160 +vn -0.0064 -0.2726 0.9621 +vn -0.0067 -0.0124 0.9999 +vn -0.7482 -0.2726 0.6049 +vn -0.7776 -0.0124 0.6286 +vn 0.7482 -0.2726 0.6049 +vn 0.7776 -0.0124 0.6286 +vn 0.0064 -0.2726 0.9621 +vn 0.0067 -0.0124 0.9999 +vn 0.9394 -0.2726 -0.2078 +vn 0.9763 -0.0124 -0.2160 +vn 0.7562 -0.2726 0.5949 +vn 0.7859 -0.0124 0.6182 +vn 0.4232 -0.2726 -0.8640 +vn 0.4398 -0.0124 -0.8980 +vn 0.9366 -0.2726 -0.2203 +vn 0.9734 -0.0124 -0.2290 +vn -0.4117 -0.2726 -0.8696 +vn -0.4278 -0.0124 -0.9038 +vn 0.1334 0.9855 0.1049 +vn -0.0011 0.9855 0.1697 +vn 0.0726 0.9855 -0.1534 +vn 0.1652 0.9855 -0.0389 +vn 0.1320 0.9855 0.1067 +vn -0.0747 0.9855 -0.1524 +vn 0.1657 0.9855 -0.0367 +vn -0.1657 0.9855 -0.0367 +vn 0.0747 0.9855 -0.1524 +vn -0.1320 0.9855 0.1067 +vn -0.0726 0.9855 -0.1534 +vn -0.1652 0.9855 -0.0389 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 5/5/2 6/6/2 8/7/2 7/8/2 +f 9/9/3 10/10/3 12/11/3 11/12/3 +f 13/13/4 14/14/4 16/15/4 15/16/4 +f 17/17/5 18/18/5 20/19/5 19/20/5 +f 21/21/6 22/22/6 24/23/6 23/24/6 +f 25/25/7 26/26/7 28/27/7 27/28/7 +f 58/29/8 30/30/8 32/31/8 59/32/8 +f 59/32/9 32/31/9 34/33/9 61/34/9 +f 61/35/10 34/36/10 36/37/10 63/38/10 +f 63/38/11 36/37/11 38/39/11 65/40/11 +f 65/41/12 38/42/12 40/43/12 67/44/12 +f 67/44/13 40/43/13 42/45/13 69/46/13 +f 69/47/14 42/48/14 44/49/14 71/50/14 +f 71/50/15 44/49/15 46/51/15 73/52/15 +f 73/53/16 46/54/16 48/55/16 75/56/16 +f 75/56/17 48/55/17 50/57/17 77/58/17 +f 77/59/18 50/60/18 52/61/18 79/62/18 +f 79/62/19 52/61/19 54/63/19 81/64/19 +f 52/61/20 50/60/20 95/65/20 96/66/20 +f 81/67/21 54/68/21 56/69/21 83/70/21 +f 83/70/22 56/69/22 30/71/22 58/72/22 +f 42/45/23 40/43/23 90/73/23 91/74/23 +f 55/75/24 84/76/24 57/77/24 29/78/24 +f 84/76/25 83/70/25 58/72/25 57/77/25 +f 53/79/26 82/80/26 84/76/26 55/75/26 +f 82/80/27 81/67/27 83/70/27 84/76/27 +f 51/81/28 80/82/28 82/83/28 53/84/28 +f 80/82/29 79/62/29 81/64/29 82/83/29 +f 49/85/30 78/86/30 80/82/30 51/81/30 +f 78/86/31 77/59/31 79/62/31 80/82/31 +f 47/87/32 76/88/32 78/89/32 49/90/32 +f 76/88/33 75/56/33 77/58/33 78/89/33 +f 45/91/34 74/92/34 76/88/34 47/87/34 +f 74/92/35 73/53/35 75/56/35 76/88/35 +f 43/93/36 72/94/36 74/95/36 45/96/36 +f 72/94/37 71/50/37 73/52/37 74/95/37 +f 41/97/38 70/98/38 72/94/38 43/93/38 +f 70/98/39 69/47/39 71/50/39 72/94/39 +f 39/99/40 68/100/40 70/101/40 41/102/40 +f 68/100/41 67/44/41 69/46/41 70/101/41 +f 37/103/42 66/104/42 68/100/42 39/99/42 +f 66/104/43 65/41/43 67/44/43 68/100/43 +f 35/105/44 64/106/44 66/107/44 37/108/44 +f 64/106/45 63/38/45 65/40/45 66/107/45 +f 33/109/46 62/110/46 64/106/46 35/105/46 +f 62/110/47 61/35/47 63/38/47 64/106/47 +f 31/111/48 60/112/48 62/113/48 33/114/48 +f 60/112/49 59/32/49 61/34/49 62/113/49 +f 29/115/50 57/116/50 60/112/50 31/111/50 +f 57/116/51 58/29/51 59/32/51 60/112/51 +f 38/39/52 36/37/52 88/117/52 89/118/52 +f 48/55/53 46/54/53 93/119/53 94/120/53 +f 30/71/54 56/69/54 98/121/54 85/122/54 +f 34/33/55 32/31/55 86/123/55 87/124/55 +f 44/49/56 42/48/56 91/125/56 92/126/56 +f 54/63/57 52/61/57 96/66/57 97/127/57 +f 40/43/58 38/42/58 89/128/58 90/73/58 +f 50/57/59 48/55/59 94/120/59 95/129/59 +f 36/37/60 34/36/60 87/130/60 88/117/60 +f 46/51/61 44/49/61 92/126/61 93/131/61 +f 32/31/62 30/30/62 85/132/62 86/123/62 +f 56/69/63 54/68/63 97/133/63 98/121/63 +f 94/134/64 93/135/64 99/136/64 +f 87/137/64 86/138/64 99/136/64 +f 95/139/64 94/134/64 99/136/64 +f 88/140/64 87/137/64 99/136/64 +f 96/141/64 95/139/64 99/136/64 +f 89/142/64 88/140/64 99/136/64 +f 97/143/64 96/141/64 99/136/64 +f 90/144/64 89/142/64 99/136/64 +f 98/145/64 97/143/64 99/136/64 +f 91/146/64 90/144/64 99/136/64 +f 85/147/64 98/145/64 99/136/64 +f 92/148/64 91/146/64 99/136/64 +f 93/135/64 92/148/64 99/136/64 +f 86/138/64 85/147/64 99/136/64 diff --git a/mods/desert_life/models/dl_barrel_cacti_2.obj b/mods/desert_life/models/dl_barrel_cacti_2.obj new file mode 100644 index 0000000..0764c2b --- /dev/null +++ b/mods/desert_life/models/dl_barrel_cacti_2.obj @@ -0,0 +1,392 @@ +# Blender v2.77 (sub 1) OBJ File: 'Barrel_Cacti.blend' +# www.blender.org +o Barrel_Cacti_2_Plane +v -0.390916 -0.440789 0.311745 +v -0.263102 -0.440789 0.209817 +v -0.390916 0.447399 0.311745 +v -0.263102 0.447399 0.209817 +v -0.487464 -0.440789 -0.111260 +v -0.328083 -0.440789 -0.074883 +v -0.487464 0.447399 -0.111261 +v -0.328083 0.447399 -0.074883 +v -0.216942 -0.440789 -0.450484 +v -0.146011 -0.440789 -0.303194 +v -0.216942 0.447399 -0.450484 +v -0.146011 0.447399 -0.303194 +v 0.216942 -0.440789 -0.450484 +v 0.146010 -0.440789 -0.303194 +v 0.216942 0.447399 -0.450484 +v 0.146011 0.447399 -0.303194 +v 0.487464 -0.440789 -0.111260 +v 0.328083 -0.440789 -0.074883 +v 0.487464 0.447399 -0.111260 +v 0.328083 0.447399 -0.074883 +v 0.390916 -0.440789 0.311745 +v 0.263102 -0.440789 0.209817 +v 0.390916 0.447399 0.311745 +v 0.263102 0.447399 0.209817 +v -0.000000 -0.440789 0.500000 +v 0.000000 -0.440789 0.336520 +v -0.000000 0.447399 0.500000 +v -0.000000 0.447399 0.336520 +v 0.000000 -0.500000 -0.232527 +v 0.000000 0.447399 -0.246971 +v 0.145047 -0.500000 -0.301192 +v 0.154056 0.447399 -0.319901 +v 0.181797 -0.500000 -0.144978 +v 0.193090 0.447399 -0.153984 +v 0.325917 -0.500000 -0.074388 +v 0.346161 0.447399 -0.079009 +v 0.226697 -0.500000 0.051742 +v 0.240779 0.447399 0.054956 +v 0.261365 -0.500000 0.208432 +v 0.277600 0.447399 0.221379 +v 0.100890 -0.500000 0.209500 +v 0.107157 0.447399 0.222513 +v 0.000000 -0.500000 0.334298 +v 0.000000 0.447399 0.355064 +v -0.100890 -0.500000 0.209500 +v -0.107157 0.447399 0.222513 +v -0.261365 -0.500000 0.208432 +v -0.277600 0.447399 0.221379 +v -0.226697 -0.500000 0.051742 +v -0.240779 0.447399 0.054956 +v -0.325917 -0.500000 -0.074388 +v -0.346161 0.447399 -0.079009 +v -0.181797 -0.500000 -0.144978 +v -0.193090 0.447399 -0.153984 +v -0.145047 -0.500000 -0.301193 +v -0.154056 0.447399 -0.319901 +v 0.000000 -0.319369 -0.278227 +v 0.000000 0.204063 -0.278227 +v 0.173554 0.204063 -0.360388 +v 0.173554 -0.319369 -0.360388 +v 0.217527 0.204063 -0.173472 +v 0.217527 -0.319369 -0.173472 +v 0.389971 0.204063 -0.089008 +v 0.389971 -0.319369 -0.089008 +v 0.271251 0.204063 0.061911 +v 0.271251 -0.319369 0.061911 +v 0.312733 0.204063 0.249396 +v 0.312733 -0.319369 0.249396 +v 0.120718 0.204063 0.250674 +v 0.120718 -0.319369 0.250674 +v 0.000000 0.204063 0.400000 +v 0.000000 -0.319369 0.400000 +v -0.120718 0.204063 0.250674 +v -0.120718 -0.319369 0.250674 +v -0.312733 0.204063 0.249396 +v -0.312733 -0.319369 0.249396 +v -0.271251 0.204063 0.061911 +v -0.271251 -0.319369 0.061911 +v -0.389971 0.204063 -0.089008 +v -0.389971 -0.319369 -0.089008 +v -0.217527 0.204063 -0.173472 +v -0.217527 -0.319369 -0.173472 +v -0.173553 0.204063 -0.360388 +v -0.173553 -0.319369 -0.360388 +v 0.000000 0.495010 -0.015670 +v 0.009775 0.495010 -0.020298 +v 0.012252 0.495010 -0.009770 +v 0.021964 0.495010 -0.005013 +v 0.015278 0.495010 0.003487 +v 0.017614 0.495010 0.014047 +v 0.006799 0.495010 0.014119 +v 0.000000 0.495010 0.022529 +v -0.006799 0.495010 0.014119 +v -0.017614 0.495010 0.014047 +v -0.015277 0.495010 0.003487 +v -0.021964 0.495010 -0.005013 +v -0.012252 0.495010 -0.009770 +v -0.009775 0.495010 -0.020298 +v 0.000000 0.495010 -0.000000 +vt 0.8622 0.0740 +vt 1.0000 0.0740 +vt 1.0000 0.9172 +vt 0.8622 0.9172 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6276 0.6005 +vt 0.4947 0.7821 +vt 0.3154 0.7165 +vt 0.3153 0.5775 +vt 0.1349 0.7793 +vt 0.0185 0.6004 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3145 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.3209 0.9555 +vt 0.3092 0.9488 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3304 0.0639 +vt 0.3309 0.2107 +vt 0.0227 0.1898 +vt 0.0584 0.0353 +vt 0.5980 0.0384 +vt 0.6267 0.1901 +vt 0.3312 0.0643 +vt 0.3318 0.2111 +vt 0.0235 0.1901 +vt 0.0592 0.0357 +vt 0.5989 0.0388 +vt 0.6276 0.1905 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3210 0.9555 +vt 0.3093 0.9487 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3217 0.9559 +vt 0.3100 0.9491 +vt 0.2971 0.9554 +vt 0.3209 0.9555 +vt 0.2971 0.9554 +vt 0.3209 0.9555 +vt 0.2978 0.9558 +vt 0.3209 0.9555 +vt 0.3209 0.9555 +vt 0.2838 0.9515 +vt 0.3005 0.9515 +vt 0.3110 0.9619 +vt 0.3299 0.9692 +vt 0.3260 0.9770 +vt 0.2874 0.9593 +vt 0.3448 0.9656 +vt 0.2771 0.9656 +vt 0.3345 0.9593 +vt 0.2921 0.9692 +vt 0.3381 0.9515 +vt 0.2959 0.9770 +vt 0.3215 0.9515 +vt 0.3110 0.9735 +vt 0.3110 0.9452 +vn 0.6235 0.0000 0.7818 +vn -0.2225 0.0000 0.9749 +vn -0.9010 0.0000 0.4339 +vn -0.9010 0.0000 -0.4339 +vn -0.2225 0.0000 -0.9749 +vn 0.6235 0.0000 -0.7818 +vn 1.0000 0.0000 0.0000 +vn -0.4250 0.1153 -0.8978 +vn 0.9669 0.1153 -0.2275 +vn 0.4369 0.1153 -0.8921 +vn 0.7807 0.1153 0.6141 +vn 0.9699 0.1153 -0.2146 +vn 0.0066 0.1153 0.9933 +vn 0.7725 0.1153 0.6245 +vn -0.7725 0.1153 0.6245 +vn -0.0066 0.1153 0.9933 +vn -0.9699 0.1153 -0.2146 +vn -0.7807 0.1153 0.6141 +vn -0.4369 0.1153 -0.8921 +vn -0.1745 0.9750 0.1373 +vn -0.9669 0.1153 -0.2275 +vn 0.4250 0.1153 -0.8978 +vn 0.0015 0.9750 0.2221 +vn 0.4171 -0.2229 -0.8811 +vn 0.4279 0.0000 -0.9038 +vn -0.9489 -0.2229 -0.2232 +vn -0.9734 0.0000 -0.2290 +vn -0.4288 -0.2229 -0.8755 +vn -0.4399 0.0000 -0.8981 +vn -0.7662 -0.2229 0.6027 +vn -0.7860 0.0000 0.6183 +vn -0.9518 -0.2229 -0.2106 +vn -0.9764 0.0000 -0.2160 +vn -0.0065 -0.2229 0.9748 +vn -0.0067 0.0000 1.0000 +vn -0.7581 -0.2229 0.6129 +vn -0.7777 0.0000 0.6287 +vn 0.7581 -0.2229 0.6129 +vn 0.7777 0.0000 0.6287 +vn 0.0065 -0.2229 0.9748 +vn 0.0067 0.0000 1.0000 +vn 0.9518 -0.2229 -0.2106 +vn 0.9764 0.0000 -0.2160 +vn 0.7662 -0.2229 0.6027 +vn 0.7860 0.0000 0.6183 +vn 0.4288 -0.2229 -0.8755 +vn 0.4399 0.0000 -0.8981 +vn 0.9489 -0.2229 -0.2232 +vn 0.9734 0.0000 -0.2290 +vn -0.4171 -0.2229 -0.8811 +vn -0.4279 0.0000 -0.9038 +vn 0.1745 0.9750 0.1373 +vn -0.0015 0.9750 0.2221 +vn 0.0950 0.9750 -0.2007 +vn 0.2162 0.9750 -0.0509 +vn 0.1727 0.9750 0.1396 +vn -0.0977 0.9750 -0.1994 +vn 0.2168 0.9750 -0.0480 +vn -0.2168 0.9750 -0.0480 +vn 0.0977 0.9750 -0.1994 +vn -0.1727 0.9750 0.1396 +vn -0.0950 0.9750 -0.2007 +vn -0.2162 0.9750 -0.0509 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 5/5/2 6/6/2 8/7/2 7/8/2 +f 9/9/3 10/10/3 12/11/3 11/12/3 +f 13/13/4 14/14/4 16/15/4 15/16/4 +f 17/17/5 18/18/5 20/19/5 19/20/5 +f 21/21/6 22/22/6 24/23/6 23/24/6 +f 25/25/7 26/26/7 28/27/7 27/28/7 +f 58/29/8 30/30/8 32/31/8 59/32/8 +f 59/32/9 32/31/9 34/33/9 61/34/9 +f 61/35/10 34/36/10 36/37/10 63/38/10 +f 63/38/11 36/37/11 38/39/11 65/40/11 +f 65/41/12 38/42/12 40/43/12 67/44/12 +f 67/44/13 40/43/13 42/45/13 69/46/13 +f 69/47/14 42/48/14 44/49/14 71/50/14 +f 71/50/15 44/49/15 46/51/15 73/52/15 +f 73/53/16 46/54/16 48/55/16 75/56/16 +f 75/56/17 48/55/17 50/57/17 77/58/17 +f 77/59/18 50/60/18 52/61/18 79/62/18 +f 79/62/19 52/61/19 54/63/19 81/64/19 +f 52/61/20 50/60/20 95/65/20 96/66/20 +f 81/67/21 54/68/21 56/69/21 83/70/21 +f 83/70/22 56/69/22 30/71/22 58/72/22 +f 42/45/23 40/43/23 90/73/23 91/74/23 +f 55/75/24 84/76/24 57/77/24 29/78/24 +f 84/76/25 83/70/25 58/72/25 57/77/25 +f 53/79/26 82/80/26 84/76/26 55/75/26 +f 82/80/27 81/67/27 83/70/27 84/76/27 +f 51/81/28 80/82/28 82/83/28 53/84/28 +f 80/82/29 79/62/29 81/64/29 82/83/29 +f 49/85/30 78/86/30 80/82/30 51/81/30 +f 78/86/31 77/59/31 79/62/31 80/82/31 +f 47/87/32 76/88/32 78/89/32 49/90/32 +f 76/88/33 75/56/33 77/58/33 78/89/33 +f 45/91/34 74/92/34 76/88/34 47/87/34 +f 74/92/35 73/53/35 75/56/35 76/88/35 +f 43/93/36 72/94/36 74/95/36 45/96/36 +f 72/94/37 71/50/37 73/52/37 74/95/37 +f 41/97/38 70/98/38 72/94/38 43/93/38 +f 70/98/39 69/47/39 71/50/39 72/94/39 +f 39/99/40 68/100/40 70/101/40 41/102/40 +f 68/100/41 67/44/41 69/46/41 70/101/41 +f 37/103/42 66/104/42 68/100/42 39/99/42 +f 66/104/43 65/41/43 67/44/43 68/100/43 +f 35/105/44 64/106/44 66/107/44 37/108/44 +f 64/106/45 63/38/45 65/40/45 66/107/45 +f 33/109/46 62/110/46 64/106/46 35/105/46 +f 62/110/47 61/35/47 63/38/47 64/106/47 +f 31/111/48 60/112/48 62/113/48 33/114/48 +f 60/112/49 59/32/49 61/34/49 62/113/49 +f 29/115/50 57/116/50 60/112/50 31/111/50 +f 57/116/51 58/29/51 59/32/51 60/112/51 +f 38/39/52 36/37/52 88/117/52 89/118/52 +f 48/55/53 46/54/53 93/119/53 94/120/53 +f 30/71/54 56/69/54 98/121/54 85/122/54 +f 34/33/55 32/31/55 86/123/55 87/124/55 +f 44/49/56 42/48/56 91/125/56 92/126/56 +f 54/63/57 52/61/57 96/66/57 97/127/57 +f 40/43/58 38/42/58 89/128/58 90/73/58 +f 50/57/59 48/55/59 94/120/59 95/129/59 +f 36/37/60 34/36/60 87/130/60 88/117/60 +f 46/51/61 44/49/61 92/126/61 93/131/61 +f 32/31/62 30/30/62 85/132/62 86/123/62 +f 56/69/63 54/68/63 97/133/63 98/121/63 +f 94/134/64 93/135/64 99/136/64 +f 87/137/64 86/138/64 99/136/64 +f 95/139/64 94/134/64 99/136/64 +f 88/140/64 87/137/64 99/136/64 +f 96/141/64 95/139/64 99/136/64 +f 89/142/64 88/140/64 99/136/64 +f 97/143/64 96/141/64 99/136/64 +f 90/144/64 89/142/64 99/136/64 +f 98/145/64 97/143/64 99/136/64 +f 91/146/64 90/144/64 99/136/64 +f 85/147/64 98/145/64 99/136/64 +f 92/148/64 91/146/64 99/136/64 +f 93/135/64 92/148/64 99/136/64 +f 86/138/64 85/147/64 99/136/64 diff --git a/mods/desert_life/models/dl_barrel_cacti_3.obj b/mods/desert_life/models/dl_barrel_cacti_3.obj new file mode 100644 index 0000000..754e5bb --- /dev/null +++ b/mods/desert_life/models/dl_barrel_cacti_3.obj @@ -0,0 +1,392 @@ +# Blender v2.77 (sub 1) OBJ File: 'Barrel_Cacti.blend' +# www.blender.org +o Barrel_Cacti_3_Plane.003 +v -0.418356 -0.440789 0.333627 +v -0.281570 -0.440789 0.224545 +v -0.418356 0.776488 0.333627 +v -0.281570 0.776488 0.224544 +v -0.521681 -0.440789 -0.119070 +v -0.351112 -0.440789 -0.080139 +v -0.521681 0.776488 -0.119070 +v -0.351112 0.776488 -0.080139 +v -0.232170 -0.440789 -0.482105 +v -0.156260 -0.440789 -0.324476 +v -0.232170 0.776488 -0.482106 +v -0.156259 0.776488 -0.324476 +v 0.232170 -0.440789 -0.482105 +v 0.156259 -0.440789 -0.324476 +v 0.232170 0.776488 -0.482105 +v 0.156260 0.776488 -0.324476 +v 0.521681 -0.440789 -0.119070 +v 0.351112 -0.440789 -0.080139 +v 0.521681 0.776488 -0.119070 +v 0.351112 0.776488 -0.080139 +v 0.418355 -0.440789 0.333627 +v 0.281570 -0.440789 0.224545 +v 0.418355 0.776488 0.333627 +v 0.281570 0.776488 0.224544 +v -0.000000 -0.440789 0.535097 +v 0.000000 -0.440789 0.360141 +v -0.000000 0.776488 0.535097 +v -0.000000 0.776488 0.360141 +v 0.000000 -0.500000 -0.232527 +v 0.000000 0.776488 -0.246971 +v 0.145047 -0.500000 -0.301192 +v 0.154056 0.776488 -0.319901 +v 0.181797 -0.500000 -0.144978 +v 0.193090 0.776488 -0.153984 +v 0.325917 -0.500000 -0.074388 +v 0.346161 0.776488 -0.079009 +v 0.226697 -0.500000 0.051742 +v 0.240779 0.776488 0.054956 +v 0.261365 -0.500000 0.208432 +v 0.277600 0.776488 0.221379 +v 0.100890 -0.500000 0.209500 +v 0.107157 0.776488 0.222513 +v 0.000000 -0.500000 0.334298 +v 0.000000 0.776488 0.355064 +v -0.100890 -0.500000 0.209500 +v -0.107157 0.776488 0.222513 +v -0.261365 -0.500000 0.208432 +v -0.277600 0.776488 0.221379 +v -0.226697 -0.500000 0.051742 +v -0.240779 0.776488 0.054956 +v -0.325917 -0.500000 -0.074388 +v -0.346161 0.776488 -0.079009 +v -0.181797 -0.500000 -0.144978 +v -0.193090 0.776488 -0.153984 +v -0.145047 -0.500000 -0.301193 +v -0.154056 0.776488 -0.319901 +v 0.000000 -0.319369 -0.297763 +v 0.000000 0.533152 -0.297763 +v 0.185740 0.533152 -0.385693 +v 0.185740 -0.319369 -0.385693 +v 0.232801 0.533152 -0.185652 +v 0.232801 -0.319369 -0.185652 +v 0.417353 0.533152 -0.095258 +v 0.417353 -0.319369 -0.095258 +v 0.290298 0.533152 0.066259 +v 0.290298 -0.319369 0.066259 +v 0.334691 0.533152 0.266908 +v 0.334691 -0.319369 0.266908 +v 0.129195 0.533152 0.268275 +v 0.129195 -0.319369 0.268275 +v 0.000000 0.533152 0.428086 +v 0.000000 -0.319369 0.428086 +v -0.129195 0.533152 0.268275 +v -0.129195 -0.319369 0.268275 +v -0.334691 0.533152 0.266908 +v -0.334691 -0.319369 0.266908 +v -0.290298 0.533152 0.066259 +v -0.290298 -0.319369 0.066259 +v -0.417353 0.533152 -0.095258 +v -0.417353 -0.319369 -0.095258 +v -0.232801 0.533152 -0.185652 +v -0.232801 -0.319369 -0.185652 +v -0.185740 0.533152 -0.385693 +v -0.185740 -0.319369 -0.385693 +v 0.000000 0.824099 -0.015670 +v 0.009775 0.824099 -0.020298 +v 0.012252 0.824099 -0.009770 +v 0.021964 0.824099 -0.005013 +v 0.015278 0.824099 0.003487 +v 0.017614 0.824099 0.014047 +v 0.006799 0.824099 0.014119 +v 0.000000 0.824099 0.022529 +v -0.006799 0.824099 0.014119 +v -0.017614 0.824099 0.014047 +v -0.015277 0.824099 0.003487 +v -0.021964 0.824099 -0.005013 +v -0.012252 0.824099 -0.009770 +v -0.009775 0.824099 -0.020298 +v 0.000000 0.824099 -0.000000 +vt 0.8622 0.0740 +vt 1.0000 0.0740 +vt 1.0000 0.9172 +vt 0.8622 0.9172 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.8619 0.0737 +vt 0.9997 0.0737 +vt 0.9997 0.9169 +vt 0.8619 0.9169 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6276 0.6005 +vt 0.4947 0.7821 +vt 0.3154 0.7165 +vt 0.3153 0.5775 +vt 0.1349 0.7793 +vt 0.0185 0.6004 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3145 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.3209 0.9555 +vt 0.3092 0.9488 +vt 0.6268 0.6002 +vt 0.4940 0.7818 +vt 0.3146 0.7161 +vt 0.3146 0.5771 +vt 0.1342 0.7789 +vt 0.0177 0.6000 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3304 0.0639 +vt 0.3309 0.2107 +vt 0.0227 0.1898 +vt 0.0584 0.0353 +vt 0.5980 0.0384 +vt 0.6267 0.1901 +vt 0.3312 0.0643 +vt 0.3318 0.2111 +vt 0.0235 0.1901 +vt 0.0592 0.0357 +vt 0.5989 0.0388 +vt 0.6276 0.1905 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3305 0.0640 +vt 0.3310 0.2107 +vt 0.0228 0.1898 +vt 0.0585 0.0353 +vt 0.5981 0.0384 +vt 0.6268 0.1901 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3210 0.9555 +vt 0.3093 0.9487 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3092 0.9488 +vt 0.2971 0.9554 +vt 0.3217 0.9559 +vt 0.3100 0.9491 +vt 0.2971 0.9554 +vt 0.3209 0.9555 +vt 0.2971 0.9554 +vt 0.3209 0.9555 +vt 0.2978 0.9558 +vt 0.3209 0.9555 +vt 0.3209 0.9555 +vt 0.2838 0.9515 +vt 0.3005 0.9515 +vt 0.3110 0.9619 +vt 0.3299 0.9692 +vt 0.3260 0.9770 +vt 0.2874 0.9593 +vt 0.3448 0.9656 +vt 0.2771 0.9656 +vt 0.3345 0.9593 +vt 0.2921 0.9692 +vt 0.3381 0.9515 +vt 0.2959 0.9770 +vt 0.3215 0.9515 +vt 0.3110 0.9735 +vt 0.3110 0.9452 +vn 0.6235 0.0000 0.7818 +vn -0.2225 0.0000 0.9749 +vn -0.9010 0.0000 0.4339 +vn -0.9010 0.0000 -0.4339 +vn -0.2225 0.0000 -0.9749 +vn 0.6235 0.0000 -0.7818 +vn 1.0000 0.0000 0.0000 +vn -0.4205 0.1854 -0.8882 +vn 0.9566 0.1854 -0.2250 +vn 0.4322 0.1854 -0.8825 +vn 0.7723 0.1854 0.6076 +vn 0.9595 0.1854 -0.2123 +vn 0.0065 0.1854 0.9826 +vn 0.7642 0.1854 0.6178 +vn -0.7642 0.1854 0.6178 +vn -0.0065 0.1854 0.9826 +vn -0.9595 0.1854 -0.2123 +vn -0.7723 0.1854 0.6076 +vn -0.4322 0.1854 -0.8825 +vn -0.1745 0.9750 0.1373 +vn -0.9566 0.1854 -0.2250 +vn 0.4205 0.1854 -0.8882 +vn 0.0015 0.9750 0.2221 +vn 0.4068 -0.3103 -0.8592 +vn 0.4279 0.0000 -0.9038 +vn -0.9254 -0.3103 -0.2177 +vn -0.9734 0.0000 -0.2290 +vn -0.4182 -0.3103 -0.8537 +vn -0.4399 0.0000 -0.8981 +vn -0.7472 -0.3103 0.5878 +vn -0.7860 0.0000 0.6183 +vn -0.9282 -0.3103 -0.2054 +vn -0.9764 0.0000 -0.2160 +vn -0.0063 -0.3103 0.9506 +vn -0.0067 0.0000 1.0000 +vn -0.7393 -0.3103 0.5976 +vn -0.7777 0.0000 0.6287 +vn 0.7393 -0.3103 0.5976 +vn 0.7777 0.0000 0.6287 +vn 0.0063 -0.3103 0.9506 +vn 0.0067 0.0000 1.0000 +vn 0.9282 -0.3103 -0.2054 +vn 0.9764 0.0000 -0.2160 +vn 0.7472 -0.3103 0.5878 +vn 0.7860 0.0000 0.6183 +vn 0.4182 -0.3103 -0.8537 +vn 0.4399 0.0000 -0.8981 +vn 0.9254 -0.3103 -0.2177 +vn 0.9734 0.0000 -0.2290 +vn -0.4068 -0.3103 -0.8592 +vn -0.4279 0.0000 -0.9038 +vn 0.1745 0.9750 0.1373 +vn -0.0015 0.9750 0.2221 +vn 0.0950 0.9750 -0.2007 +vn 0.2162 0.9750 -0.0509 +vn 0.1727 0.9750 0.1396 +vn -0.0977 0.9750 -0.1994 +vn 0.2168 0.9750 -0.0480 +vn -0.2168 0.9750 -0.0480 +vn 0.0977 0.9750 -0.1994 +vn -0.1727 0.9750 0.1396 +vn -0.0950 0.9750 -0.2007 +vn -0.2162 0.9750 -0.0509 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 5/5/2 6/6/2 8/7/2 7/8/2 +f 9/9/3 10/10/3 12/11/3 11/12/3 +f 13/13/4 14/14/4 16/15/4 15/16/4 +f 17/17/5 18/18/5 20/19/5 19/20/5 +f 21/21/6 22/22/6 24/23/6 23/24/6 +f 25/25/7 26/26/7 28/27/7 27/28/7 +f 58/29/8 30/30/8 32/31/8 59/32/8 +f 59/32/9 32/31/9 34/33/9 61/34/9 +f 61/35/10 34/36/10 36/37/10 63/38/10 +f 63/38/11 36/37/11 38/39/11 65/40/11 +f 65/41/12 38/42/12 40/43/12 67/44/12 +f 67/44/13 40/43/13 42/45/13 69/46/13 +f 69/47/14 42/48/14 44/49/14 71/50/14 +f 71/50/15 44/49/15 46/51/15 73/52/15 +f 73/53/16 46/54/16 48/55/16 75/56/16 +f 75/56/17 48/55/17 50/57/17 77/58/17 +f 77/59/18 50/60/18 52/61/18 79/62/18 +f 79/62/19 52/61/19 54/63/19 81/64/19 +f 52/61/20 50/60/20 95/65/20 96/66/20 +f 81/67/21 54/68/21 56/69/21 83/70/21 +f 83/70/22 56/69/22 30/71/22 58/72/22 +f 42/45/23 40/43/23 90/73/23 91/74/23 +f 55/75/24 84/76/24 57/77/24 29/78/24 +f 84/76/25 83/70/25 58/72/25 57/77/25 +f 53/79/26 82/80/26 84/76/26 55/75/26 +f 82/80/27 81/67/27 83/70/27 84/76/27 +f 51/81/28 80/82/28 82/83/28 53/84/28 +f 80/82/29 79/62/29 81/64/29 82/83/29 +f 49/85/30 78/86/30 80/82/30 51/81/30 +f 78/86/31 77/59/31 79/62/31 80/82/31 +f 47/87/32 76/88/32 78/89/32 49/90/32 +f 76/88/33 75/56/33 77/58/33 78/89/33 +f 45/91/34 74/92/34 76/88/34 47/87/34 +f 74/92/35 73/53/35 75/56/35 76/88/35 +f 43/93/36 72/94/36 74/95/36 45/96/36 +f 72/94/37 71/50/37 73/52/37 74/95/37 +f 41/97/38 70/98/38 72/94/38 43/93/38 +f 70/98/39 69/47/39 71/50/39 72/94/39 +f 39/99/40 68/100/40 70/101/40 41/102/40 +f 68/100/41 67/44/41 69/46/41 70/101/41 +f 37/103/42 66/104/42 68/100/42 39/99/42 +f 66/104/43 65/41/43 67/44/43 68/100/43 +f 35/105/44 64/106/44 66/107/44 37/108/44 +f 64/106/45 63/38/45 65/40/45 66/107/45 +f 33/109/46 62/110/46 64/106/46 35/105/46 +f 62/110/47 61/35/47 63/38/47 64/106/47 +f 31/111/48 60/112/48 62/113/48 33/114/48 +f 60/112/49 59/32/49 61/34/49 62/113/49 +f 29/115/50 57/116/50 60/112/50 31/111/50 +f 57/116/51 58/29/51 59/32/51 60/112/51 +f 38/39/52 36/37/52 88/117/52 89/118/52 +f 48/55/53 46/54/53 93/119/53 94/120/53 +f 30/71/54 56/69/54 98/121/54 85/122/54 +f 34/33/55 32/31/55 86/123/55 87/124/55 +f 44/49/56 42/48/56 91/125/56 92/126/56 +f 54/63/57 52/61/57 96/66/57 97/127/57 +f 40/43/58 38/42/58 89/128/58 90/73/58 +f 50/57/59 48/55/59 94/120/59 95/129/59 +f 36/37/60 34/36/60 87/130/60 88/117/60 +f 46/51/61 44/49/61 92/126/61 93/131/61 +f 32/31/62 30/30/62 85/132/62 86/123/62 +f 56/69/63 54/68/63 97/133/63 98/121/63 +f 94/134/64 93/135/64 99/136/64 +f 87/137/64 86/138/64 99/136/64 +f 95/139/64 94/134/64 99/136/64 +f 88/140/64 87/137/64 99/136/64 +f 96/141/64 95/139/64 99/136/64 +f 89/142/64 88/140/64 99/136/64 +f 97/143/64 96/141/64 99/136/64 +f 90/144/64 89/142/64 99/136/64 +f 98/145/64 97/143/64 99/136/64 +f 91/146/64 90/144/64 99/136/64 +f 85/147/64 98/145/64 99/136/64 +f 92/148/64 91/146/64 99/136/64 +f 93/135/64 92/148/64 99/136/64 +f 86/138/64 85/147/64 99/136/64 diff --git a/mods/desert_life/models/dl_ostrich.b3d b/mods/desert_life/models/dl_ostrich.b3d new file mode 100644 index 0000000..0634125 Binary files /dev/null and b/mods/desert_life/models/dl_ostrich.b3d differ diff --git a/mods/desert_life/models/dl_pp_1.obj b/mods/desert_life/models/dl_pp_1.obj new file mode 100644 index 0000000..66dc55d --- /dev/null +++ b/mods/desert_life/models/dl_pp_1.obj @@ -0,0 +1,45 @@ +# Blender v2.76 (sub 0) OBJ File: 'Prickly_Pear.blend' +# www.blender.org +o PricklyPear_1_Cube.001 +v -0.100000 -0.500000 0.050000 +v -0.200000 -0.200000 0.100000 +v -0.100000 -0.500000 -0.050000 +v -0.200000 -0.200000 -0.100000 +v 0.100000 -0.500000 0.050000 +v 0.200000 -0.200000 0.100000 +v 0.100000 -0.500000 -0.050000 +v 0.200000 -0.200000 -0.100000 +v -0.100000 -0.000000 0.050000 +v -0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 0.050000 +vt 0.563911 0.641438 +vt 0.451166 0.589250 +vt 0.555243 0.317470 +vt 0.668040 0.353694 +vt 0.192184 0.493691 +vt 0.337870 0.241378 +vt 0.000096 0.422585 +vt 0.249733 0.176371 +vt 0.886954 0.820395 +vt 0.913299 0.401556 +vt 0.379745 0.000096 +vt 0.467883 0.065102 +vt 0.473694 0.814299 +vt 0.370314 0.772975 +vt 0.015003 0.724495 +vt 0.148981 0.731949 +vt 0.134073 0.999904 +vt 0.000096 0.992450 +vt 0.658934 0.945657 +s off +f 2/1 4/2 3/3 1/4 +f 4/2 8/5 7/6 3/3 +f 8/5 6/7 5/8 7/6 +f 6/9 2/1 1/4 5/10 +f 1/11 3/12 7/6 5/8 +f 4/2 2/1 9/13 10/14 +f 12/15 11/16 10/17 9/18 +f 2/1 6/9 12/19 9/13 +f 8/5 4/2 10/14 11/16 +f 6/7 8/5 11/16 12/15 diff --git a/mods/desert_life/models/dl_pp_2.obj b/mods/desert_life/models/dl_pp_2.obj new file mode 100644 index 0000000..ef388df --- /dev/null +++ b/mods/desert_life/models/dl_pp_2.obj @@ -0,0 +1,67 @@ +# Blender v2.76 (sub 0) OBJ File: 'Prickly_Pear.blend' +# www.blender.org +o PricklyPear_2_Cube.006 +v -0.100000 -0.500000 0.050000 +v -0.200000 -0.200000 0.100000 +v -0.100000 -0.500000 -0.050000 +v -0.200000 -0.200000 -0.100000 +v 0.100000 -0.500000 0.050000 +v 0.200000 -0.200000 0.100000 +v 0.100000 -0.500000 -0.050000 +v 0.200000 -0.200000 -0.100000 +v -0.100000 -0.000000 0.050000 +v -0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 0.050000 +v 0.101978 -0.012272 0.050000 +v 0.322747 0.214136 0.100000 +v 0.101978 -0.012272 -0.050000 +v 0.322747 0.214136 -0.100000 +v 0.193669 -0.190016 0.050000 +v 0.506130 -0.141350 0.100000 +v 0.193669 -0.190016 -0.050000 +v 0.506130 -0.141350 -0.100000 +v 0.546336 0.216956 0.050000 +v 0.546336 0.216956 -0.050000 +v 0.638028 0.039213 -0.050000 +v 0.638028 0.039213 0.050000 +vt 0.563911 0.641438 +vt 0.451166 0.589250 +vt 0.555243 0.317470 +vt 0.668040 0.353694 +vt 0.192184 0.493691 +vt 0.337870 0.241378 +vt 0.000096 0.422585 +vt 0.249733 0.176371 +vt 0.886954 0.820395 +vt 0.913299 0.401556 +vt 0.379745 0.000096 +vt 0.467883 0.065102 +vt 0.473694 0.814299 +vt 0.370314 0.772975 +vt 0.015003 0.724495 +vt 0.148981 0.731949 +vt 0.134073 0.999904 +vt 0.000096 0.992450 +vt 0.658934 0.945657 +s off +f 2/1 4/2 3/3 1/4 +f 4/2 8/5 7/6 3/3 +f 8/5 6/7 5/8 7/6 +f 6/9 2/1 1/4 5/10 +f 1/11 3/12 7/6 5/8 +f 4/2 2/1 9/13 10/14 +f 12/15 11/16 10/17 9/18 +f 2/1 6/9 12/19 9/13 +f 8/5 4/2 10/14 11/16 +f 6/7 8/5 11/16 12/15 +f 14/1 16/2 15/3 13/4 +f 16/2 20/5 19/6 15/3 +f 20/5 18/7 17/8 19/6 +f 18/9 14/1 13/4 17/10 +f 13/11 15/12 19/6 17/8 +f 16/2 14/1 21/13 22/14 +f 24/15 23/16 22/17 21/18 +f 14/1 18/9 24/19 21/13 +f 20/5 16/2 22/14 23/16 +f 18/7 20/5 23/16 24/15 diff --git a/mods/desert_life/models/dl_pp_3.obj b/mods/desert_life/models/dl_pp_3.obj new file mode 100644 index 0000000..782e2a7 --- /dev/null +++ b/mods/desert_life/models/dl_pp_3.obj @@ -0,0 +1,89 @@ +# Blender v2.76 (sub 0) OBJ File: 'Prickly_Pear.blend' +# www.blender.org +o PricklyPear_3_Cube.007 +v -0.100000 -0.500000 0.050000 +v -0.200000 -0.200000 0.100000 +v -0.100000 -0.500000 -0.050000 +v -0.200000 -0.200000 -0.100000 +v 0.100000 -0.500000 0.050000 +v 0.200000 -0.200000 0.100000 +v 0.100000 -0.500000 -0.050000 +v 0.200000 -0.200000 -0.100000 +v -0.100000 -0.000000 0.050000 +v -0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 0.050000 +v 0.101978 -0.012272 0.050000 +v 0.322747 0.214136 0.100000 +v 0.101978 -0.012272 -0.050000 +v 0.322747 0.214136 -0.100000 +v 0.193669 -0.190016 0.050000 +v 0.506130 -0.141350 0.100000 +v 0.193669 -0.190016 -0.050000 +v 0.506130 -0.141350 -0.100000 +v 0.546336 0.216956 0.050000 +v 0.546336 0.216956 -0.050000 +v 0.638028 0.039213 -0.050000 +v 0.638028 0.039213 0.050000 +v -0.182689 -0.196467 0.050000 +v -0.496058 -0.154043 0.100000 +v -0.182689 -0.196467 -0.050000 +v -0.496058 -0.154043 -0.100000 +v -0.094561 -0.016930 0.050000 +v -0.319802 0.205031 0.100000 +v -0.094561 -0.016930 -0.050000 +v -0.319802 0.205031 -0.100000 +v -0.631531 0.023854 0.050000 +v -0.631531 0.023854 -0.050000 +v -0.543403 0.203390 -0.050000 +v -0.543403 0.203390 0.050000 +vt 0.563911 0.641438 +vt 0.451166 0.589250 +vt 0.555243 0.317470 +vt 0.668040 0.353694 +vt 0.192184 0.493691 +vt 0.337870 0.241378 +vt 0.000096 0.422585 +vt 0.249733 0.176371 +vt 0.886954 0.820395 +vt 0.913299 0.401556 +vt 0.379745 0.000096 +vt 0.467883 0.065102 +vt 0.473694 0.814299 +vt 0.370314 0.772975 +vt 0.015003 0.724495 +vt 0.148981 0.731949 +vt 0.134073 0.999904 +vt 0.000096 0.992450 +vt 0.658934 0.945657 +s off +f 2/1 4/2 3/3 1/4 +f 4/2 8/5 7/6 3/3 +f 8/5 6/7 5/8 7/6 +f 6/9 2/1 1/4 5/10 +f 1/11 3/12 7/6 5/8 +f 4/2 2/1 9/13 10/14 +f 12/15 11/16 10/17 9/18 +f 2/1 6/9 12/19 9/13 +f 8/5 4/2 10/14 11/16 +f 6/7 8/5 11/16 12/15 +f 14/1 16/2 15/3 13/4 +f 16/2 20/5 19/6 15/3 +f 20/5 18/7 17/8 19/6 +f 18/9 14/1 13/4 17/10 +f 13/11 15/12 19/6 17/8 +f 16/2 14/1 21/13 22/14 +f 24/15 23/16 22/17 21/18 +f 14/1 18/9 24/19 21/13 +f 20/5 16/2 22/14 23/16 +f 18/7 20/5 23/16 24/15 +f 26/1 28/2 27/3 25/4 +f 28/2 32/5 31/6 27/3 +f 32/5 30/7 29/8 31/6 +f 30/9 26/1 25/4 29/10 +f 25/11 27/12 31/6 29/8 +f 28/2 26/1 33/13 34/14 +f 36/15 35/16 34/17 33/18 +f 26/1 30/9 36/19 33/13 +f 32/5 28/2 34/14 35/16 +f 30/7 32/5 35/16 36/15 diff --git a/mods/desert_life/models/dl_pp_4.obj b/mods/desert_life/models/dl_pp_4.obj new file mode 100644 index 0000000..d3a542b --- /dev/null +++ b/mods/desert_life/models/dl_pp_4.obj @@ -0,0 +1,111 @@ +# Blender v2.76 (sub 0) OBJ File: 'Prickly_Pear.blend' +# www.blender.org +o PricklyPear_4_Cube.008 +v -0.100000 -0.500000 0.050000 +v -0.200000 -0.200000 0.100000 +v -0.100000 -0.500000 -0.050000 +v -0.200000 -0.200000 -0.100000 +v 0.100000 -0.500000 0.050000 +v 0.200000 -0.200000 0.100000 +v 0.100000 -0.500000 -0.050000 +v 0.200000 -0.200000 -0.100000 +v -0.100000 -0.000000 0.050000 +v -0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 0.050000 +v 0.101978 -0.012272 0.050000 +v 0.322747 0.214136 0.100000 +v 0.101978 -0.012272 -0.050000 +v 0.322747 0.214136 -0.100000 +v 0.193669 -0.190016 0.050000 +v 0.506130 -0.141350 0.100000 +v 0.193669 -0.190016 -0.050000 +v 0.506130 -0.141350 -0.100000 +v 0.546336 0.216956 0.050000 +v 0.546336 0.216956 -0.050000 +v 0.638028 0.039213 -0.050000 +v 0.638028 0.039213 0.050000 +v -0.182689 -0.196467 0.050000 +v -0.496058 -0.154043 0.100000 +v -0.182689 -0.196467 -0.050000 +v -0.496058 -0.154043 -0.100000 +v -0.094561 -0.016930 0.050000 +v -0.319802 0.205031 0.100000 +v -0.094561 -0.016930 -0.050000 +v -0.319802 0.205031 -0.100000 +v -0.631531 0.023854 0.050000 +v -0.631531 0.023854 -0.050000 +v -0.543403 0.203390 -0.050000 +v -0.543403 0.203390 0.050000 +v -0.100000 -0.041188 0.043582 +v -0.200000 0.235648 0.169524 +v -0.100000 -0.015306 -0.053010 +v -0.200000 0.287412 -0.023661 +v 0.100000 -0.041188 0.043582 +v 0.200000 0.235648 0.169524 +v 0.100000 -0.015306 -0.053010 +v 0.200000 0.287412 -0.023661 +v -0.100000 0.441774 0.172992 +v -0.100000 0.467656 0.076399 +v 0.100000 0.467656 0.076399 +v 0.100000 0.441774 0.172992 +vt 0.563911 0.641438 +vt 0.451166 0.589250 +vt 0.555243 0.317470 +vt 0.668040 0.353694 +vt 0.192184 0.493691 +vt 0.337870 0.241378 +vt 0.000096 0.422585 +vt 0.249733 0.176371 +vt 0.886954 0.820395 +vt 0.913299 0.401556 +vt 0.379745 0.000096 +vt 0.467883 0.065102 +vt 0.473694 0.814299 +vt 0.370314 0.772975 +vt 0.015003 0.724495 +vt 0.148981 0.731949 +vt 0.134073 0.999904 +vt 0.000096 0.992450 +vt 0.658934 0.945657 +s off +f 2/1 4/2 3/3 1/4 +f 4/2 8/5 7/6 3/3 +f 8/5 6/7 5/8 7/6 +f 6/9 2/1 1/4 5/10 +f 1/11 3/12 7/6 5/8 +f 4/2 2/1 9/13 10/14 +f 12/15 11/16 10/17 9/18 +f 2/1 6/9 12/19 9/13 +f 8/5 4/2 10/14 11/16 +f 6/7 8/5 11/16 12/15 +f 14/1 16/2 15/3 13/4 +f 16/2 20/5 19/6 15/3 +f 20/5 18/7 17/8 19/6 +f 18/9 14/1 13/4 17/10 +f 13/11 15/12 19/6 17/8 +f 16/2 14/1 21/13 22/14 +f 24/15 23/16 22/17 21/18 +f 14/1 18/9 24/19 21/13 +f 20/5 16/2 22/14 23/16 +f 18/7 20/5 23/16 24/15 +f 26/1 28/2 27/3 25/4 +f 28/2 32/5 31/6 27/3 +f 32/5 30/7 29/8 31/6 +f 30/9 26/1 25/4 29/10 +f 25/11 27/12 31/6 29/8 +f 28/2 26/1 33/13 34/14 +f 36/15 35/16 34/17 33/18 +f 26/1 30/9 36/19 33/13 +f 32/5 28/2 34/14 35/16 +f 30/7 32/5 35/16 36/15 +f 38/1 40/2 39/3 37/4 +f 40/2 44/5 43/6 39/3 +f 44/5 42/7 41/8 43/6 +f 42/9 38/1 37/4 41/10 +f 37/11 39/12 43/6 41/8 +f 40/2 38/1 45/13 46/14 +f 48/15 47/16 46/17 45/18 +f 38/1 42/9 48/19 45/13 +f 44/5 40/2 46/14 47/16 +f 42/7 44/5 47/16 48/15 diff --git a/mods/desert_life/models/dl_pp_5.obj b/mods/desert_life/models/dl_pp_5.obj new file mode 100644 index 0000000..8d838a8 --- /dev/null +++ b/mods/desert_life/models/dl_pp_5.obj @@ -0,0 +1,133 @@ +# Blender v2.76 (sub 0) OBJ File: 'Prickly_Pear.blend' +# www.blender.org +o PricklyPear_5_Cube.009 +v -0.100000 -0.500000 0.050000 +v -0.200000 -0.200000 0.100000 +v -0.100000 -0.500000 -0.050000 +v -0.200000 -0.200000 -0.100000 +v 0.100000 -0.500000 0.050000 +v 0.200000 -0.200000 0.100000 +v 0.100000 -0.500000 -0.050000 +v 0.200000 -0.200000 -0.100000 +v -0.100000 -0.000000 0.050000 +v -0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 0.050000 +v 0.101978 -0.012272 0.050000 +v 0.322747 0.214136 0.100000 +v 0.101978 -0.012272 -0.050000 +v 0.322747 0.214136 -0.100000 +v 0.193669 -0.190016 0.050000 +v 0.506130 -0.141350 0.100000 +v 0.193669 -0.190016 -0.050000 +v 0.506130 -0.141350 -0.100000 +v 0.546336 0.216956 0.050000 +v 0.546336 0.216956 -0.050000 +v 0.638028 0.039213 -0.050000 +v 0.638028 0.039213 0.050000 +v -0.182689 -0.196467 0.050000 +v -0.496058 -0.154043 0.100000 +v -0.182689 -0.196467 -0.050000 +v -0.496058 -0.154043 -0.100000 +v -0.094561 -0.016930 0.050000 +v -0.319802 0.205031 0.100000 +v -0.094561 -0.016930 -0.050000 +v -0.319802 0.205031 -0.100000 +v -0.631531 0.023854 0.050000 +v -0.631531 0.023854 -0.050000 +v -0.543403 0.203390 -0.050000 +v -0.543403 0.203390 0.050000 +v -0.100000 -0.041188 0.043582 +v -0.200000 0.235648 0.169524 +v -0.100000 -0.015306 -0.053010 +v -0.200000 0.287412 -0.023661 +v 0.100000 -0.041188 0.043582 +v 0.200000 0.235648 0.169524 +v 0.100000 -0.015306 -0.053010 +v 0.200000 0.287412 -0.023661 +v -0.100000 0.441774 0.172992 +v -0.100000 0.467656 0.076399 +v 0.100000 0.467656 0.076399 +v 0.100000 0.441774 0.172992 +v 0.325596 0.204379 0.019302 +v 0.285457 0.519065 0.062451 +v 0.344629 0.204379 -0.078870 +v 0.323524 0.519065 -0.133893 +v 0.517080 0.160158 0.056426 +v 0.668426 0.430622 0.136699 +v 0.536114 0.160158 -0.041746 +v 0.706492 0.430622 -0.059645 +v 0.434129 0.692004 0.040343 +v 0.453162 0.692004 -0.057829 +v 0.644647 0.647782 -0.020704 +v 0.625613 0.647782 0.077468 +vt 0.563911 0.641438 +vt 0.451166 0.589250 +vt 0.555243 0.317470 +vt 0.668040 0.353694 +vt 0.192184 0.493691 +vt 0.337870 0.241378 +vt 0.000096 0.422585 +vt 0.249733 0.176371 +vt 0.886954 0.820395 +vt 0.913299 0.401556 +vt 0.379745 0.000096 +vt 0.467883 0.065102 +vt 0.473694 0.814299 +vt 0.370314 0.772975 +vt 0.015003 0.724495 +vt 0.148981 0.731949 +vt 0.134073 0.999904 +vt 0.000096 0.992450 +vt 0.658934 0.945657 +s off +f 2/1 4/2 3/3 1/4 +f 4/2 8/5 7/6 3/3 +f 8/5 6/7 5/8 7/6 +f 6/9 2/1 1/4 5/10 +f 1/11 3/12 7/6 5/8 +f 4/2 2/1 9/13 10/14 +f 12/15 11/16 10/17 9/18 +f 2/1 6/9 12/19 9/13 +f 8/5 4/2 10/14 11/16 +f 6/7 8/5 11/16 12/15 +f 14/1 16/2 15/3 13/4 +f 16/2 20/5 19/6 15/3 +f 20/5 18/7 17/8 19/6 +f 18/9 14/1 13/4 17/10 +f 13/11 15/12 19/6 17/8 +f 16/2 14/1 21/13 22/14 +f 24/15 23/16 22/17 21/18 +f 14/1 18/9 24/19 21/13 +f 20/5 16/2 22/14 23/16 +f 18/7 20/5 23/16 24/15 +f 26/1 28/2 27/3 25/4 +f 28/2 32/5 31/6 27/3 +f 32/5 30/7 29/8 31/6 +f 30/9 26/1 25/4 29/10 +f 25/11 27/12 31/6 29/8 +f 28/2 26/1 33/13 34/14 +f 36/15 35/16 34/17 33/18 +f 26/1 30/9 36/19 33/13 +f 32/5 28/2 34/14 35/16 +f 30/7 32/5 35/16 36/15 +f 38/1 40/2 39/3 37/4 +f 40/2 44/5 43/6 39/3 +f 44/5 42/7 41/8 43/6 +f 42/9 38/1 37/4 41/10 +f 37/11 39/12 43/6 41/8 +f 40/2 38/1 45/13 46/14 +f 48/15 47/16 46/17 45/18 +f 38/1 42/9 48/19 45/13 +f 44/5 40/2 46/14 47/16 +f 42/7 44/5 47/16 48/15 +f 50/1 52/2 51/3 49/4 +f 52/2 56/5 55/6 51/3 +f 56/5 54/7 53/8 55/6 +f 54/9 50/1 49/4 53/10 +f 49/11 51/12 55/6 53/8 +f 52/2 50/1 57/13 58/14 +f 60/15 59/16 58/17 57/18 +f 50/1 54/9 60/19 57/13 +f 56/5 52/2 58/14 59/16 +f 54/7 56/5 59/16 60/15 diff --git a/mods/desert_life/models/dl_pp_6.obj b/mods/desert_life/models/dl_pp_6.obj new file mode 100644 index 0000000..9c77bcc --- /dev/null +++ b/mods/desert_life/models/dl_pp_6.obj @@ -0,0 +1,155 @@ +# Blender v2.76 (sub 0) OBJ File: 'Prickly_Pear.blend' +# www.blender.org +o PricklyPear_6_Cube.010 +v -0.100000 -0.500000 0.050000 +v -0.200000 -0.200000 0.100000 +v -0.100000 -0.500000 -0.050000 +v -0.200000 -0.200000 -0.100000 +v 0.100000 -0.500000 0.050000 +v 0.200000 -0.200000 0.100000 +v 0.100000 -0.500000 -0.050000 +v 0.200000 -0.200000 -0.100000 +v -0.100000 -0.000000 0.050000 +v -0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 0.050000 +v 0.101978 -0.012272 0.050000 +v 0.322747 0.214136 0.100000 +v 0.101978 -0.012272 -0.050000 +v 0.322747 0.214136 -0.100000 +v 0.193669 -0.190016 0.050000 +v 0.506130 -0.141350 0.100000 +v 0.193669 -0.190016 -0.050000 +v 0.506130 -0.141350 -0.100000 +v 0.546336 0.216956 0.050000 +v 0.546336 0.216956 -0.050000 +v 0.638028 0.039213 -0.050000 +v 0.638028 0.039213 0.050000 +v -0.182689 -0.196467 0.050000 +v -0.496058 -0.154043 0.100000 +v -0.182689 -0.196467 -0.050000 +v -0.496058 -0.154043 -0.100000 +v -0.094561 -0.016930 0.050000 +v -0.319802 0.205031 0.100000 +v -0.094561 -0.016930 -0.050000 +v -0.319802 0.205031 -0.100000 +v -0.631531 0.023854 0.050000 +v -0.631531 0.023854 -0.050000 +v -0.543403 0.203390 -0.050000 +v -0.543403 0.203390 0.050000 +v -0.100000 -0.041188 0.043582 +v -0.200000 0.235648 0.169524 +v -0.100000 -0.015306 -0.053010 +v -0.200000 0.287412 -0.023661 +v 0.100000 -0.041188 0.043582 +v 0.200000 0.235648 0.169524 +v 0.100000 -0.015306 -0.053010 +v 0.200000 0.287412 -0.023661 +v -0.100000 0.441774 0.172992 +v -0.100000 0.467656 0.076399 +v 0.100000 0.467656 0.076399 +v 0.100000 0.441774 0.172992 +v 0.325596 0.204379 0.019302 +v 0.285457 0.519065 0.062451 +v 0.344629 0.204379 -0.078870 +v 0.323524 0.519065 -0.133893 +v 0.517080 0.160158 0.056426 +v 0.668426 0.430622 0.136699 +v 0.536114 0.160158 -0.041746 +v 0.706492 0.430622 -0.059645 +v 0.434129 0.692004 0.040343 +v 0.453162 0.692004 -0.057829 +v 0.644647 0.647782 -0.020704 +v 0.625613 0.647782 0.077468 +v -0.503115 0.137169 0.066426 +v -0.650346 0.402347 0.168912 +v -0.535106 0.137169 -0.028319 +v -0.714328 0.402347 -0.020577 +v -0.319724 0.187501 0.004504 +v -0.283564 0.503012 0.045068 +v -0.351715 0.187501 -0.090241 +v -0.347546 0.503012 -0.144422 +v -0.622334 0.621076 0.106681 +v -0.654325 0.621076 0.011936 +v -0.470934 0.671409 -0.049987 +v -0.438943 0.671409 0.044758 +vt 0.563911 0.641438 +vt 0.451166 0.589250 +vt 0.555243 0.317470 +vt 0.668040 0.353694 +vt 0.192184 0.493691 +vt 0.337870 0.241378 +vt 0.000096 0.422585 +vt 0.249733 0.176371 +vt 0.886954 0.820395 +vt 0.913299 0.401556 +vt 0.379745 0.000096 +vt 0.467883 0.065102 +vt 0.473694 0.814299 +vt 0.370314 0.772975 +vt 0.015003 0.724495 +vt 0.148981 0.731949 +vt 0.134073 0.999904 +vt 0.000096 0.992450 +vt 0.658934 0.945657 +s off +f 2/1 4/2 3/3 1/4 +f 4/2 8/5 7/6 3/3 +f 8/5 6/7 5/8 7/6 +f 6/9 2/1 1/4 5/10 +f 1/11 3/12 7/6 5/8 +f 4/2 2/1 9/13 10/14 +f 12/15 11/16 10/17 9/18 +f 2/1 6/9 12/19 9/13 +f 8/5 4/2 10/14 11/16 +f 6/7 8/5 11/16 12/15 +f 14/1 16/2 15/3 13/4 +f 16/2 20/5 19/6 15/3 +f 20/5 18/7 17/8 19/6 +f 18/9 14/1 13/4 17/10 +f 13/11 15/12 19/6 17/8 +f 16/2 14/1 21/13 22/14 +f 24/15 23/16 22/17 21/18 +f 14/1 18/9 24/19 21/13 +f 20/5 16/2 22/14 23/16 +f 18/7 20/5 23/16 24/15 +f 26/1 28/2 27/3 25/4 +f 28/2 32/5 31/6 27/3 +f 32/5 30/7 29/8 31/6 +f 30/9 26/1 25/4 29/10 +f 25/11 27/12 31/6 29/8 +f 28/2 26/1 33/13 34/14 +f 36/15 35/16 34/17 33/18 +f 26/1 30/9 36/19 33/13 +f 32/5 28/2 34/14 35/16 +f 30/7 32/5 35/16 36/15 +f 38/1 40/2 39/3 37/4 +f 40/2 44/5 43/6 39/3 +f 44/5 42/7 41/8 43/6 +f 42/9 38/1 37/4 41/10 +f 37/11 39/12 43/6 41/8 +f 40/2 38/1 45/13 46/14 +f 48/15 47/16 46/17 45/18 +f 38/1 42/9 48/19 45/13 +f 44/5 40/2 46/14 47/16 +f 42/7 44/5 47/16 48/15 +f 50/1 52/2 51/3 49/4 +f 52/2 56/5 55/6 51/3 +f 56/5 54/7 53/8 55/6 +f 54/9 50/1 49/4 53/10 +f 49/11 51/12 55/6 53/8 +f 52/2 50/1 57/13 58/14 +f 60/15 59/16 58/17 57/18 +f 50/1 54/9 60/19 57/13 +f 56/5 52/2 58/14 59/16 +f 54/7 56/5 59/16 60/15 +f 62/1 64/2 63/3 61/4 +f 64/2 68/5 67/6 63/3 +f 68/5 66/7 65/8 67/6 +f 66/9 62/1 61/4 65/10 +f 61/11 63/12 67/6 65/8 +f 64/2 62/1 69/13 70/14 +f 72/15 71/16 70/17 69/18 +f 62/1 66/9 72/19 69/13 +f 68/5 64/2 70/14 71/16 +f 66/7 68/5 71/16 72/15 diff --git a/mods/desert_life/models/dl_pp_7.obj b/mods/desert_life/models/dl_pp_7.obj new file mode 100644 index 0000000..bd47b7b --- /dev/null +++ b/mods/desert_life/models/dl_pp_7.obj @@ -0,0 +1,177 @@ +# Blender v2.76 (sub 0) OBJ File: 'Prickly_Pear.blend' +# www.blender.org +o PricklyPear_7_Cube.011 +v -0.100000 -0.500000 0.050000 +v -0.200000 -0.200000 0.100000 +v -0.100000 -0.500000 -0.050000 +v -0.200000 -0.200000 -0.100000 +v 0.100000 -0.500000 0.050000 +v 0.200000 -0.200000 0.100000 +v 0.100000 -0.500000 -0.050000 +v 0.200000 -0.200000 -0.100000 +v -0.100000 -0.000000 0.050000 +v -0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 -0.050000 +v 0.100000 -0.000000 0.050000 +v 0.101978 -0.012272 0.050000 +v 0.322747 0.214136 0.100000 +v 0.101978 -0.012272 -0.050000 +v 0.322747 0.214136 -0.100000 +v 0.193669 -0.190016 0.050000 +v 0.506130 -0.141350 0.100000 +v 0.193669 -0.190016 -0.050000 +v 0.506130 -0.141350 -0.100000 +v 0.546336 0.216956 0.050000 +v 0.546336 0.216956 -0.050000 +v 0.638028 0.039213 -0.050000 +v 0.638028 0.039213 0.050000 +v -0.182689 -0.196467 0.050000 +v -0.496058 -0.154043 0.100000 +v -0.182689 -0.196467 -0.050000 +v -0.496058 -0.154043 -0.100000 +v -0.094561 -0.016930 0.050000 +v -0.319802 0.205031 0.100000 +v -0.094561 -0.016930 -0.050000 +v -0.319802 0.205031 -0.100000 +v -0.631531 0.023854 0.050000 +v -0.631531 0.023854 -0.050000 +v -0.543403 0.203390 -0.050000 +v -0.543403 0.203390 0.050000 +v -0.100000 -0.041188 0.043582 +v -0.200000 0.235648 0.169524 +v -0.100000 -0.015306 -0.053010 +v -0.200000 0.287412 -0.023661 +v 0.100000 -0.041188 0.043582 +v 0.200000 0.235648 0.169524 +v 0.100000 -0.015306 -0.053010 +v 0.200000 0.287412 -0.023661 +v -0.100000 0.441774 0.172992 +v -0.100000 0.467656 0.076399 +v 0.100000 0.467656 0.076399 +v 0.100000 0.441774 0.172992 +v 0.325596 0.204379 0.019302 +v 0.285457 0.519065 0.062451 +v 0.344629 0.204379 -0.078870 +v 0.323524 0.519065 -0.133893 +v 0.517080 0.160158 0.056426 +v 0.668426 0.430622 0.136699 +v 0.536114 0.160158 -0.041746 +v 0.706492 0.430622 -0.059645 +v 0.434129 0.692004 0.040343 +v 0.453162 0.692004 -0.057829 +v 0.644647 0.647782 -0.020704 +v 0.625613 0.647782 0.077468 +v -0.503115 0.137169 0.066426 +v -0.650346 0.402347 0.168912 +v -0.535106 0.137169 -0.028319 +v -0.714328 0.402347 -0.020577 +v -0.319724 0.187501 0.004504 +v -0.283564 0.503012 0.045068 +v -0.351715 0.187501 -0.090241 +v -0.347546 0.503012 -0.144422 +v -0.622334 0.621076 0.106681 +v -0.654325 0.621076 0.011936 +v -0.470934 0.671409 -0.049987 +v -0.438943 0.671409 0.044758 +v -0.100000 0.434230 0.162271 +v -0.200000 0.732811 0.104401 +v -0.100000 0.399321 0.068562 +v -0.200000 0.662995 -0.083017 +v 0.100000 0.434230 0.162271 +v 0.200000 0.732811 0.104401 +v 0.100000 0.399321 0.068562 +v 0.200000 0.662995 -0.083017 +v -0.100000 0.902776 -0.012270 +v -0.100000 0.867867 -0.105979 +v 0.100000 0.867867 -0.105979 +v 0.100000 0.902776 -0.012270 +vt 0.563911 0.641438 +vt 0.451166 0.589250 +vt 0.555243 0.317470 +vt 0.668040 0.353694 +vt 0.192184 0.493691 +vt 0.337870 0.241378 +vt 0.000096 0.422585 +vt 0.249733 0.176371 +vt 0.886954 0.820395 +vt 0.913299 0.401556 +vt 0.379745 0.000096 +vt 0.467883 0.065102 +vt 0.473694 0.814299 +vt 0.370314 0.772975 +vt 0.015003 0.724495 +vt 0.148981 0.731949 +vt 0.134073 0.999904 +vt 0.000096 0.992450 +vt 0.658934 0.945657 +s off +f 2/1 4/2 3/3 1/4 +f 4/2 8/5 7/6 3/3 +f 8/5 6/7 5/8 7/6 +f 6/9 2/1 1/4 5/10 +f 1/11 3/12 7/6 5/8 +f 4/2 2/1 9/13 10/14 +f 12/15 11/16 10/17 9/18 +f 2/1 6/9 12/19 9/13 +f 8/5 4/2 10/14 11/16 +f 6/7 8/5 11/16 12/15 +f 14/1 16/2 15/3 13/4 +f 16/2 20/5 19/6 15/3 +f 20/5 18/7 17/8 19/6 +f 18/9 14/1 13/4 17/10 +f 13/11 15/12 19/6 17/8 +f 16/2 14/1 21/13 22/14 +f 24/15 23/16 22/17 21/18 +f 14/1 18/9 24/19 21/13 +f 20/5 16/2 22/14 23/16 +f 18/7 20/5 23/16 24/15 +f 26/1 28/2 27/3 25/4 +f 28/2 32/5 31/6 27/3 +f 32/5 30/7 29/8 31/6 +f 30/9 26/1 25/4 29/10 +f 25/11 27/12 31/6 29/8 +f 28/2 26/1 33/13 34/14 +f 36/15 35/16 34/17 33/18 +f 26/1 30/9 36/19 33/13 +f 32/5 28/2 34/14 35/16 +f 30/7 32/5 35/16 36/15 +f 38/1 40/2 39/3 37/4 +f 40/2 44/5 43/6 39/3 +f 44/5 42/7 41/8 43/6 +f 42/9 38/1 37/4 41/10 +f 37/11 39/12 43/6 41/8 +f 40/2 38/1 45/13 46/14 +f 48/15 47/16 46/17 45/18 +f 38/1 42/9 48/19 45/13 +f 44/5 40/2 46/14 47/16 +f 42/7 44/5 47/16 48/15 +f 50/1 52/2 51/3 49/4 +f 52/2 56/5 55/6 51/3 +f 56/5 54/7 53/8 55/6 +f 54/9 50/1 49/4 53/10 +f 49/11 51/12 55/6 53/8 +f 52/2 50/1 57/13 58/14 +f 60/15 59/16 58/17 57/18 +f 50/1 54/9 60/19 57/13 +f 56/5 52/2 58/14 59/16 +f 54/7 56/5 59/16 60/15 +f 62/1 64/2 63/3 61/4 +f 64/2 68/5 67/6 63/3 +f 68/5 66/7 65/8 67/6 +f 66/9 62/1 61/4 65/10 +f 61/11 63/12 67/6 65/8 +f 64/2 62/1 69/13 70/14 +f 72/15 71/16 70/17 69/18 +f 62/1 66/9 72/19 69/13 +f 68/5 64/2 70/14 71/16 +f 66/7 68/5 71/16 72/15 +f 74/1 76/2 75/3 73/4 +f 76/2 80/5 79/6 75/3 +f 80/5 78/7 77/8 79/6 +f 78/9 74/1 73/4 77/10 +f 73/11 75/12 79/6 77/8 +f 76/2 74/1 81/13 82/14 +f 84/15 83/16 82/17 81/18 +f 74/1 78/9 84/19 81/13 +f 80/5 76/2 82/14 83/16 +f 78/7 80/5 83/16 84/15 diff --git a/mods/desert_life/ostrich.lua b/mods/desert_life/ostrich.lua new file mode 100644 index 0000000..aeab45f --- /dev/null +++ b/mods/desert_life/ostrich.lua @@ -0,0 +1,66 @@ + +local S = mobs.intllib + +mobs:register_mob("desert_life:ostrich", { + type = "animal", + passive = false, + attack_type = "dogfight", + group_attack = true, + reach = 2, + damage = 2, + hp_min = 5, + hp_max = 10, + armor = 200, + collisionbox = {-0.4, -0.5, -0.4, 0.4, 0.75, 0.4}, + visual = "mesh", + mesh = "dl_ostrich.b3d", + textures = { + {'dl_ostrich.png'}, + }, + visual_size = {x=9, y=9}, + makes_footstep_sound = true, +-- sounds = { +-- random = "mobs_chicken", +-- }, + walk_velocity = 1, + run_velocity = 3, + jump = true, + drops = { + {name = "mobs:chicken_raw", chance = 1, min = 2, max = 6}, + }, + water_damage = 1, + lava_damage = 5, + light_damage = 0, + fall_damage = 0, + fall_speed = -8, + fear_height = 5, + animation = { + speed_normal = 15, + speed_run = 30, + stand_start = 0, + stand_end = 60, + walk_start = 180, + walk_end = 229, + run_start = 180, + run_end = 229, + punch_start = 65, + punch_end = 90, + punch2_start = 95, + punch2_end = 125, + }, + follow = {"farming:seed_wheat", "farming:seed_cotton"}, + view_range = 5, + replace_what = {'group:flora', 'group:plant'}, + replace_with = 'air', + replace_rate = 1, +}) + +mobs:spawn({ + name = 'desert_life:ostrich', + nodes = {'default:desert_sand', 'default:desert_stone'}, + min_height = 0, + max_height = 150, + interval = 60, + chance = 10000, + active_object_count = 5, +}) diff --git a/mods/desert_life/prickly_pear.lua b/mods/desert_life/prickly_pear.lua new file mode 100644 index 0000000..1cf9f01 --- /dev/null +++ b/mods/desert_life/prickly_pear.lua @@ -0,0 +1,147 @@ +local pp_col_box_1 = { + type = 'fixed', + fixed = {{-.2, -.5, -.2, .2, .0, .2}} +} + +local pp_col_box_2 = { + type = 'fixed', + fixed = {{-.6, -.5, -.2, .2, .2, .2}} +} + +local pp_col_box_3 = { + type = 'fixed', + fixed = {{-.6, -.5, -.2, .6, .2, .2}} +} + +local pp_col_box_4 = { + type = 'fixed', + fixed = {{-.6, -.5, -.2, .6, .45, .2}} +} + +local pp_col_box_5 = { + type = 'fixed', + fixed = {{-.7, -.5, -.2, .7, .7, .2}} +} + +local pp_col_box_6 = { + type = 'fixed', + fixed = {{-.7, -.5, -.2, .7, .7, .2}} +} + +local pp_col_box_7 = { + type = 'fixed', + fixed = {{-.6, -.5, -.2, .6, .9, .2}} +} + +local prickly_pear_table = { --number, after_dig, col_box + {1, 'air', pp_col_box_1}, + {2, 'desert_life:prickly_pear_1', pp_col_box_2}, + {3, 'desert_life:prickly_pear_2', pp_col_box_3}, + {4, 'desert_life:prickly_pear_3', pp_col_box_4}, + {5, 'desert_life:prickly_pear_4', pp_col_box_5}, + {6, 'desert_life:prickly_pear_5', pp_col_box_6}, + {7, 'desert_life:prickly_pear_6', pp_col_box_7}, +} + +for i in ipairs (prickly_pear_table) do + local num = prickly_pear_table[i][1] + local AD = prickly_pear_table[i][2] + local col = prickly_pear_table[i][3] + + minetest.register_node('desert_life:prickly_pear_'..num, { + description = 'Prickly Pear', + drawtype = 'mesh', + mesh = 'dl_pp_'..num..'.obj', + tiles = {'dl_prickly_pear.png'}, + groups = {not_in_creative_inventory=1, dl_pp=1}, + paramtype = 'light', + paramtype2 = 'facedir', + selection_box = col, + collision_box = col, + on_punch = function(pos, node, player, pointed_thing) + minetest.set_node(pos, {name = AD, param2 = node.param2}) + player:get_inventory():add_item('main', 'desert_life:prickly_pear') --If inventory is full it should be dropped. +-- local stack = ItemStack('desert_life:prickly_pear') +-- local leftover = minetest.add_item('main', stack) +-- if leftover:get_count() > 0 then +-- minetest.add_item (pos, 'desert_life:prickly_pear '..leftover:get_count()) +-- end + local damage_chance = math.random(1,15) + if damage_chance == 1 then + local hp = player:get_hp() + player:set_hp(hp - 1) + end + end + }) +end + + +minetest.register_node('desert_life:prickly_pear', { + description = 'Prickly Pear Pad', + drawtype = 'mesh', + mesh = 'dl_pp_1.obj', + tiles = {'dl_prickly_pear.png'}, + groups = {dig_immediate = 3}, + paramtype = 'light', + paramtype2 = 'facedir', + selection_box = { + type = 'fixed', + fixed = {{-.2, -.5, -.2, .2, .0, .2}} + }, + collision_box = { + type = 'fixed', + fixed = {{-.2, -.5, -.2, .2, .0, .2}} -- left bottom front right top back + }, + drop = 'desert_life:prickly_pear', + after_place_node = function(pos, placer, itemstack) + local under = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) + local node = minetest.get_node(pos) + if under.name == 'default:sand' or under.name == 'default:desert_sand' then + minetest.set_node(pos, {name = 'desert_life:prickly_pear_1', param2 = node.param2}) + end + end, +}) + +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:desert_sand"}, + sidelen = 16, + noise_params = { + offset = .005, + scale = 0.002, + spread = {x = 150, y = 150, z = 150}, + seed = 150, + octaves = 3, + persist = 0.6 + }, + y_min = -10, + y_max = 60, + decoration = "desert_life:prickly_pear_1", + param2 = 0, + param2_max = 3, + biomes = {'desert'}, +}) + +minetest.register_abm{ + nodenames = {"group:dl_pp"}, + interval = 40, + chance = 30, + action = function(pos) + local node = minetest.get_node(pos) + if node.name == 'desert_life:prickly_pear_1' then + minetest.set_node(pos, {name = "desert_life:prickly_pear_2", param2 = node.param2}) + elseif node.name == 'desert_life:prickly_pear_2' then + minetest.set_node(pos, {name = "desert_life:prickly_pear_3", param2 = node.param2}) + elseif node.name == 'desert_life:prickly_pear_3' then + minetest.set_node(pos, {name = "desert_life:prickly_pear_4", param2 = node.param2}) + elseif node.name == 'desert_life:prickly_pear_4' then + minetest.set_node(pos, {name = "desert_life:prickly_pear_5", param2 = node.param2}) + elseif node.name == 'desert_life:prickly_pear_5' then + minetest.set_node(pos, {name = "desert_life:prickly_pear_6", param2 = node.param2}) + elseif node.name == 'desert_life:prickly_pear_6' then + minetest.set_node(pos, {name = "desert_life:prickly_pear_7", param2 = node.param2}) + elseif node.name == 'desert_life:prickly_pear_7' then + desert_life.spread('desert_life:prickly_pear_1', pos, 1, 'default:desert_sand', 'air', 22) + end + end, +} diff --git a/mods/desert_life/readme.md b/mods/desert_life/readme.md new file mode 100644 index 0000000..d69d46e --- /dev/null +++ b/mods/desert_life/readme.md @@ -0,0 +1,2 @@ +Deserts are pretty boring in default game, this mod attempts to remedy that by spicing them up with some extra flora and fauna. +If you have mobs_redo enabled you'll get a few additional desert animals. diff --git a/mods/desert_life/textures/dl_armadillo_1.png b/mods/desert_life/textures/dl_armadillo_1.png new file mode 100644 index 0000000..32d32ac Binary files /dev/null and b/mods/desert_life/textures/dl_armadillo_1.png differ diff --git a/mods/desert_life/textures/dl_armadillo_2.png b/mods/desert_life/textures/dl_armadillo_2.png new file mode 100644 index 0000000..af1f100 Binary files /dev/null and b/mods/desert_life/textures/dl_armadillo_2.png differ diff --git a/mods/desert_life/textures/dl_barrel_cacti.png b/mods/desert_life/textures/dl_barrel_cacti.png new file mode 100644 index 0000000..bd36cb1 Binary files /dev/null and b/mods/desert_life/textures/dl_barrel_cacti.png differ diff --git a/mods/desert_life/textures/dl_ostrich.png b/mods/desert_life/textures/dl_ostrich.png new file mode 100644 index 0000000..5cf6823 Binary files /dev/null and b/mods/desert_life/textures/dl_ostrich.png differ diff --git a/mods/desert_life/textures/dl_ostrich_inv.png b/mods/desert_life/textures/dl_ostrich_inv.png new file mode 100644 index 0000000..13324dc Binary files /dev/null and b/mods/desert_life/textures/dl_ostrich_inv.png differ diff --git a/mods/desert_life/textures/dl_prickly_pear.png b/mods/desert_life/textures/dl_prickly_pear.png new file mode 100644 index 0000000..ecd4b9e Binary files /dev/null and b/mods/desert_life/textures/dl_prickly_pear.png differ diff --git a/mods/desert_life/textures/dl_prickly_pear_bloom.png b/mods/desert_life/textures/dl_prickly_pear_bloom.png new file mode 100644 index 0000000..155fc4d Binary files /dev/null and b/mods/desert_life/textures/dl_prickly_pear_bloom.png differ diff --git a/mods/doc_modpack/README.md b/mods/doc_modpack/README.md new file mode 100644 index 0000000..6e731bc --- /dev/null +++ b/mods/doc_modpack/README.md @@ -0,0 +1,31 @@ +# Help +The goal of this modpack is to make using Minetest and mods easier for both +newcomers and advanced users. +It makes it easier for newcomers by making help more accessible. +It makes life easier for advanced user by making it more convenient to use, by +centralizing the help where you most need it: Inside the game. This modpack +will also make the life of modder easier by allowing them to add help texts +directly into mods (via `doc_items`). + +For Minetest 5.0.0 or later. + +More information is given in the respective mods. + +Overview of the mods: + +* `doc`: Documentation System. Core API and user interface. Mods can add arbitrary categories and entries +* `doc_basics`: Basic Help. Adds basic help texts about Minetest, controls, gameplay and other basics +* `doc_items`: Item Help. Adds automatically generated help texts for items and an API +* `doc_encyclopedia`: Encyclopedia. An item to access the help +* `doc_identifier`: Lookup Tool. A tool to identify and show help texts for pointed things + +## How to clone (Information for developers) + +This repository does not directly include the mods, +but as [https://git-scm.com/book/en/v2/Git-Tools-Submodules](Git submodules) instead. + +You can use the following command to clone this repository and get all its submodules: + + git clone http://repo.or.cz/minetest_doc_modpack.git --recurse-submodules + +Consult the Git help to learn more about working with submodules. diff --git a/mods/doc_modpack/description.txt b/mods/doc_modpack/description.txt new file mode 100644 index 0000000..59a7a4c --- /dev/null +++ b/mods/doc_modpack/description.txt @@ -0,0 +1 @@ +Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage. diff --git a/mods/doc_modpack/doc/API.md b/mods/doc_modpack/doc/API.md new file mode 100644 index 0000000..59b8825 --- /dev/null +++ b/mods/doc_modpack/doc/API.md @@ -0,0 +1,543 @@ +# API documentation for the Documentation System +## Core concepts +As a modder, you are free to write basically about everything and are also +relatively free in the presentation of information. There are no +restrictions on content whatsoever. + +### Categories and entries +In the Documentation System, everything is built on categories and entries. +An entry is a single piece of documentation and is the basis of all actual +documentation. Categories group multiple entries of the same topic together. + +Categories also define a template function which is used to determine how the +final result in the tab “Entry list†looks like. Entries themselves have +a data field attached to them, this is a table containing arbitrary metadata +which is used to construct the final formspec in the Entry tab. It may also +be used for sorting entries in the entry list. + +## Advanced concepts +### Viewed and hidden entries +The mod keeps track of which entries have been viewed on a per-player basis. +Any entry which has been accessed by a player is immediately marked as +“viewedâ€. + +Entries can also be hidden. Hidden entries are not visible or otherwise +accessible to players until they become revealed by function calls. + +Marking an entry as viewed or revealed is not reversible with this API. +The viewed and hidden states are stored in the file `doc.mt` inside the +world directory. You can safely delete this file if you want to reset +the player states. + +### Entry aliases +Entry aliases are alternative identifiers for entry identifiers. With the +exception of the alias functions themselves, for functions demanding an +`entry_id` you can either supply the original `entry_id` or any alias of the +`entry_id`. + +## Possible use cases +This section shows some possible use cases to give you a rough idea what +this mod is capable of and how these use cases could be implemented. + +### Simple use case: Minetest basics +Let's say you want to write in free form short help texts about the basic +concepts of Minetest or your subgame. First you could define a category +called “Basicsâ€, the data for each of its entry is just a free form text. +The template function simply creates a formspec where this free form +text is displayed. + +This is one of the most simple use cases and the mod `doc_basics` does +exactly that. + +### Complex use case: Blocks +You could create a category called “Blocksâ€, and this category is supposed to +contain entries for every single block (i.e. node) in the game. For this use +case, a free form approach would be very inefficient and error-prone, as a +lot of data can be reused. + +Here the template function comes in handy: The internal entry data +contain a lot of different things about a block, like block name, identifier, +custom description and most importantly, the definition table of the block. + +Finally, the template function takes all that data and turns it into +sentences which are just concatenated, telling as many useful facts about +this block as possible. + +## Functions +This is a list of all publicly available functions. + +### Overview +The most important functions are `doc.add_category` and `doc.ad_entry`. All other functions +are mostly used for utility and examination purposes. + +If not mentioned otherwise, the return value of all functions is `nil`. + +These functions are available: + +#### Core +* `doc.add_category`: Adds a new category +* `doc.add_entry`: Adds a new entry + +#### Display +* `doc.show_entry`: Shows a particular entry to a player +* `doc.show_category`: Shows the entry list of a category to a player +* `doc.show_doc`: Opens the main help form for a player + +#### Query +* `doc.get_category_definition`: Returns the definition table of a category +* `doc.get_entry_definition`: Returns the definition table of an entry +* `doc.entry_exists`: Checks whether an entry exists +* `doc.entry_viewed`: Checks whether an entry has been viewed/read by a player +* `doc.entry_revealed`: Checks whether an entry is visible and normally accessible to a player +* `doc.get_category_count`: Returns the total number of categories +* `doc.get_entry_count`: Returns the total number of entries in a category +* `doc.get_viewed_count`: Returns the number of entries a player has viewed in a category +* `doc.get_revealed_count`: Returns the number of entries a player has access to in a category +* `doc.get_hidden_count`: Returns the number of entries which are hidden from a player in a category +* `doc.get_selection`: Returns the currently viewed entry/category of a player + +#### Modify +* `doc.set_category_order`: Sets the order of categories in the category list +* `doc.mark_entry_as_viewed`: Manually marks an entry as viewed/read by a player +* `doc.mark_entry_as_revealed`: Make a hidden entry visible and accessible to a player +* `doc.mark_all_entries_as_revealed`: Make all hidden entries visible and accessible to a player + +#### Aliases +* `doc.add_entry_alias`: Add an alternative name which can be used to access an entry + +#### Special widgets +This API provides functions to add unique “widgets†for functionality +you may find useful when creating entry templates. You find these +functions in `doc.widgets`. +Currently there is a widget for scrollable multi-line text and a +widget providing an image gallery. + + + +### `doc.add_category(id, def)` +Adds a new category. You have to define an unique identifier, a name +and a template function to build the entry formspec from the entry +data. + +**Important**: You must call this function *before* any player joins. + +#### Parameters +* `id`: Unique category identifier as a string +* `def`: Definition table with the following fields: + * `name`: Category name to be shown in the interface + * `description`: (optional) Short description of the category, + will be shown as tooltip. Recommended style (in English): + First letter capitalized, no punctuation at the end, + max. 100 characters + * `build_formspec`: The template function (see below). Takes entry data + as its first parameter (has the data type of the entry data) and the + name of the player who views the entry as its second parameter. It must + return a formspec which is inserted in the Entry tab. + * `sorting`: (optional) Sorting algorithm for display order of entries + * `"abc"`: Alphabetical (default) + * `"nosort"`: Entries appear in no particular order + * `"custom"`: Manually define the order of entries in `sorting_data` + * `"function"`: Sort by function defined in `sorting_data` + * `sorting_data`: (optional) Additional data for special sorting methods. + * If `sorting=="custom"`, this field must contain a table (list form) in which + the entry IDs are specified in the order they are supposed to appear in the + entry list. All entries which are missing in this table will appear in no + particular order below the final specified one. + * If `sorting=="function"`, this field is a compare function to be used as + the `comp` parameter of `table.sort`. The parameters given are two entries. + * This field is not required if `sorting` has any other value + * `hide_entries_by_default` (optional): If `true`, all entries + added to this category will start as hidden, unless explicitly specified otherwise + (default: `false`) + +Note: For function-based sorting, the entries provided to the compare function +will have the following format: + + { + eid = e, -- unique entry identifier + name = n, -- entry name + data = d, -- arbitrary entry data + } + +#### Using `build_formspec` +For `build_formspec` you can either define your own function which +procedurally generates the entry formspec or you use one of the +following predefined convenience functions: + +* `doc.entry_builders.text`: Expects entry data to be a string. + It will be inserted directly into the entry. Useful for entries with + a free form text. +* `doc.entry_builders.text_and_gallery`: For entries with text and + an optional standard gallery (3 rows, 3:2 aspect ratio). Expects + entry data to be a table with these fields: + * `text`: The entry text + * `images`: The images of the gallery, the format is the same as the + `imagedata` parameter of `doc.widgets.gallery`. Can be `nil`, in + which case no gallery is shown for the entry +* `doc.entry_builders.formspec`: Entry data is expected to contain the + complete entry formspec as a string. Useful if your entries. Useful + if you expect your entries to differ wildly in layouts. + +##### Formspec restrictions +When building your formspec, you have to respect the size limitations. +The help form currently uses a size of 15×10.5 and you must make sure +all entry widgets are inside a boundary box. The remaining space is +reserved for widgets of the help form and should not be used to avoid +overlapping. +Read from the following variables to calculate the final formspec coordinates: + +* `doc.FORMSPEC.WIDTH`: Width of help formspec +* `doc.FORMSPEC.HEIGHT`: Height of help formspec +* `doc.FORMSPEC.ENTRY_START_X`: Leftmost X point of bounding box +* `doc.FORMSPEC.ENTRY_START_Y`: Topmost Y point of bounding box +* `doc.FORMSPEC.ENTRY_END_X`: Rightmost X point of bounding box +* `doc.FORMSPEC.ENTRY_END_Y`: Bottom Y point of bounding box +* `doc.FORMSPEC.ENTRY_WIDTH`: Width of the entry widgets bounding box +* `doc.FORMSPEC.ENTRY_HEIGHT`: Height of the entry widgets bounding box + +Finally, to avoid naming collisions, you must make sure that all identifiers +of your own formspec elements do *not* begin with “`doc_`â€. + +##### Receiving formspec events +You can even use the formspec elements you have added with `build_formspec` to +receive formspec events, just like with any other formspec. For receiving, use +the standard function `minetest.register_on_player_receive_fields` to register +your event handling. The `formname` parameter will be `doc:entry`. Use +`doc.get_selection` to get the category ID and entry ID of the entry in question. + +### `doc.add_entry(category_id, entry_id, def)` +Adds a new entry into an existing category. You have to define the category +to which to insert the entry, the entry's identifier, a name and some +data which defines the entry. Note you do not directly define here how the +end result of an entry looks like, this is done by `build_formspec` from +the category definition. + +**Important**: You must call this function *before* any player joins. + +#### Parameters +* `category_id`: Identifier of the category to add the entry into +* `entry_id`: Unique identifier of the new entry, as a string +* `def`: Definition table, it has the following fields: + * `name`: Entry name to be shown in the interface + * `hidden`: (optional) If `true`, entry will not be displayed in entry list + initially (default: `false`); it can be revealed later + * `data`: Arbitrary data attached to the entry. Any data type is allowed; + The data in this field will be used to create the actual formspec + with `build_formspec` from the category definition + +### `doc.set_category_order(category_list)` +Sets the order of categories in the category list. +The help starts with this default order: + + {"basics", "nodes", "tools", "craftitems", "advanced"} + +This function can be called at any time, but it recommended to only call +this function once for the entire server session and to only call it +from subgame mods, to avoid contradictions. If this function is called a +second time by any mod, a warning is written into the log. + +#### Parameters +* `category_list`: List of category IDs in the order they should appear + in the category list. All unspecified categories will be appended to + the end + + +### `doc.show_doc(playername)` +Opens the main help formspec for the player (“Category list†tab). + +#### Parameters +* `playername`: Name of the player to show the formspec to + +### `doc.show_category(playername, category_id)` +Opens the help formspec for the player at the specified category +(“Entry list†tab). + +#### Parameters +* `playername`: Name of the player to show the formspec to +* `category_id`: Category identifier of the selected category + +### `doc.show_entry(playername, category_id, entry_id, ignore_hidden)` +Opens the help formspec for the player showing the specified entry +of a category (“Entry†tab). If the entry is hidden, an error message +is displayed unless `ignore_hidden==true`. + +#### Parameters +* `playername`: Name of the player to show the formspec to +* `category_id`: Category identifier of the selected category +* `entry_id`: Entry identifier of the entry to show +* `ignore_hidden`: (optional) If `true`, shows entry even if it is still hidden + to the player; this will automatically reveal the entry to this player for the + rest of the game + +### `doc.get_category_definition(category_id)` +Returns the definition of the specified category. + +#### Parameters +* `category_id`: Category identifier of the category to the the definition + for + +#### Return value +The category's definition table as specified in the `def` argument of +`doc.add_category`. The table fields are the same. + +### `doc.get_entry_definition(category_id, entry_id)` +Returns the definition of the specified entry. + +#### Parameters +* `category_id`: Category identifier of entry's category +* `entry_id`: Entry identifier of the entry to get the definition for + +#### Return value +The entry's definition table as specified in the `def` argument of +`doc.add_entry`. The table fields are the same. + +### `doc.entry_exists(category_id, entry_id)` +Checks whether the specified entry exists and returns `true` or `false`. +Entry aliases are taken into account. + +#### Parameters +* `category_id`: Category identifier of the category to check +* `entry_id`: Entry identifier of the entry to check for its existence + +#### Return value +Returns `true` if and only if: + +* The specified category exists +* It contains the specified entry + +Otherwise, returns `false`. + +### `doc.entry_viewed(playername, category_id, entry_id)` +Tells whether the specified entry is marked as “viewed†(or read) by +the player. + +#### Parameters +* `playername`: Name of the player to check +* `category_id`: Category identifier of the category to check +* `entry_id`: Entry identifier of the entry to check + +#### Return value +`true`, if entry is viewed, `false` otherwise. + +### `doc.entry_revealed(playername, category_id, entry_id)` +Tells whether the specified entry is marked as “revealed†to the player +and thus visible and accessible to the player. + +#### Parameters +* `playername`: Name of the player to check +* `category_id`: Category identifier of the category to check +* `entry_id`: Entry identifier of the entry to check + +#### Return value +`true`, if entry is revealed, `false` otherwise. + +### `doc.mark_entry_as_viewed(playername, category_id, entry_id)` +Marks a particular entry as “viewed†(or read) by a player. This will +also automatically reveal the entry to the player for the rest of +the game. + +#### Parameters +* `playername`: Name of the player for whom to mark an entry as “viewed†+* `category_id`: Category identifier of the category of the entry to mark +* `entry_id`: Entry identifier of the entry to mark + +### `doc.mark_entry_as_revealed(playername, category_id, entry_id)` +Marks a particular entry as “revealed†to a player. If the entry is +declared as hidden, it will become visible in the list of entries for +this player and will always be accessible with `doc.show_entry`. This +change remains for the rest of the game. + +For entries which are not normally hidden, this function has no direct +effect. + +#### Parameters +* `playername`: Name of the player for whom to reveal the entry +* `category_id`: Category identifier of the category of the entry to reveal +* `entry_id`: Entry identifier of the entry to reveal + +### `doc.mark_all_entries_as_revealed(playername)` +Marks all entries as “revealed†to a player. This change remains for the +rest of the game. + +#### Parameters +* `playername`: Name of the player for whom to reveal the entries + +### `doc.add_entry_alias(category_id_orig, entry_id_orig, category_id_alias, entry_id_orig)` +Adds a single alias for an entry. If an entry has an alias, supplying the +alias to a function which demand `category_id` and `entry_id` will work as expected. +When using this function, you must make sure the category already exists. + +This function could be useful for legacy support after changing an entry ID or +moving an entry to a different category. + +#### Parameters +* `category_id_orig`: Category identifier of the category of the entry in question +* `entry_id_orig`: The original (!) entry identifier of the entry to create an alias + for +* `category_id_alias`: The category ID of the alias +* `entry_id_alias`: The entry ID of the alias + +#### Example + + doc.add_entry_alias("nodes", "test", "craftitems", "test2") + +When calling a function with category ID “craftitems†and entry ID “test2â€, it will +act as if you supplied “nodes†as category ID and “test†as entry ID. + +### `doc.get_category_count()` +Returns the number of registered categories. + +#### Return value +Number of registered categories. + +### `doc.get_entry_count(category_id)` +Returns the number of entries in a category. + +#### Parameters +* `category_id`: Category identifier of the category in which to count entries + +#### Return value +Number of entries in the specified category. + +### `doc.get_viewed_count(playername, category_id)` +Returns how many entries have been viewed by a player. + +#### Parameters +* `playername`: Name of the player to count the viewed entries for +* `category_id`: Category identifier of the category in which to count the + viewed entries + +#### Return value +Amount of entries the player has viewed in the specified category. If the +player does not exist, this function returns `nil`. + +### `doc.get_revealed_count(playername, category_id)` +Returns how many entries the player has access to (non-hidden entries) +in this category. + +#### Parameters +* `playername`: Name of the player to count the revealed entries for +* `category_id`: Category identifier of the category in which to count the + revealed entries + +#### Return value +Amount of entries the player has access to in the specified category. If the +player does not exist, this function returns `nil`. + +### `doc.get_hidden_count(playername, category_id)` +Returns how many entries are hidden from the player in this category. + +#### Parameters +* `playername`: Name of the player to count the hidden entries for +* `category_id`: Category identifier of the category in which to count the + hidden entries + +#### Return value +Amount of entries hidden from the player. If the player does not exist, +this function returns `nil`. + +### `doc.get_selection(playername)` +Returns the currently or last viewed entry and/or category of a player. + +#### Parameter +* `playername`: Name of the player to query + +#### Return value +It returns up to 2 values. The first one is the category ID, the second one +is the entry ID of the entry/category which the player is currently viewing +or is the last entry the player viewed in this session. If the player only +viewed a category so far, the second value is `nil`. If the player has not +viewed a category as well, both returned values are `nil`. + + +### `doc.widgets.text(data, x, y, width, height)` +This is a convenience function for creating a special formspec widget. It creates +a widget in which you can insert scrollable multi-line text. + +As of Minetest 0.4.14, this function is only provided because Minetest lacks +native support for such a widget. When Minetest supports such a widget natively, +this function may become just a simple wrapper. + +#### Parameters +* `data`: Text to be written inside the widget +* `x`: Formspec X coordinate (optional) +* `y`: Formspec Y coordinate (optional) +* `width`: Width of the widget in formspec units (optional) +* `height`: Height of the widget in formspec units (optional) + +The default values for the optional parameters result in a widget which fills +nearly the entire entry page. + +#### Return value +Two values are returned, in this order: + +* string: Contains a complete formspec definition building the widget +* string: Formspec element ID of the created widget + +#### Note +If you use this function to build a formspec string, do not use identifiers +beginning with `doc_widget_text` to avoid naming collisions, as this function +makes use of such identifiers internally. + + +### `doc.widgets.gallery(imagedata, playername, x, y, aspect_ratio, width, rows, align_left, align_top)` +This function creates an image gallery which allows you to display an +arbitrary amount of images aligned horizontally. It is possible to add more +images than the space of an entry would normally held, this is done by adding +“scroll†buttons to the left and right which allows the user to see more images +of the gallery. + +This function is useful for adding multiple illustration to your entry without +worrying about space too much. Adding illustrations can help you to create +entry templates which aren't just lengthy walls of text. ;-) + +You can define the position, image aspect ratio, total gallery width and the +number of images displayed at once. You can *not* directly define the image +size, nor the resulting height of the overall gallery, those values will +be derived from the parameters. + +You can only really use this function efficiently inside a *custom* +`build_formspec` function definition. This is because you need to pass a +`playername`. You can currently also only add up to one gallery per entry; +adding more galleries is not supported and will lead to bugs. + +### Parameters +* `imagedata`: List of images to be displayed in the specified order. All images must + have the same aspect ratio. It's a table of tables with this format: + * `imagetype`: Type of image to be used (optional): + * `"image"`: Texture file (default) + * `"item"`: Item image, specified as itemstring + * `image`: What to display. Depending on `imagetype`, a texture file or itemstring +* `playername`: Name of the player who is viewing the entry in question +* `x`: Formspec X coordinate of the top left corner (optional) +* `y`: Formspec Y coordinate of the top left corner (optional) +* `aspect_ratio`: Aspect ratio of all the images (width/height) +* `width`: Total gallery width in formspec units (optional) +* `rows`: Number of images which can be seen at once (optional) +* `align_left`: If `false`, gallery is aligned to the left instead of the right (optional) +* `align_right`: If `false`, gallery is aligned to the bottom instead of the top (optional) + +The default values for the optional parameters result in a gallery with +3 rows which is placed at the top left corner and spans the width of the +entry and assumes an aspect ratio of two thirds. + +If the number of images is greater than `rows`, “scroll†buttons will appear +at the left and right side of the images. + +#### Return values +Two values are returned, in this order: + +* string: Contains a complete formspec definition building the gallery +* number: The height the gallery occupies in the formspec + +## Extending this mod (naming conventions) +If you want to extend this mod with your own functionality, it is recommended +that you put all API functions into `doc.sub.`. +As a naming convention, if you mod *primarily* depends on `doc`, it is recommended +to use a short mod name which starts with “`doc_`â€, like `doc_items`, +`doc_minetest_game`, or `doc_identifier`. + +One mod which uses this convention is `doc_items` which uses the `doc.sub.items` +table. + + diff --git a/mods/doc_modpack/doc/README.md b/mods/doc_modpack/doc/README.md new file mode 100644 index 0000000..ceb8342 --- /dev/null +++ b/mods/doc_modpack/doc/README.md @@ -0,0 +1,52 @@ +# Documentation System [`doc`] +This mod provides a simple and highly extensible form in which the user +can access help pages about various things and the modder can add those pages. +The mod itself does not provide any help texts, just the framework. +It is the heart of the Help modpack, on which the other Help mods depend. + +Current version: 1.0.0 + +## For players +### Accessing the help +To open the help, there are multiple ways: + +- Use the `/helpform` chat command. This works always. +- If you use one of these mods, there's a help button in the inventory menu: + - Unified Inventory [`unified_inventory`] + - Simple Fast Inventory Buttons [`sfinv_buttons`] + - Inventory++ [`inventory_plus`] + +The help itself should be more or less self-explanatory. + +This mod is useless on its own, you will only need this mod as a dependency +for mods which actually add some help entries. + +### Hidden entries +Some entries are initially hidden from you. You can't see them until you +unlocked them. Mods can decide for themselves how particular entries are +revealed. Normally you just have to proceed in the game to unlock more +entries. Hidden entries exist to avoid spoilers and give players a small +sense of progress. + +Players with the `help_reveal` privilege can use the `/help_reveal` chat +command to reveal all hidden entries instantly. + +### Maintenance +The information of which player has viewed and revealed which entries is +stored in the world directory in the file `doc.mt`. You can safely reset +the viewed/revealed state of all players by deleting this file. Players +then need to start over revealing all entries. + +## For modders and subgame authors +This mod helps you in creating extensive and flexible help entries for your +mods or subgame. You can write about basically anything in the presentation +you prefer. + +To get started, read `API.md` in the directory of this mod. + +Note: If you want to add help texts for items and nodes, refer to the API +documentation of `doc_items`, instead of manually adding entries. +For custom entities, you may also want to add support for `doc_identifier`. + +## License of everything +MIT License diff --git a/mods/doc_modpack/doc/depends.txt b/mods/doc_modpack/doc/depends.txt new file mode 100644 index 0000000..c6040df --- /dev/null +++ b/mods/doc_modpack/doc/depends.txt @@ -0,0 +1,4 @@ +intllib? +unified_inventory? +sfinv_buttons? +central_message? diff --git a/mods/doc_modpack/doc/description.txt b/mods/doc_modpack/doc/description.txt new file mode 100644 index 0000000..808a218 --- /dev/null +++ b/mods/doc_modpack/doc/description.txt @@ -0,0 +1 @@ +A simple in-game documentation system which enables mods to add help entries based on templates. diff --git a/mods/doc_modpack/doc/init.lua b/mods/doc_modpack/doc/init.lua new file mode 100644 index 0000000..1626923 --- /dev/null +++ b/mods/doc_modpack/doc/init.lua @@ -0,0 +1,1271 @@ +-- Boilerplate to support localized strings if intllib mod is installed. +local S, F +if minetest.get_modpath("intllib") then + S = intllib.Getter() +else + S = function(s,a,...)a={a,...}return s:gsub("@(%d+)",function(n)return a[tonumber(n)]end)end +end +F = function(f) return minetest.formspec_escape(S(f)) end + +-- Compability for 0.4.14 or earlier +local colorize +if core.colorize then + colorize = core.colorize +else + colorize = function(color, text) return text end +end + +doc = {} + +-- Some informational variables +-- DO NOT CHANGE THEM AFTERWARDS AT RUNTIME! + +-- Version number (follows the SemVer specification 2.0.0) +doc.VERSION = {} +doc.VERSION.MAJOR = 1 +doc.VERSION.MINOR = 0 +doc.VERSION.PATCH = 0 +doc.VERSION.STRING = doc.VERSION.MAJOR.."."..doc.VERSION.MINOR.."."..doc.VERSION.PATCH + +-- Formspec information +doc.FORMSPEC = {} +-- Width of formspec +doc.FORMSPEC.WIDTH = 15 +doc.FORMSPEC.HEIGHT = 10.5 + +--[[ Recommended bounding box coordinates for widgets to be placed in entry pages. Make sure +all entry widgets are completely inside these coordinates to avoid overlapping. ]] +doc.FORMSPEC.ENTRY_START_X = 0 +doc.FORMSPEC.ENTRY_START_Y = 0.5 +doc.FORMSPEC.ENTRY_END_X = doc.FORMSPEC.WIDTH +doc.FORMSPEC.ENTRY_END_Y = doc.FORMSPEC.HEIGHT - 0.5 +doc.FORMSPEC.ENTRY_WIDTH = doc.FORMSPEC.ENTRY_END_X - doc.FORMSPEC.ENTRY_START_X +doc.FORMSPEC.ENTRY_HEIGHT = doc.FORMSPEC.ENTRY_END_Y - doc.FORMSPEC.ENTRY_START_Y + +--TODO: Use container formspec element later + +-- Internal helper variables +local DOC_INTRO = S("This is the help.") + +local COLOR_NOT_VIEWED = "#00FFFF" -- cyan +local COLOR_VIEWED = "#FFFFFF" -- white +local COLOR_HIDDEN = "#999999" -- gray +local COLOR_ERROR = "#FF0000" -- red + +local CATEGORYFIELDSIZE = { + WIDTH = math.ceil(doc.FORMSPEC.WIDTH / 4), + HEIGHT = math.floor(doc.FORMSPEC.HEIGHT-1), +} + +-- Maximum characters per line in the text widget +local TEXT_LINELENGTH = 80 + +doc.data = {} +doc.data.categories = {} +doc.data.aliases = {} +-- Default order (includes categories of other mods from the Docuentation System modpack) +doc.data.category_order = {"basics", "nodes", "tools", "craftitems", "advanced"} +doc.data.category_count = 0 +doc.data.players = {} + +-- Space for additional APIs +doc.sub = {} + +-- Status variables +local set_category_order_was_called = false + +-- Returns the entry definition and true entry ID of an entry, taking aliases into account +local function get_entry(category_id, entry_id) + local category = doc.data.categories[category_id] + local entry + if category ~= nil then + entry = category.entries[entry_id] + end + if category == nil or entry == nil then + local c_alias = doc.data.aliases[category_id] + if c_alias then + local alias = c_alias[entry_id] + if alias then + category_id = alias.category_id + entry_id = alias.entry_id + category = doc.data.categories[category_id] + if category then + entry = category.entries[entry_id] + else + return nil + end + else + return nil + end + else + return nil + end + end + return entry, category_id, entry_id +end + +--[[ Core API functions ]] + +-- Add a new category +function doc.add_category(id, def) + if doc.data.categories[id] == nil and id ~= nil then + doc.data.categories[id] = {} + doc.data.categories[id].entries = {} + doc.data.categories[id].entry_count = 0 + doc.data.categories[id].hidden_count = 0 + doc.data.categories[id].def = def + -- Determine order position + local order_id = nil + for i=1,#doc.data.category_order do + if doc.data.category_order[i] == id then + order_id = i + break + end + end + if order_id == nil then + table.insert(doc.data.category_order, id) + doc.data.categories[id].order_position = #doc.data.category_order + else + doc.data.categories[id].order_position = order_id + end + doc.data.category_count = doc.data.category_count + 1 + return true + else + return false + end +end + +-- Add a new entry +function doc.add_entry(category_id, entry_id, def) + local cat = doc.data.categories[category_id] + if cat ~= nil then + local hidden = def.hidden or (def.hidden == nil and cat.def.hide_entries_by_default) + if hidden then + cat.hidden_count = cat.hidden_count + 1 + def.hidden = hidden + end + cat.entry_count = doc.data.categories[category_id].entry_count + 1 + if def.name == nil or def.name == "" then + minetest.log("warning", "[doc] Nameless entry added. Entry ID: "..entry_id) + end + cat.entries[entry_id] = def + return true + else + return false + end +end + +-- Marks a particular entry as viewed by a certain player, which also +-- automatically reveals it +function doc.mark_entry_as_viewed(playername, category_id, entry_id) + local entry, category_id, entry_id = get_entry(category_id, entry_id) + if not entry then + return + end + if doc.data.players[playername].stored_data.viewed[category_id] == nil then + doc.data.players[playername].stored_data.viewed[category_id] = {} + doc.data.players[playername].stored_data.viewed_count[category_id] = 0 + end + if doc.entry_exists(category_id, entry_id) and doc.data.players[playername].stored_data.viewed[category_id][entry_id] ~= true then + doc.data.players[playername].stored_data.viewed[category_id][entry_id] = true + doc.data.players[playername].stored_data.viewed_count[category_id] = doc.data.players[playername].stored_data.viewed_count[category_id] + 1 + -- Needed because viewed entries get a different color + doc.data.players[playername].entry_textlist_needs_updating = true + end + doc.mark_entry_as_revealed(playername, category_id, entry_id) +end + +-- Marks a particular entry as revealed/unhidden by a certain player +function doc.mark_entry_as_revealed(playername, category_id, entry_id) + local entry, category_id, entry_id = get_entry(category_id, entry_id) + if not entry then + return + end + if doc.data.players[playername].stored_data.revealed[category_id] == nil then + doc.data.players[playername].stored_data.revealed[category_id] = {} + doc.data.players[playername].stored_data.revealed_count[category_id] = doc.get_entry_count(category_id) - doc.data.categories[category_id].hidden_count + end + if doc.entry_exists(category_id, entry_id) and entry.hidden and doc.data.players[playername].stored_data.revealed[category_id][entry_id] ~= true then + doc.data.players[playername].stored_data.revealed[category_id][entry_id] = true + doc.data.players[playername].stored_data.revealed_count[category_id] = doc.data.players[playername].stored_data.revealed_count[category_id] + 1 + -- Needed because a new entry is added to the list of visible entries + doc.data.players[playername].entry_textlist_needs_updating = true + if minetest.get_modpath("central_message") ~= nil then + local cat = doc.data.categories[category_id] + cmsg.push_message_player(minetest.get_player_by_name(playername), S("New help entry unlocked: @1 > @2", cat.def.name, entry.name)) + end + -- To avoid sound spamming, don't play sound more than once per second + local last_sound = doc.data.players[playername].last_reveal_sound + if last_sound == nil or os.difftime(os.time(), last_sound) >= 1 then + -- Play notification sound + --minetest.sound_play({ name = "doc_reveal", gain = 0.2 }, { to_player = playername }) + doc.data.players[playername].last_reveal_sound = os.time() + end + end +end + +-- Reveal +function doc.mark_all_entries_as_revealed(playername) + -- Has at least 1 new entry been revealed? + local reveal1 = false + for category_id, category in pairs(doc.data.categories) do + if doc.data.players[playername].stored_data.revealed[category_id] == nil then + doc.data.players[playername].stored_data.revealed[category_id] = {} + doc.data.players[playername].stored_data.revealed_count[category_id] = doc.get_entry_count(category_id) - doc.data.categories[category_id].hidden_count + end + for entry_id, _ in pairs(category.entries) do + if doc.data.players[playername].stored_data.revealed[category_id][entry_id] ~= true then + doc.data.players[playername].stored_data.revealed[category_id][entry_id] = true + doc.data.players[playername].stored_data.revealed_count[category_id] = doc.data.players[playername].stored_data.revealed_count[category_id] + 1 + reveal1 = true + end + end + end + + local msg + if reveal1 then + -- Needed because new entries are added to player's view on entry list + doc.data.players[playername].entry_textlist_needs_updating = true + + msg = S("All help entries revealed!") + + -- Play notification sound (ignore sound limit intentionally) + --minetest.sound_play({ name = "doc_reveal", gain = 0.2 }, { to_player = playername }) + doc.data.players[playername].last_reveal_sound = os.time() + else + msg = S("All help entries are already revealed.") + end + -- Notify + if minetest.get_modpath("central_message") ~= nil then + cmsg.push_message_player(minetest.get_player_by_name(playername), msg) + else + minetest.chat_send_player(playername, msg) + end +end + +-- Returns true if the specified entry has been viewed by the player +function doc.entry_viewed(playername, category_id, entry_id) + local entry, category_id, entry_id = get_entry(category_id, entry_id) + if doc.data.players[playername].stored_data.viewed[category_id] == nil then + return false + else + return doc.data.players[playername].stored_data.viewed[category_id][entry_id] == true + end +end + +-- Returns true if the specified entry is hidden from the player +function doc.entry_revealed(playername, category_id, entry_id) + local entry, category_id, entry_id = get_entry(category_id, entry_id) + local hidden = doc.data.categories[category_id].entries[entry_id].hidden + if doc.data.players[playername].stored_data.revealed[category_id] == nil then + return not hidden + else + if hidden then + return doc.data.players[playername].stored_data.revealed[category_id][entry_id] == true + else + return true + end + end +end + +-- Returns category definition +function doc.get_category_definition(category_id) + if doc.data.categories[category_id] == nil then + return nil + end + return doc.data.categories[category_id].def +end + +-- Returns entry definition +function doc.get_entry_definition(category_id, entry_id) + if not doc.entry_exists(category_id, entry_id) then + return nil + end + local entry, _, _ = get_entry(category_id, entry_id) + return entry +end + +-- Opens the main documentation formspec for the player +function doc.show_doc(playername) + if doc.get_category_count() <= 0 then + minetest.show_formspec(playername, "doc:error_no_categories", doc.formspec_error_no_categories()) + return + end + local formspec = doc.formspec_core()..doc.formspec_main(playername) + minetest.show_formspec(playername, "doc:main", formspec) +end + +-- Opens the documentation formspec for the player at the specified category +function doc.show_category(playername, category_id) + if doc.get_category_count() <= 0 then + minetest.show_formspec(playername, "doc:error_no_categories", doc.formspec_error_no_categories()) + return + end + doc.data.players[playername].catsel = nil + doc.data.players[playername].category = category_id + doc.data.players[playername].entry = nil + local formspec = doc.formspec_core(2)..doc.formspec_category(category_id, playername) + minetest.show_formspec(playername, "doc:category", formspec) +end + +-- Opens the documentation formspec for the player showing the specified entry in a category +function doc.show_entry(playername, category_id, entry_id, ignore_hidden) + if doc.get_category_count() <= 0 then + minetest.show_formspec(playername, "doc:error_no_categories", doc.formspec_error_no_categories()) + return + end + local entry, category_id, entry_id = get_entry(category_id, entry_id) + if ignore_hidden or doc.entry_revealed(playername, category_id, entry_id) then + local playerdata = doc.data.players[playername] + playerdata.category = category_id + playerdata.entry = entry_id + + doc.mark_entry_as_viewed(playername, category_id, entry_id) + playerdata.entry_textlist_needs_updating = true + doc.generate_entry_list(category_id, playername) + + playerdata.catsel = playerdata.catsel_list[entry_id] + playerdata.galidx = 1 + + local formspec = doc.formspec_core(3)..doc.formspec_entry(category_id, entry_id, playername) + minetest.show_formspec(playername, "doc:entry", formspec) + else + minetest.show_formspec(playername, "doc:error_hidden", doc.formspec_error_hidden(category_id, entry_id)) + end +end + +-- Returns true if and only if: +-- * The specified category exists +-- * This category contains the specified entry +-- Aliases are taken into account +function doc.entry_exists(category_id, entry_id) + return get_entry(category_id, entry_id) ~= nil +end + +-- Sets the order of categories in the category list +function doc.set_category_order(categories) + local reverse_categories = {} + for cid=1,#categories do + reverse_categories[categories[cid]] = cid + end + doc.data.category_order = categories + for cid, cat in pairs(doc.data.categories) do + if reverse_categories[cid] == nil then + table.insert(doc.data.category_order, cid) + end + end + reverse_categories = {} + for cid=1, #doc.data.category_order do + reverse_categories[categories[cid]] = cid + end + + for cid, cat in pairs(doc.data.categories) do + cat.order_position = reverse_categories[cid] + end + if set_category_order_was_called then + minetest.log("warning", "[doc] doc.set_category_order was called again!") + end + set_category_order_was_called = true +end + +-- Adds an alias for an entry. Attempting to open an entry by an alias name +-- results in opening the entry of the original name. +function doc.add_entry_alias(category_id_orig, entry_id_orig, category_id_alias, entry_id_alias) + if not doc.data.aliases[category_id_alias] then + doc.data.aliases[category_id_alias] = {} + end + doc.data.aliases[category_id_alias][entry_id_alias] = { category_id = category_id_orig, entry_id = entry_id_orig } +end + +-- Returns number of categories +function doc.get_category_count() + return doc.data.category_count +end + +-- Returns number of entries in category +function doc.get_entry_count(category_id) + return doc.data.categories[category_id].entry_count +end + +-- Returns how many entries have been viewed by the player +function doc.get_viewed_count(playername, category_id) + local playerdata = doc.data.players[playername] + if playerdata == nil then + return nil + end + local count = playerdata.stored_data.viewed_count[category_id] + if count == nil then + playerdata.stored_data.viewed[category_id] = {} + count = 0 + playerdata.stored_data.viewed_count[category_id] = count + return count + else + return count + end +end + +-- Returns how many entries have been revealed by the player +function doc.get_revealed_count(playername, category_id) + local playerdata = doc.data.players[playername] + if playerdata == nil then + return nil + end + local count = playerdata.stored_data.revealed_count[category_id] + if count == nil then + playerdata.stored_data.revealed[category_id] = {} + count = doc.get_entry_count(category_id) - doc.data.categories[category_id].hidden_count + playerdata.stored_data.revealed_count[category_id] = count + return count + else + return count + end +end + +-- Returns how many entries are hidden from the player +function doc.get_hidden_count(playername, category_id) + local playerdata = doc.data.players[playername] + if playerdata == nil then + return nil + end + local total = doc.get_entry_count(category_id) + local rcount = playerdata.stored_data.revealed_count[category_id] + if rcount == nil then + return total + else + return total - rcount + end +end + +-- Returns the currently viewed entry and/or category of the player +function doc.get_selection(playername) + local playerdata = doc.data.players[playername] + if playerdata ~= nil then + local cat = playerdata.category + if cat then + local entry = playerdata.entry + if entry then + return cat, entry + else + return cat + end + else + return nil + end + else + return nil + end +end + +-- Template function templates, to be used for build_formspec in doc.add_category +doc.entry_builders = {} + +-- Inserts line breaks into a single paragraph and collapses all whitespace (including newlines) +-- into spaces +local linebreaker_single = function(text, linelength) + if linelength == nil then + linelength = TEXT_LINELENGTH + end + local remain = linelength + local res = {} + local line = {} + local split = function(s) + local res = {} + for w in string.gmatch(s, "%S+") do + res[#res+1] = w + end + return res + end + + for _, word in ipairs(split(text)) do + if string.len(word) + 1 > remain then + table.insert(res, table.concat(line, " ")) + line = { word } + remain = linelength - string.len(word) + else + table.insert(line, word) + remain = remain - (string.len(word) + 1) + end + end + + table.insert(res, table.concat(line, " ")) + return table.concat(res, "\n") +end + +-- Inserts automatic line breaks into an entire text and preserves existing newlines +local linebreaker = function(text, linelength) + local out = "" + for s in string.gmatch(text, "([^\n]*)") do + local l = linebreaker_single(s, linelength) + out = out .. l + if(string.len(l) == 0) then + out = out .. "\n" + end + end + -- Remove last newline + if string.len(out) >= 1 then + out = string.sub(out, 1, string.len(out) - 1) + end + return out +end + +-- Inserts text suitable for a textlist (including automatic word-wrap) +local text_for_textlist = function(text, linelength) + text = linebreaker(text, linelength) + text = minetest.formspec_escape(text) + text = string.gsub(text, "\n", ",") + return text +end + +-- Scrollable freeform text +doc.entry_builders.text = function(data) + local formstring = doc.widgets.text(data, doc.FORMSPEC.ENTRY_START_X, doc.FORMSPEC.ENTRY_START_Y, doc.FORMSPEC.ENTRY_WIDTH - 0.2, doc.FORMSPEC.ENTRY_HEIGHT) + return formstring +end + +-- Scrollable freeform text with an optional standard gallery (3 rows, 3:2 aspect ratio) +doc.entry_builders.text_and_gallery = function(data, playername) + -- How much height the image gallery “steals†from the text widget + local stolen_height = 0 + local formstring = "" + -- Only add the gallery if images are in the data, otherwise, the text widget gets all of the space + if data.images ~= nil then + local gallery + gallery, stolen_height = doc.widgets.gallery(data.images, playername, nil, doc.FORMSPEC.ENTRY_END_Y + 0.2, nil, nil, nil, nil, false) + formstring = formstring .. gallery + end + formstring = formstring .. doc.widgets.text(data.text, + doc.FORMSPEC.ENTRY_START_X, + doc.FORMSPEC.ENTRY_START_Y, + doc.FORMSPEC.ENTRY_WIDTH - 0.2, + doc.FORMSPEC.ENTRY_HEIGHT - stolen_height) + + return formstring +end + +doc.widgets = {} + +local text_id = 1 +-- Scrollable freeform text +doc.widgets.text = function(data, x, y, width, height) + if x == nil then + x = doc.FORMSPEC.ENTRY_START_X + end + if y == nil then + y = doc.FORMSPEC.ENTRY_START_Y + end + if width == nil then + width = doc.FORMSPEC.ENTRY_WIDTH + end + if height == nil then + height = doc.FORMSPEC.ENTRY_HEIGHT + end + local baselength = TEXT_LINELENGTH + local widget_basewidth = doc.FORMSPEC.WIDTH + local linelength = math.max(20, math.floor(baselength * (width / widget_basewidth))) + + local widget_id = "doc_widget_text"..text_id + text_id = text_id + 1 + -- TODO: Wait for Minetest to provide a native widget for scrollable read-only text with automatic line breaks. + -- Currently, all of this had to be hacked into this script manually by using/abusing the table widget + local formstring = "tablecolumns[text]".. + "tableoptions[background=#000000FF;highlight=#000000FF;border=false]".. + "table["..tostring(x)..","..tostring(y)..";"..tostring(width)..","..tostring(height)..";"..widget_id..";"..text_for_textlist(data, linelength).."]" + return formstring, widget_id +end + +-- Image gallery +-- Currently, only one gallery per entry is supported. TODO: Add support for multiple galleries in an entry (low priority) +doc.widgets.gallery = function(imagedata, playername, x, y, aspect_ratio, width, rows, align_left, align_top) + if playername == nil then return nil end -- emergency exit + + local formstring = "" + + -- Defaults + if x == nil then + if align_left == false then + x = doc.FORMSPEC.ENTRY_END_X + else + x = doc.FORMSPEC.ENTRY_START_X + end + end + if y == nil then + if align_top == false then + y = doc.FORMSPEC.ENTRY_END_Y + else + y = doc.FORMSPEC.ENTRY_START_Y + end + end + if width == nil then width = doc.FORMSPEC.ENTRY_WIDTH end + if rows == nil then rows = 3 end + + if align_left == false then + x = x - width + end + + local imageindex = doc.data.players[playername].galidx + doc.data.players[playername].maxgalidx = #imagedata + doc.data.players[playername].galrows = rows + + if aspect_ratio == nil then aspect_ratio = (2/3) end + local pos = 0 + local totalimagewidth, iw, ih + local bw = 0.5 + local buttonoffset = 0 + if #imagedata > rows then + totalimagewidth = width - bw*2 + iw = totalimagewidth / rows + ih = iw * aspect_ratio + if align_top == false then + y = y - ih + end + + local tt + if imageindex > 1 then + formstring = formstring .. "button["..x..","..y..";"..bw..","..ih..";doc_button_gallery_prev;"..F("<").."]" + if rows == 1 then + tt = F("Show previous image") + else + tt = F("Show previous gallery page") + end + formstring = formstring .. "tooltip[doc_button_gallery_prev;"..tt.."]" + end + if (imageindex + rows) <= #imagedata then + local rightx = buttonoffset + (x + rows * iw) + formstring = formstring .. "button["..rightx..","..y..";"..bw..","..ih..";doc_button_gallery_next;"..F(">").."]" + if rows == 1 then + tt = F("Show next image") + else + tt = F("Show next gallery page") + end + formstring = formstring .. "tooltip[doc_button_gallery_next;"..tt.."]" + end + buttonoffset = bw + else + totalimagewidth = width + iw = totalimagewidth / rows + ih = iw * aspect_ratio + if align_top == false then + y = y - ih + end + end + for i=imageindex, math.min(#imagedata, (imageindex-1)+rows) do + local xoffset = buttonoffset + (x + pos * iw) + local nx = xoffset - 0.2 + local ny = y - 0.05 + if imagedata[i].imagetype == "item" then + formstring = formstring .. "item_image["..xoffset..","..y..";"..iw..","..ih..";"..imagedata[i].image.."]" + else + formstring = formstring .. "image["..xoffset..","..y..";"..iw..","..ih..";"..imagedata[i].image.."]" + end + formstring = formstring .. "label["..nx..","..ny..";"..i.."]" + pos = pos + 1 + end + local bw, bh + + return formstring, ih +end + +-- Direct formspec +doc.entry_builders.formspec = function(data) + return data +end + +--[[ Internal stuff ]] + +-- Loading and saving player data +do + local filepath = minetest.get_worldpath().."/doc.mt" + local file = io.open(filepath, "r") + if file then + minetest.log("action", "[doc] doc.mt opened.") + local string = file:read() + io.close(file) + if(string ~= nil) then + local savetable = minetest.deserialize(string) + for name, players_stored_data in pairs(savetable.players_stored_data) do + doc.data.players[name] = {} + doc.data.players[name].stored_data = players_stored_data + end + minetest.debug("[doc] doc.mt successfully read.") + end + end +end + +function doc.save_to_file() + local savetable = {} + savetable.players_stored_data = {} + for name, playerdata in pairs(doc.data.players) do + savetable.players_stored_data[name] = playerdata.stored_data + end + + local savestring = minetest.serialize(savetable) + + local filepath = minetest.get_worldpath().."/doc.mt" + local file = io.open(filepath, "w") + if file then + file:write(savestring) + io.close(file) + minetest.log("action", "[doc] Wrote player data into "..filepath..".") + else + minetest.log("error", "[doc] Failed to write player data into "..filepath..".") + end +end + +minetest.register_on_leaveplayer(function(player) + doc.save_to_file() +end) + +minetest.register_on_shutdown(function() + minetest.log("action", "[doc] Server shuts down. Player data is about to be saved.") + doc.save_to_file() +end) + +--[[ Functions for internal use ]] + +function doc.formspec_core(tab) + if tab == nil then tab = 1 else tab = tostring(tab) end + return "size["..doc.FORMSPEC.WIDTH..","..doc.FORMSPEC.HEIGHT.."]tabheader[0,0;doc_header;".. + minetest.formspec_escape(S("Category list")) .. "," .. + minetest.formspec_escape(S("Entry list")) .. "," .. + minetest.formspec_escape(S("Entry")) .. ";" + ..tab..";true;true]" .. + "bgcolor[#343434FF]" +end + +function doc.formspec_main(playername) + local formstring = "label[0,0;"..minetest.formspec_escape(DOC_INTRO) .. "\n" + if doc.get_category_count() >= 1 then + formstring = formstring .. F("Please select a category you wish to learn more about:").."]" + if doc.get_category_count() <= (CATEGORYFIELDSIZE.WIDTH * CATEGORYFIELDSIZE.HEIGHT) then + local y = 1 + local x = 1 + -- Show all categories in order + for c=1,#doc.data.category_order do + local id = doc.data.category_order[c] + local data = doc.data.categories[id] + local bw = doc.FORMSPEC.WIDTH / math.floor(((doc.data.category_count-1) / CATEGORYFIELDSIZE.HEIGHT)+1) + -- Skip categories which do not exist + if data ~= nil then + -- Category buton + local button = "button["..((x-1)*bw)..","..y..";"..bw..",1;doc_button_category_"..id..";"..minetest.formspec_escape(data.def.name).."]" + local tooltip = "" + -- Optional description + if data.def.description ~= nil then + tooltip = "tooltip[doc_button_category_"..id..";"..minetest.formspec_escape(data.def.description).."]" + end + formstring = formstring .. button .. tooltip + y = y + 1 + if y > CATEGORYFIELDSIZE.HEIGHT then + x = x + 1 + y = 1 + end + end + end + else + formstring = formstring .. "textlist[0,1;"..(doc.FORMSPEC.WIDTH-0.2)..","..(doc.FORMSPEC.HEIGHT-2)..";doc_mainlist;" + for c=1,#doc.data.category_order do + local id = doc.data.category_order[c] + local data = doc.data.categories[id] + formstring = formstring .. minetest.formspec_escape(data.def.name) + if c < #doc.data.category_order then + formstring = formstring .. "," + end + end + local sel = doc.data.categories[doc.data.players[playername].category] + if sel ~= nil then + formstring = formstring .. ";" + formstring = formstring .. doc.data.categories[doc.data.players[playername].category].order_position + end + formstring = formstring .. "]" + formstring = formstring .. "button[0,"..(doc.FORMSPEC.HEIGHT-1)..";3,1;doc_button_goto_category;"..F("Show category").."]" + end + else + formstring = formstring .. "]" + end + return formstring +end + +function doc.formspec_error_no_categories() + local formstring = "size[8,6]textarea[0.25,0;8,6;;" + formstring = formstring .. + minetest.formspec_escape( + colorize(COLOR_ERROR, S("Error: No help available.")) .. "\n\n" .. +S("No categories have been registered, but they are required to provide help.\nThe Documentation System [doc] does not come with help contents on its own, it needs additional mods to add help content. Please make sure such mods are enabled on for this world, and try again.")) .. "\n\n" .. +S("Recommended mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia.") + formstring = formstring .. ";]button_exit[3,5;2,1;okay;"..F("OK").."]" + return formstring +end + +function doc.formspec_error_hidden(category_id, entry_id) + local formstring = "size[8,6]textarea[0.25,0;8,6;;" + formstring = formstring .. minetest.formspec_escape( + colorize(COLOR_ERROR, S("Error: Access denied.")) .. "\n\n" .. + S("Access to the requested entry has been denied; this entry is secret. You may unlock access by progressing in the game. Figure out on your own how to unlock this entry.")) + formstring = formstring .. ";]button_exit[3,5;2,1;okay;"..F("OK").."]" + return formstring +end + +function doc.generate_entry_list(cid, playername) + local formstring + if doc.data.players[playername].entry_textlist == nil + or doc.data.players[playername].catsel_list == nil + or doc.data.players[playername].category ~= cid + or doc.data.players[playername].entry_textlist_needs_updating == true then + local entry_textlist = "textlist[0,1;"..(doc.FORMSPEC.WIDTH-0.2)..","..(doc.FORMSPEC.HEIGHT-2)..";doc_catlist;" + local counter = 0 + doc.data.players[playername].entry_ids = {} + local entries = doc.get_sorted_entry_names(cid) + doc.data.players[playername].catsel_list = {} + for i=1, #entries do + local eid = entries[i] + local edata = doc.data.categories[cid].entries[eid] + if doc.entry_revealed(playername, cid, eid) then + table.insert(doc.data.players[playername].entry_ids, eid) + doc.data.players[playername].catsel_list[eid] = counter + 1 + -- Colorize entries based on viewed status + local viewedprefix = COLOR_NOT_VIEWED + local name = edata.name + if name == nil or name == "" then + name = S("Nameless entry (@1)", eid) + if doc.entry_viewed(playername, cid, eid) then + viewedprefix = "#FF4444" + else + viewedprefix = COLOR_ERROR + end + elseif doc.entry_viewed(playername, cid, eid) then + viewedprefix = COLOR_VIEWED + end + entry_textlist = entry_textlist .. viewedprefix .. minetest.formspec_escape(name) .. "," + counter = counter + 1 + end + end + if counter >= 1 then + entry_textlist = string.sub(entry_textlist, 1, #entry_textlist-1) + end + local catsel = doc.data.players[playername].catsel + if catsel then + entry_textlist = entry_textlist .. ";"..catsel + end + entry_textlist = entry_textlist .. "]" + doc.data.players[playername].entry_textlist = entry_textlist + formstring = entry_textlist + doc.data.players[playername].entry_textlist_needs_updating = false + else + formstring = doc.data.players[playername].entry_textlist + end + return formstring +end + +function doc.get_sorted_entry_names(cid) + local sort_table = {} + local entry_table = {} + local cat = doc.data.categories[cid] + local used_eids = {} + -- Helper function to extract the entry ID out of the output table + local extract = function(entry_table) + local eids = {} + for k,v in pairs(entry_table) do + local eid = v.eid + table.insert(eids, eid) + end + return eids + end + -- Predefined sorting + if cat.def.sorting == "custom" then + for i=1,#cat.def.sorting_data do + local new_entry = table.copy(cat.entries[cat.def.sorting_data[i]]) + new_entry.eid = cat.def.sorting_data[i] + table.insert(entry_table, new_entry) + used_eids[cat.def.sorting_data[i]] = true + end + end + for eid,entry in pairs(cat.entries) do + local new_entry = table.copy(entry) + new_entry.eid = eid + if not used_eids[eid] then + table.insert(entry_table, new_entry) + end + table.insert(sort_table, entry.name) + end + if cat.def.sorting == "custom" then + return extract(entry_table) + else + table.sort(sort_table) + end + local reverse_sort_table = table.copy(sort_table) + for i=1, #sort_table do + reverse_sort_table[sort_table[i]] = i + end + local comp + if cat.def.sorting ~= "nosort" then + -- Sorting by user function + if cat.def.sorting == "function" then + comp = cat.def.sorting_data + -- Alphabetic sorting + elseif cat.def.sorting == "abc" or cat.def.sorting == nil then + comp = function(e1, e2) + if reverse_sort_table[e1.name] < reverse_sort_table[e2.name] then return true else return false end + end + end + table.sort(entry_table, comp) + end + + return extract(entry_table) +end + +function doc.formspec_category(id, playername) + local formstring + if id == nil then + formstring = "label[0,0;"..F("Help > (No Category)") .. "]" + formstring = formstring .. "label[0,0.5;"..F("You haven't chosen a category yet. Please choose one in the category list first.").."]" + formstring = formstring .. "button[0,1;3,1;doc_button_goto_main;"..F("Go to category list").."]" + else + formstring = "label[0,0;"..minetest.formspec_escape(S("Help > @1", doc.data.categories[id].def.name)).."]" + local total = doc.get_entry_count(id) + if total >= 1 then + local revealed = doc.get_revealed_count(playername, id) + if revealed == 0 then + formstring = formstring .. "label[0,0.5;"..F("Currently all entries in this category are hidden from you.\nUnlock new entries by progressing in the game.").."]" + formstring = formstring .. "button[0,1.5;3,1;doc_button_goto_main;"..F("Go to category list").."]" + else + formstring = formstring .. "label[0,0.5;"..F("This category has the following entries:").."]" + formstring = formstring .. doc.generate_entry_list(id, playername) + formstring = formstring .. "button[0,"..(doc.FORMSPEC.HEIGHT-1)..";3,1;doc_button_goto_entry;"..F("Show entry").."]" + formstring = formstring .. "label["..(doc.FORMSPEC.WIDTH-4)..","..(doc.FORMSPEC.HEIGHT-1)..";"..minetest.formspec_escape(S("Number of entries: @1", total)).."\n" + local viewed = doc.get_viewed_count(playername, id) + local hidden = total - revealed + local new = total - viewed - hidden + -- TODO/FIXME: Check if number of hidden/viewed entries is always correct + if viewed < total then + formstring = formstring .. colorize(COLOR_NOT_VIEWED, minetest.formspec_escape(S("New entries: @1", new))) + if hidden > 0 then + formstring = formstring .. "\n" + formstring = formstring .. colorize(COLOR_HIDDEN, minetest.formspec_escape(S("Hidden entries: @1", hidden))).."]" + else + formstring = formstring .. "]" + end + else + formstring = formstring .. F("All entries read.").."]" + end + end + else + formstring = formstring .. "label[0,0.5;"..F("This category is empty.").."]" + formstring = formstring .. "button[0,1.5;3,1;doc_button_goto_main;"..F("Go to category list").."]" + end + end + return formstring +end + +function doc.formspec_entry_navigation(category_id, entry_id) + if doc.get_entry_count(category_id) < 1 then + return "" + end + local formstring = "" + formstring = formstring .. "button["..(doc.FORMSPEC.WIDTH-2)..","..(doc.FORMSPEC.HEIGHT-0.5)..";1,1;doc_button_goto_prev;"..F("<").."]" + formstring = formstring .. "button["..(doc.FORMSPEC.WIDTH-1)..","..(doc.FORMSPEC.HEIGHT-0.5)..";1,1;doc_button_goto_next;"..F(">").."]" + formstring = formstring .. "tooltip[doc_button_goto_prev;"..F("Show previous entry").."]" + formstring = formstring .. "tooltip[doc_button_goto_next;"..F("Show next entry").."]" + return formstring +end + +function doc.formspec_entry(category_id, entry_id, playername) + local formstring + if category_id == nil then + formstring = "label[0,0;"..F("Help > (No Category)") .. "]" + formstring = formstring .. "label[0,0.5;"..F("You haven't chosen a category yet. Please choose one in the category list first.").."]" + formstring = formstring .. "button[0,1;3,1;doc_button_goto_main;"..F("Go to category list").."]" + elseif entry_id == nil then + formstring = "label[0,0;"..minetest.formspec_escape(S("Help > @1 > (No Entry)", doc.data.categories[category_id].def.name)) .. "]" + if doc.get_entry_count(category_id) >= 1 then + formstring = formstring .. "label[0,0.5;"..F("You haven't chosen an entry yet. Please choose one in the entry list first.").."]" + formstring = formstring .. "button[0,1.5;3,1;doc_button_goto_category;"..F("Go to entry list").."]" + else + formstring = formstring .. "label[0,0.5;"..F("This category does not have any entries.").."]" + formstring = formstring .. "button[0,1.5;3,1;doc_button_goto_main;"..F("Go to category list").."]" + end + else + + local category = doc.data.categories[category_id] + local entry = get_entry(category_id, entry_id) + local ename = entry.name + if ename == nil or ename == "" then + ename = S("Nameless entry (@1)", entry_id) + end + formstring = "label[0,0;"..minetest.formspec_escape(S("Help > @1 > @2", category.def.name, ename)).."]" + formstring = formstring .. category.def.build_formspec(entry.data, playername) + formstring = formstring .. doc.formspec_entry_navigation(category_id, entry_id) + end + return formstring +end + +function doc.process_form(player,formname,fields) + local playername = player:get_player_name() + --[[ process clicks on the tab header ]] + if(formname == "doc:main" or formname == "doc:category" or formname == "doc:entry") then + if fields.doc_header ~= nil then + local tab = tonumber(fields.doc_header) + local formspec, subformname, contents + local cid, eid + cid = doc.data.players[playername].category + eid = doc.data.players[playername].entry + if(tab==1) then + contents = doc.formspec_main(playername) + subformname = "main" + elseif(tab==2) then + contents = doc.formspec_category(cid, playername) + subformname = "category" + elseif(tab==3) then + doc.data.players[playername].galidx = 1 + contents = doc.formspec_entry(cid, eid, playername) + if cid ~= nil and eid ~= nil then + doc.mark_entry_as_viewed(playername, cid, eid) + end + subformname = "entry" + end + formspec = doc.formspec_core(tab)..contents + minetest.show_formspec(playername, "doc:" .. subformname, formspec) + return + end + end + if(formname == "doc:main") then + for cid,_ in pairs(doc.data.categories) do + if fields["doc_button_category_"..cid] then + doc.data.players[playername].catsel = nil + doc.data.players[playername].category = cid + doc.data.players[playername].entry = nil + doc.data.players[playername].entry_textlist_needs_updating = true + local formspec = doc.formspec_core(2)..doc.formspec_category(cid, playername) + minetest.show_formspec(playername, "doc:category", formspec) + break + end + end + if fields["doc_mainlist"] then + local event = minetest.explode_textlist_event(fields["doc_mainlist"]) + local cid = doc.data.category_order[event.index] + if cid ~= nil then + if event.type == "CHG" then + doc.data.players[playername].catsel = nil + doc.data.players[playername].category = cid + doc.data.players[playername].entry = nil + doc.data.players[playername].entry_textlist_needs_updating = true + elseif event.type == "DCL" then + doc.data.players[playername].catsel = nil + doc.data.players[playername].category = cid + doc.data.players[playername].entry = nil + doc.data.players[playername].entry_textlist_needs_updating = true + local formspec = doc.formspec_core(2)..doc.formspec_category(cid, playername) + minetest.show_formspec(playername, "doc:category", formspec) + end + end + end + if fields["doc_button_goto_category"] then + local cid = doc.data.players[playername].category + doc.data.players[playername].catsel = nil + doc.data.players[playername].entry = nil + doc.data.players[playername].entry_textlist_needs_updating = true + local formspec = doc.formspec_core(2)..doc.formspec_category(cid, playername) + minetest.show_formspec(playername, "doc:category", formspec) + end + elseif(formname == "doc:category") then + if fields["doc_button_goto_entry"] then + local cid = doc.data.players[playername].category + if cid ~= nil then + local eid = nil + local eids, catsel = doc.data.players[playername].entry_ids, doc.data.players[playername].catsel + if eids ~= nil and catsel ~= nil then + eid = eids[catsel] + end + doc.data.players[playername].galidx = 1 + local formspec = doc.formspec_core(3)..doc.formspec_entry(cid, eid, playername) + minetest.show_formspec(playername, "doc:entry", formspec) + doc.mark_entry_as_viewed(playername, cid, eid) + end + end + if fields["doc_button_goto_main"] then + local formspec = doc.formspec_core(1)..doc.formspec_main(playername) + minetest.show_formspec(playername, "doc:main", formspec) + end + if fields["doc_catlist"] then + local event = minetest.explode_textlist_event(fields["doc_catlist"]) + if event.type == "CHG" then + doc.data.players[playername].catsel = event.index + doc.data.players[playername].entry = doc.data.players[playername].entry_ids[event.index] + doc.data.players[playername].entry_textlist_needs_updating = true + elseif event.type == "DCL" then + local cid = doc.data.players[playername].category + local eid = nil + local eids, catsel = doc.data.players[playername].entry_ids, event.index + if eids ~= nil and catsel ~= nil then + eid = eids[catsel] + end + doc.mark_entry_as_viewed(playername, cid, eid) + doc.data.players[playername].entry_textlist_needs_updating = true + doc.data.players[playername].galidx = 1 + local formspec = doc.formspec_core(3)..doc.formspec_entry(cid, eid, playername) + minetest.show_formspec(playername, "doc:entry", formspec) + end + end + elseif(formname == "doc:entry") then + if fields["doc_button_goto_main"] then + local formspec = doc.formspec_core(1)..doc.formspec_main(playername) + minetest.show_formspec(playername, "doc:main", formspec) + elseif fields["doc_button_goto_category"] then + local formspec = doc.formspec_core(2)..doc.formspec_category(doc.data.players[playername].category, playername) + minetest.show_formspec(playername, "doc:category", formspec) + elseif fields["doc_button_goto_next"] then + if doc.data.players[playername].catsel == nil then return end -- emergency exit + local eids = doc.data.players[playername].entry_ids + local cid = doc.data.players[playername].category + local new_catsel= doc.data.players[playername].catsel + 1 + local new_eid = eids[new_catsel] + if #eids > 1 and new_catsel <= #eids then + doc.mark_entry_as_viewed(playername, cid, new_eid) + doc.data.players[playername].catsel = new_catsel + doc.data.players[playername].entry = new_eid + doc.data.players[playername].galidx = 1 + local formspec = doc.formspec_core(3)..doc.formspec_entry(cid, new_eid, playername) + minetest.show_formspec(playername, "doc:entry", formspec) + end + elseif fields["doc_button_goto_prev"] then + if doc.data.players[playername].catsel == nil then return end -- emergency exit + local eids = doc.data.players[playername].entry_ids + local cid = doc.data.players[playername].category + local new_catsel= doc.data.players[playername].catsel - 1 + local new_eid = eids[new_catsel] + if #eids > 1 and new_catsel >= 1 then + doc.mark_entry_as_viewed(playername, cid, new_eid) + doc.data.players[playername].catsel = new_catsel + doc.data.players[playername].entry = new_eid + doc.data.players[playername].galidx = 1 + local formspec = doc.formspec_core(3)..doc.formspec_entry(cid, new_eid, playername) + minetest.show_formspec(playername, "doc:entry", formspec) + end + elseif fields["doc_button_gallery_prev"] then + local cid, eid = doc.get_selection(playername) + if doc.data.players[playername].galidx - doc.data.players[playername].galrows > 0 then + doc.data.players[playername].galidx = doc.data.players[playername].galidx - doc.data.players[playername].galrows + end + local formspec = doc.formspec_core(3)..doc.formspec_entry(cid, eid, playername) + minetest.show_formspec(playername, "doc:entry", formspec) + elseif fields["doc_button_gallery_next"] then + local cid, eid = doc.get_selection(playername) + if doc.data.players[playername].galidx + doc.data.players[playername].galrows <= doc.data.players[playername].maxgalidx then + doc.data.players[playername].galidx = doc.data.players[playername].galidx + doc.data.players[playername].galrows + end + local formspec = doc.formspec_core(3)..doc.formspec_entry(cid, eid, playername) + minetest.show_formspec(playername, "doc:entry", formspec) + end + else + if fields["doc_inventory_plus"] and minetest.get_modpath("inventory_plus") then + doc.show_doc(playername) + return + end + end +end + +minetest.register_on_player_receive_fields(doc.process_form) + +minetest.register_chatcommand("helpform", { + params = "", + description = S("Open a window providing help entries about Minetest and more"), + privs = {}, + func = function(playername, param) + doc.show_doc(playername) + end, + } +) + +minetest.register_on_joinplayer(function(player) + local playername = player:get_player_name() + local playerdata = doc.data.players[playername] + if playerdata == nil then + -- Initialize player data + doc.data.players[playername] = {} + playerdata = doc.data.players[playername] + -- Gallery index, stores current index of first displayed image in a gallery + playerdata.galidx = 1 + -- Maximum gallery index (index of last image in gallery) + playerdata.maxgalidx = 1 + -- Number of rows in an gallery of the current entry + playerdata.galrows = 1 + -- Table for persistant data + playerdata.stored_data = {} + -- Contains viewed entries + playerdata.stored_data.viewed = {} + -- Count viewed entries + playerdata.stored_data.viewed_count = {} + -- Contains revealed/unhidden entries + playerdata.stored_data.revealed = {} + -- Count revealed entries + playerdata.stored_data.revealed_count = {} + else + -- Completely rebuild viewed and revealed counts from scratch + for cid, cat in pairs(doc.data.categories) do + if playerdata.stored_data.viewed[cid] == nil then + playerdata.stored_data.viewed[cid] = {} + end + if playerdata.stored_data.revealed[cid] == nil then + playerdata.stored_data.revealed[cid] = {} + end + local vc = 0 + local rc = doc.get_entry_count(cid) - doc.data.categories[cid].hidden_count + for eid, entry in pairs(cat.entries) do + if playerdata.stored_data.viewed[cid][eid] then + vc = vc + 1 + playerdata.stored_data.revealed[cid][eid] = true + end + if playerdata.stored_data.revealed[cid][eid] and entry.hidden then + rc = rc + 1 + end + end + playerdata.stored_data.viewed_count[cid] = vc + playerdata.stored_data.revealed_count[cid] = rc + end + end + + -- Add button for Inventory++ + if minetest.get_modpath("inventory_plus") ~= nil then + inventory_plus.register_button(player, "doc_inventory_plus", S("Help")) + end +end) + +---[[ Add buttons for inventory mods ]] +local button_action = function(player) + doc.show_doc(player:get_player_name()) +end + +--[[ +-- Unified Inventory +if minetest.get_modpath("unified_inventory") ~= nil then + unified_inventory.register_button("doc", { + type = "image", + image = "doc_button_icon_hires.png", + tooltip = S("Help"), + action = button_action, + }) +end + +-- sfinv_buttons +if minetest.get_modpath("sfinv_buttons") ~= nil then + sfinv_buttons.register_button("doc", { + image = "doc_button_icon_lores.png", + tooltip = S("Collection of help texts"), + title = S("Help"), + action = button_action, + }) +end +--]] + +minetest.register_privilege("help_reveal", { + description = S("Allows you to reveal all hidden help entries with /help_reveal"), + give_to_singleplayer = false +}) + +minetest.register_chatcommand("help_reveal", { + params = "", + description = S("Reveal all hidden help entries to you"), + privs = { help_reveal = true }, + func = function(name, param) + doc.mark_all_entries_as_revealed(name) + end, +}) diff --git a/mods/doc_modpack/doc/locale/de.txt b/mods/doc_modpack/doc/locale/de.txt new file mode 100644 index 0000000..113307e --- /dev/null +++ b/mods/doc_modpack/doc/locale/de.txt @@ -0,0 +1,42 @@ +< = < +> = > +Access to the requested entry has been denied; this entry is secret. You may unlock access by progressing in the game. Figure out on your own how to unlock this entry. = Der Zugriff auf den angeforderten Eintrag wurde verweigert; dieser Eintrag ist geheim. Sie können durch weiteren Spielfortschritt den Zugriff freischalten. Finden Sie selbst heraus, wie Sie diesen Eintrag freischalten können. +All entries read. = Alle Einträge gelesen. +All help entries revealed! = Alle Hilfseinträge aufgedeckt! +All help entries are already revealed. = Alle Hilfseinträge sind schon aufgedeckt. +Allows you to reveal all hidden help entries with /help_reveal = Ermöglicht es Ihnen, alle verborgenen Hilfseinträge mit /help_reveal freizuschalten +Category list = Kategorienliste +Currently all entries in this category are hidden from you.\nUnlock new entries by progressing in the game. = Momentan sind alle Einträge in dieser Kategorie vor Ihnen verborgen.\nSchalten Sie neue Einträge frei, indem Sie im Spiel fortschreiten. +Help = Hilfe +Entry = Eintrag +Entry list = Eintragsliste +Error: Access denied. = Fehler: Zugriff verweigert. +Error: No help available. = Fehler: Keine Hilfe verfügbar. +Go to category list = Zur Kategorienliste +Go to entry list = Zur Eintragsliste +Help > (No Category) = Hilfe > (Keine Kategorie) +Help > @1 = Hilfe > @1 +Help > @1 > @2 = Hilfe > @1 > @2 +Help > @1 > (No Entry) = Hilfe > @1 > (Kein Eintrag) +Hidden entries: @1 = Verborgene Einträge: @1 +New entries: @1 = Neue Einträge: @1 +New help entry unlocked: @1 > @2 = Neuen Hilfseintrag freigeschaltet: @1 > @2 +No categories have been registered, but they are required to provide help.\nThe Documentation System [doc] does not come with help contents on its own, it needs additional mods to add help content. Please make sure such mods are enabled on for this world, and try again. = Es wurden keine Kategorien registriert, aber sie werden benötigt, um die Hilfe anbieten zu können.\nDas Dokumentationssystem [doc] bringt von sich aus keine eigenen Hilfsinhalte mit, es benötigt zusätzliche Mods, um sie hinzuzufügen. Bitte stellen Sie sicher, dass solche Mods für diese Welt aktiviert sind und versuchen Sie es erneut. +Number of entries: @1 = Anzahl der Einträge: @1 +OK = OK +Open a window providing help entries about Minetest and more = Ein Fenster mit Hilfseinträgen über Minetest und mehr öffnen +Please select a category you wish to learn more about: = Bitte wählen Sie eine Kategorie, über die Sie mehr erfahren möchten, aus: +Recommended mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia. = Empfohlene Mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia. +Reveal all hidden help entries to you = Alle für Sie verborgenen Hilfseinträge freischalten +Show entry = Eintrag zeigen +Show category = Kategorie zeigen +Show next entry = Nächsten Eintrag zeigen +Show previous entry = Vorherigen Eintrag zeigen +This category does not have any entries. = Diese Kategorie hat keine Einträge. +This category has the following entries: = Diese Kategorie hat die folgenden Einträge: +This category is empty. = Diese Kategorie ist leer. +This is the help. = Dies ist die Hilfe. +You haven't chosen a category yet. Please choose one in the category list first. = Sie haben noch keine Kategorie gewählt. Bitte wählen Sie zuerst eine Kategorie in der Kategorienliste aus. +You haven't chosen an entry yet. Please choose one in the entry list first. = Sie haben noch keinen Eintrag gewählt. Bitte wählen Sie zuerst einen Eintrag in der Eintragsliste aus. +Nameless entry (@1) = Namenloser Eintrag (@1) +Collection of help texts = Sammlung von Hilfstexten diff --git a/mods/doc_modpack/doc/locale/template.txt b/mods/doc_modpack/doc/locale/template.txt new file mode 100644 index 0000000..7d852e9 --- /dev/null +++ b/mods/doc_modpack/doc/locale/template.txt @@ -0,0 +1,42 @@ +< = +> = +Access to the requested entry has been denied; this entry is secret. You may unlock access by progressing in the game. Figure out on your own how to unlock this entry. = +All entries read. = +All help entries revealed! = +All help entries are already revealed. = +Allows you to reveal all hidden help entries with /help_reveal = +Category list = +Currently all entries in this category are hidden from you.\\nUnlock new entries by progressing in the game. = +Help = +Entry = +Entry list = +Error: Access denied. = +Error: No help available. = +Go to category list = +Go to entry list = +Help > @1 = +Help > @1 > @2 = +Help > @1 > (No Entry) = +Help > (No Category) = +Hidden entries: @1 = +Nameless entry (@1) = +New entries: @1 = +New help entry unlocked: @1 > @2 = +No categories have been registered, but they are required to provide help.\nThe Documentation System [doc] does not come with help contents on its own, it needs additional mods to add help content. Please make sure such mods are enabled on for this world, and try again. = +Number of entries: @1 = +OK = +Open a window providing help entries about Minetest and more = +Please select a category you wish to learn more about: = +Recommended mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia. = +Reveal all hidden help entries to you = +Show entry = +Show category = +Show next entry = +Show previous entry = +This category does not have any entries. = +This category has the following entries: = +This category is empty. = +This is the help. = +You haven't chosen a category yet. Please choose one in the category list first. = +You haven't chosen an entry yet. Please choose one in the entry list first. = +Collection of help texts = diff --git a/mods/doc_modpack/doc/mod.conf b/mods/doc_modpack/doc/mod.conf new file mode 100644 index 0000000..5e2f430 --- /dev/null +++ b/mods/doc_modpack/doc/mod.conf @@ -0,0 +1 @@ +name = doc diff --git a/mods/doc_modpack/doc/sounds/doc_reveal.ogg b/mods/doc_modpack/doc/sounds/doc_reveal.ogg new file mode 100644 index 0000000..3fbe176 Binary files /dev/null and b/mods/doc_modpack/doc/sounds/doc_reveal.ogg differ diff --git a/mods/doc_modpack/doc/textures/doc_awards_icon_generic.png b/mods/doc_modpack/doc/textures/doc_awards_icon_generic.png new file mode 100644 index 0000000..b33fa34 Binary files /dev/null and b/mods/doc_modpack/doc/textures/doc_awards_icon_generic.png differ diff --git a/mods/doc_modpack/doc/textures/doc_button_icon_hires.png b/mods/doc_modpack/doc/textures/doc_button_icon_hires.png new file mode 100644 index 0000000..25c9fe4 Binary files /dev/null and b/mods/doc_modpack/doc/textures/doc_button_icon_hires.png differ diff --git a/mods/doc_modpack/doc/textures/doc_button_icon_lores.png b/mods/doc_modpack/doc/textures/doc_button_icon_lores.png new file mode 100644 index 0000000..3df6195 Binary files /dev/null and b/mods/doc_modpack/doc/textures/doc_button_icon_lores.png differ diff --git a/mods/doc_modpack/doc/textures/inventory_plus_doc_inventory_plus.png b/mods/doc_modpack/doc/textures/inventory_plus_doc_inventory_plus.png new file mode 100644 index 0000000..3df6195 Binary files /dev/null and b/mods/doc_modpack/doc/textures/inventory_plus_doc_inventory_plus.png differ diff --git a/mods/doc_modpack/doc_basics/README.md b/mods/doc_modpack/doc_basics/README.md new file mode 100644 index 0000000..2125bed --- /dev/null +++ b/mods/doc_modpack/doc_basics/README.md @@ -0,0 +1,12 @@ +# Basic help [`doc_basics`] +Adds basic help texts about Minetest, controls, gameplay and other basics. +This mod uses the Documentation System [`doc`] as a basis and adds these +categories: + +* Basics: Basic gameplay information (e.g. how to craft) +* Advanced usage: Advanced Minetest information (not gameplay-releavant) for power users (e.g. how to use commands) + +Version: 1.0.0 + +## License +Everything in this mod is licensed under the MIT License. diff --git a/mods/doc_modpack/doc_basics/depends.txt b/mods/doc_modpack/doc_basics/depends.txt new file mode 100644 index 0000000..31aa390 --- /dev/null +++ b/mods/doc_modpack/doc_basics/depends.txt @@ -0,0 +1,2 @@ +doc +intllib? diff --git a/mods/doc_modpack/doc_basics/description.txt b/mods/doc_modpack/doc_basics/description.txt new file mode 100644 index 0000000..f86a1b5 --- /dev/null +++ b/mods/doc_modpack/doc_basics/description.txt @@ -0,0 +1 @@ +Adds some help texts explaining how to use Minetest. diff --git a/mods/doc_modpack/doc_basics/init.lua b/mods/doc_modpack/doc_basics/init.lua new file mode 100644 index 0000000..dea6b7e --- /dev/null +++ b/mods/doc_modpack/doc_basics/init.lua @@ -0,0 +1,780 @@ +--[[ +- TODO: Allow to disable images to save bandwidth +- TODO: Add API for subgame-specific changes so the entries are not too awfully generic + - Support for landing page + - Support to modify some parts of existing entries +- TODO: Add introduction to online play (if possible) +- TODO: Ideas for advanced entries: + - Sneak Glitch? + - Rendering (far view, etc.) +-- TODO: Better (official) support for customizable creative page +]] + +-- Boilerplate to support localized strings if intllib mod is installed. +local S +if minetest.get_modpath("intllib") then + S = intllib.Getter() +else + S = function(s) return s end +end + +doc.add_category("basics", +{ + name = S("Basics"), + description = S("Everything you need to know about Minetest to get started with playing"), + sorting = "custom", + sorting_data = {"quick_start", "minetest", "controls", "point", "items", "inventory", "hotbar", "tools", "weapons", "nodes", "mine", "build", "craft", "cook", "minimap", "cam", "sneak", "players", "liquids", "light", "groups", "glossary"}, + build_formspec = doc.entry_builders.text_and_gallery, +}) + +doc.add_category("advanced", +{ + name = S("Advanced usage"), + description = S("Advanced information about Minetest which may be nice to know, but is not crucial to gameplay"), + sorting = "custom", + sorting_data = {"console", "commands", "privs", "movement_modes", "coordinates", "settings", "online"}, + build_formspec = doc.entry_builders.text_and_gallery, +}) + +doc.add_entry("basics", "quick_start", { + name = S("Quick start"), + data = { text = +S("This is a very brief introduction to the basic gameplay:").."\n\n".. + +S("• Move mouse to look").."\n".. +S("• [W], [A], [S] and [D] to move").."\n".. +S("• [Space] to jump or move upwards").."\n".. +S("• [Shift] to sneak or move downwards").."\n".. +S("• Mouse wheel or [0]-[9] to select item").."\n".. +S("• Left-click to mine blocks or attack").."\n".. +S("• Recover from swings to deal full damage").."\n".. +S("• Right-click to build blocks and use things").."\n".. +S("• [I] for the inventory").."\n".. +S("• First items in inventory appear in hotbar below").."\n".. +S("• [F9] for the minimap").."\n".. +S("• Put items into crafting grid (usually 3×3 grid) to craft").."\n".. +S("• Use a crafting guide mod to learn crafting recipes or visit ").."\n".. +S("• Read entries in this help to learn the rest").."\n".. +S("• [Esc] to close this window") +}}) + +doc.add_entry("basics", "minetest", { + name = S("Minetest"), + data = { + text = +S("Minetest is a free software game engine for games based on voxel gameplay, inspired by InfiniMiner, Minecraft, and the like. Minetest was originally created by Perttu Ahola (alias “celeron55â€).").."\n\n".. + +S("The player is thrown into a huge world made out of cubes or blocks. These cubes usually make the landscape they blocks can be removed and placed almost entirely freely. Using the collected items, new tools and other items can be crafted. Games in Minetest (also called “subgamesâ€) can, however, be much more complex than this.").."\n\n".. + +S("A core feature of Minetest is the built-in modding capability. Mods modify existing gameplay. They can be as simple as adding a few decorational blocks or be very complex by e.g. introducing completely new gameplay concepts, generating a completely different kind of world, and many other things.").."\n\n".. + +S("Minetest can be played alone or online together with multiple players. Online play will work out of the box with any mods, with no need for additional software as they are entirely provided by the server.").."\n\n".. + +S("Minetest is usually bundled with a simple default game, named “Minetest Game†(shown in images 1 and 2). You probably already have it. Other games for Minetest can be downloaded from the official Minetest forums .").."\n\n".. + +S("Minetest as well as Minetest Game are both unfinished at the moment, so please forgive us when not everything works out perfectly."), + images = {{image="doc_basics_gameplay_mtg_1.png"}, {image="doc_basics_gameplay_mtg_2.png"}, {image="doc_basics_gameplay_carbone_ng.png"}, {image="doc_basics_gameplay_lott.png"}, {image="doc_basics_gameplay_pixture.png"}, {image="doc_basics_gameplay_outback.png"}, {image="doc_basics_gameplay_moontest.png"}, +{image="doc_basics_gameplay_hades.png"}, {image="doc_basics_gameplay_xtraores_xtension.png"},} +}}) + +doc.add_entry("basics", "sneak", { + name = S("Sneaking"), + data = { text = +S("Sneaking makes you walk slower and prevents you from falling off the edge of a block.").."\n".. +S("To sneak, hold down the sneak key (default: [Shift]). When you release it, you stop sneaking. Careful: When you release the sneak key at a ledge, you might fall!").."\n\n".. + +S("• Sneak: [Shift]").."\n\n".. + +S("Sneaking only works when you stand on solid ground, are not in a liquid and don't climb.").."\n\n".. + +S("If you jump while holding the sneak key, you also jump slightly higher than usual.").."\n\n".. + +S("Sneaking might be disabled by mods. In this case, you still walk slower by sneaking, but you will no longer be stopped at ledges."), + images = { { image = "doc_basics_sneak.png" } }, +}}) + +doc.add_entry("basics", "controls", { + name = S("Controls"), + data = { text = +S("These are the default controls:").."\n\n".. + +S("Basic movement:").."\n".. +S("• Moving the mouse around: Look around").."\n".. +S("• W: Move forwards").."\n".. +S("• A: Move to the left").."\n".. +S("• D: Move to the right").."\n".. +S("• S: Move backwards").."\n\n".. + +S("While standing on solid ground:").."\n".. +S("• Space: Jump").."\n".. +S("• Shift: Sneak").."\n\n".. + +S("While on a ladder, swimming in a liquid or fly mode is active").."\n".. +S("• Space: Move up").."\n".. +S("• Shift: Move down").."\n\n".. + +S("Extended movement (requires privileges):").."\n".. +S("• J: Toggle fast mode, makes you run or fly fast (requires “fast†privilege)").."\n".. +S("• K: Toggle fly mode, makes you move freely in all directions (requires “fly†privilege)").."\n".. +S("• H: Toggle noclip mode, makes you go through walls in fly mode (requires “noclip†privilege)").."\n".. +S("• E: Walk fast in fast mode").."\n\n".. + +S("World interaction:").."\n".. +S("• Left mouse button: Punch / mine blocks / take items").."\n".. +S("• Right mouse button: Build or use pointed block").."\n".. +S("• Shift+Right mouse button: Build").."\n".. +S("• Roll mouse wheel: Select next/previous item in hotbar").."\n".. +S("• 0-9: Select item in hotbar directly").."\n".. +S("• Q: Drop item stack").."\n".. +S("• Shift+Q: Drop 1 item").."\n".. +S("• I: Show/hide inventory menu").."\n\n".. + +S("Inventory interaction:").."\n".. +S("See the entry “Basics > Inventoryâ€.").."\n\n".. + +S("Camera:").."\n".. +S("• Z: Zoom (requires “zoom†privilege)").."\n".. +S("• F7: Toggle camera mode").."\n".. +S("• F8: Toggle cinematic mode").."\n\n".. + +S("Interface:").."\n".. +S("• Esc: Open menu window (pauses in single-player mode) or close window").."\n".. +S("• F1: Show/hide HUD").."\n".. +S("• F2: Show/hide chat").."\n".. +S("• F9: Toggle minimap").."\n".. +S("• Shift+F9: Toggle minimap rotation mode").."\n".. +S("• F10: Open/close console/chat log").."\n".. +S("• F12: Take a screenshot").."\n\n".. + +S("Server interaction:").."\n".. +S("• T: Open chat window (chat requires the “shout†privilege)").."\n".. +S("• /: Start issuing a server command)").."\n\n".. + +S("Technical:").."\n".. +S("• R: Toggle far view (disables all fog and allows viewing far away, can make game very slow)").."\n".. +S("• +: Increase minimal viewing distance").."\n".. +S("• -: Decrease minimal viewing distance").."\n".. +S("• F3: Enable/disable fog").."\n".. +S("• F5: Enable/disable debug screen which also shows your coordinates").."\n".. +S("• F6: Only useful for developers. Enables/disables profiler").."\n".. +S("• P: Only useful for developers. Writes current stack traces") +}}) + +doc.add_entry("basics", "players", { + name = S("Players"), + data = { + text = +S("Players (actually: “player charactersâ€) are the characters which users control.").."\n\n".. + +S("Players are living beings which occupy a space of about 1×2×1 cubes. They start with 20 health points (HP) and 10 breath points (BP).").."\n".. +S("Players are capable of walking, sneaking, jumping, climbing, swimming, diving, mining, building, fighting and using tools and blocks.").."\n".. + +S("Players can take damage for a variety of reasons, here are some:\ +• Taking fall damage\ +• Touching a block which causes direct damage\ +• Drowning\ +• Being attacked by another player\ +• Being attacked by a computer enemy").."\n\n".. + +S("At a health of 0, the player dies. The player can just respawn in the world.").."\n".. +S("Other consequences of death depend on the subgame. The player could lose all items, or lose the round in a competitive game.").."\n\n".. + +S("Some blocks reduce breath. While being with the head in a block which causes drowning, the breath points are reduced by 1 for every 2 seconds. When all breath is gone, the player starts to suffer drowning damage. Breath is quickly restored in any other block.").."\n\n".. + +S("Damage can be disabled on any world. Without damage, players are immortal and health and breath are unimportant.").."\n\n".. + +S("In multi-player mode, the name of other players is written above their head."), + images = {{image="doc_basics_players_sam.png"}, {image="doc_basics_players_lott.png"}, {image="doc_basics_players_flat.png"}}, +}}) + +doc.add_entry("basics", "items", { + name = S("Items"), + data = { + text = +S("Items are things you can carry along and store in inventories. They can be used for crafting, smelting, building, mining, and more. Types of items include blocks, tools, weapons and items only used for crafting.").."\n\n".. + +S("An item stack is a collection of items of the same type which fits into a single item slot. Item stacks can be dropped on the ground. Items which drop into the same coordinates will form an item stack.").."\n\n".. + +S("Items have several properties, including the following:\ +\ +• Maximum stack size: Number of items which fit on 1 item stack\ +• Pointing range: How close things must be to be pointed while wielding this item\ +• Group memberships: See “Basics > Groupsâ€\ +• May be used for crafting or cooking").."\n\n".. + +S("A dropped item stack can be collected by punching it."), + images = {{image="doc_basics_inventory_detail.png"}, {image="doc_basics_items_dropped.png"}}, +}}) + +doc.add_entry("basics", "tools", { + name = S("Tools"), + data = { text = +S("Some items may serve as a tool when wielded. Any item which has some special use which can be directly used by its wielder is considered a tool.").."\n\n".. + +S("A common tool in Minetest are, of course, mining tools. These are important to break all kinds of blocks. Weapons are a kind of tool in Minetest. There are of course many other possible tools. Special actions of tools are usually done by left-click or right-click.").."\n\n".. + +S("When nothing is wielded, players use their hand which may act as tool and weapon. The hand is capable of collecting dropped items by punching.").."\n\n".. + +S("Many tools will wear off when using them and may eventually get destroyed. The damage is displayed in a damage bar below the tool icon. If no damage bar is shown, the tool is in mint condition. Tools may be repairable by crafting, see “Basics > Craftingâ€."), + images = {{image="doc_basics_tools.png"}, {image="doc_basics_tools_mining.png"}}, +}}) + +doc.add_entry("basics", "weapons", { + name = S("Weapons"), + data = { text = +S("Some items are usable as a melee weapon when wielded. Weapons share most of the properties of tools.").."\n\n".. + +S("Melee weapons deal damage by punching players and other animate objects. There are two ways to attack:").."\n".. +S("• Single punch: Left-click once to deal a single punch").."\n".. +S("• Quick punching: Hold down the left mouse button to deal quick repeated punches").."\n\n".. + +S("There are two core attributes of melee weapons:").."\n".. +S("• Maximum damage: Damage which is dealt after a hit when the weapon was fully recovered)").."\n".. +S("• Full punch interval: Time it takes for fully recovering from a punch").."\n\n".. + +S("A weapon only deals full damage when it has fully recovered from a previous punch. Otherwise, the weapon will deal only reduced damage. This means, quick punching is very fast, but also deals rather low damage. Note the full punch interval does not limit how fast you can attack.").."\n\n".. + +S("There is a rule which sometimes makes attacks impossible: Players, animate objects and weapons belong to damage groups. A weapon only deals damage to those who share at least one damage group with it. So if you're using the wrong weapon, you might not deal any damage at all.") +}}) + + +doc.add_entry("basics", "point", { + name = S("Pointing"), + data = { + text = +S("“Pointing†means looking at something in range with the crosshair. Pointing is needed for interaction, like mining, punching, using, etc. Pointable things include blocks, dropped items, players, computer enemies and objects.").."\n\n".. + +S("To point something, it must be in the pointing range (also just called “rangeâ€) of your wielded item. There's a default range when you are not wielding anything. A pointed thing will be outlined or highlighted (depending on your settings). Pointing is not possible with the 3rd person front camera.").."\n\n".. + +S("A few things can not be pointed. Most blocks are pointable. A few blocks, like air, can never be pointed. Other blocks, like liquids can only be pointed by special items."), + images = {{ image = "doc_basics_pointing.png" }}, +}}) + +doc.add_entry("basics", "cam", { + name = S("Camera"), + data = { + text = +S("Minetest has 3 different views which determine the way you see the world. The modes are:\ +\ +• 1: First-person view (default)\ +• 2: Third-person view from behind\ +• 3: Third-person view from the front").."\n\n".. + +S("You can change the camera mode by pressing [F7].").."\n".. +S("There is also Cinematic Mode which can be toggled with [F8]. With Cinematic Mode enabled, the camera movements become more smooth. Some players don't like it, it is a matter of taste.").."\n".. +S("By holding down [Z], you can zoom the view at your crosshair. You need the “zoom†privilege to do this.").."\n\n".. + +S("• Switch camera mode: [F7]").."\n".. +S("• Toggle Cinematic Mode: [F8]").."\n".. +S("• Zoom: [Z]"), + images = {{image="doc_basics_camera_ego.png"}, {image="doc_basics_camera_behind.png"}, {image="doc_basics_camera_front.png"}} +}}) + +doc.add_entry("basics", "nodes", { + name = S("Blocks"), + data = { + text = +S("The world of Minetest is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.").."\n\n".. + +S("Blocks can have a wide range of different properties which determine mining times, behavior, looks, shape, and much more. Their properties include:").."\n\n".. + +S("• Collidable: Collidable blocks can not be passed through; players can walk on them. Non-collidable blocks can be passed through freely").."\n".. +S("• Pointable: Pointable blocks show a wireframe or a halo box when pointed. But you will just point through non-pointable blocks. Liquids are usually non-pointable but they can be pointed at by some special tools").."\n".. +S("• Mining properties: By which tools it can be mined, how fast and how much it wears off tools").."\n".. +S("• Climbable: While you are at a climbable block, you won't fall and you can move up and down with the jump and sneak keys").."\n".. +S("• Drowning damage: See the entry “Basics > Playerâ€").."\n".. +S("• Liquids: See the entry “Basics > Liquidsâ€").."\n".. +S("• Group memberships: Group memberships are used to determine mining properties, crafting, interactions between blocks and more"), + images = {{image="doc_basics_nodes.png"}} +}}) + +-- TODO: Oh jeez, this explanation is WAY too difficult. Maybe we need to find some way to make it easier to understand. +doc.add_entry("basics", "mine", { + name = S("Mining"), + data = { + text = +S("Mining (or digging) is the process of breaking blocks to remove them. To mine a block, point it and hold down the left mouse button until it breaks.").."\n\n".. + +S("Short explanation:").."\n\n".. + +S("Blocks require a mining tool to be mined. Different blocks are mined by different mining tools, and some blocks can not be mined by any tool. Blocks vary in toughness and tools vary in strength. Mining tools will wear off over time. The mining time and the tool wear depend on the block and the mining tool. The fastest way to find out how efficient your mining tools are is by just trying them out on various blocks. Any items you gather by mining go straight into your inventory.") .. "\n\n".. + +S("Detailed explanation:").."\n\n".. + +S("Mineable blocks have mining properties (based on groups) and a toughness level. Mining tools have the same properties. Each mining property of a block also has a rating, while tools can be able to break blocks within a range of ratings.").."\n\n".. + +S("In order to mine a block, these conditions need to be met:").."\n".. +S("• The block and tool share at least one mining property for which they have a matching rating").."\n".. +S("• The tool's toughness level is equal or less than the block's toughness level").."\n\n".. + +S("Example: A block with the mining property “crackyâ€, rating 3 and toughness level 0 can only be broken by a tool which is able to break “cracky†blocks at rating 3 and it must have a toughness level of 0 or larger.").."\n\n".. + +S("The time it takes to mine a block depends on the ratings and the toughness levels of both tool and block.").."\n".. +S("• The base mining time depends on the ratings of the block and the mining speed of the tool").."\n".. +S("• The mining speed of the tool differs for each mining property and its rating").."\n".. +S("• The toughness level further modifies the mining speed for this mining proeprty").."\n".. +S("• A high difference in toughness levels decreases the mining time considerably").."\n".. +S("• If the toughness level difference is 2, the mining time is half of the base mining time").."\n".. +S("• If the a difference of 3, the mining time is a third, and so on").."\n\n".. + +S("The item help shows the mining times of a tool listed by its mining properties and its ratings. The mining times are often expressed as a range. The low number stands for the mining time for toughness level 0 and the high number for the highest level the tool can mine.").."\n\n".. + +S("Mining usually wears off tools. Each time you mine a block, your tool takes some damage until it is destroyed eventually. The wear per mined block determined by the difference between the tool's toughness level and the block's toughness level. The higher the difference, the lower the wear. This means:").."\n".. +S("• High-level blocks wear off your tools faster").."\n".. +S("• You can use high-level tools to compensate this").."\n".. +S("• The highest wear is caused when the level of both tool and block are equal").."\n\n".. + +S("After mining, a block may leave a “drop†behind. This is a number of items you get after mining. Most commonly, you will get the block itself. There are other possibilities for a drop which depends on the block type. The following drops are possible:").."\n".. +S("• Always drops itself (the usual case)").."\n".. +S("• Always drops the same items").."\n".. +S("• Drops items based on probability").."\n".. +S("• Drops nothing").."\n\n".. + +S("The drop goes directly into your inventory, unless there's no more space left. In that case, the items literally drop on the floor."), + images = {{image="doc_basics_tools_mining.png"}}, +}}) + +doc.add_entry("basics", "build", { + name = S("Building"), + data = { + text = +S("Almost all blocks can be built (or placed). Building is very simple and has no delay.").."\n\n".. + +S("To build your wielded block, point at a block in the world and right-click. If this is not possible because the pointed block has a special right-click action, hold down the sneak key before right-clicking.").."\n\n".. + +S("Blocks can almost always be built at pointable blocks. One exception are blocks attached to the floor; these can only be built on the floor.").."\n\n".. + +S("Normally, blocks are built in front of the pointed side of the pointed block. A few blocks are different: When you try to build at them, they are replaced."), + images = {{image="doc_basics_build.png"}}, +}}) + + + +doc.add_entry("basics", "liquids", { + name = S("Liquids"), + data = { + text = +S("Liquids are special dynamic blocks. Liquids like to spread and flow to their surrounding blocks. Players can swim and drown in them.").."\n\n".. + +S("Liquids usually come in two forms: In source form (S) and in flowing form (F).").."\n".. +S("Liquid sources have the shape of a full cube. A liquid source will generate flowing liquids around it from time to time, and, if the liquid is renewable, it also generates liquid sources. A liquid source can sustain itself. A long it is left alone, a liquid source will normally keep its place and does not drain out.").."\n".. +S("Flowing liquids take a sloped form. Flowing liquids spread around the world until they drain. A flowing liquid can not sustain itself and always comes from a liquid source, either directly or indirectly. Without a liquid source, a flowing liquid will eventually drain out and disappear.").."\n".. + +S("All liquids share the following properties:").."\n".. +S("• All properties of blocks (including drowning damage").."\n".. +S("• Renewability: Renewable liquids can create new sources").."\n".. +S("• Flowing range: How many flowing liquids are created at maximum per liquid source, it determines how far the liquid will spread. Possible are ranges from 0 to 8. At 0, no flowing liquids will be created. Image 5 shows a liquid of flowing range 2").."\n".. +S("• Viscosity: How slow players move through it and how slow the liquid spreads").."\n\n".. + +S("Renewable liquids create new liquid sources at open spaces (image 2). A new liquid source is created when:\ +• Two renewable liquid blocks of the same type touch each other diagonally\ +• These blocks are also on the same height\ +• One of the two “corners†is open space which allows liquids to flow in").."\n\n".. + +S("When those criteria are met, the open space is filled with a new liquid source of the same type (image 3).").."\n\n".. + +S("Swimming in a liquid is fairly straightforward: The usual direction keys for basic movement, the jump key for rising and the sneak key for sinking.").."\n\n".. + +S("The physics for swimming and diving in a liquid are:").."\n".. +S("• The higher the viscosity, the slower you move").."\n".. +S("• If you rest, you'll slowly sink").."\n".. +S("• There is no fall damage for falling into a liquid as such").."\n".. +S("• If you fall into a liquid, you will be slowed down on impact (but don't stop instantly). Your impact depth is determined by your speed and the liquid viscosity. For a safe high drop into a liquid, make sure there is enough liquid above the ground, otherwise you might hit the ground and take fall damage").."\n\n".. + +S("Liquids are often not pointable. But some special items are able to point all liquids."), + images = { + { image="doc_basics_liquids_types.png", + caption="A source liquid and its flowing liquids" }, + { image="doc_basics_liquids_renewable_1.png", + caption="Renewable liquids need to be arranged like this to create a new source block" }, + { image="doc_basics_liquids_renewable_2.png", + caption="A new liquid source is born" }, + { image="doc_basics_liquids_nonrenewable.png", + caption="Non-renewable liquids creates a flowing liquid (F) instead" }, + { image="doc_basics_liquids_range.png", + caption="Liquid with a flowing range of 2" }, + }, + }, +}) + +doc.add_entry("basics", "craft", { + name = S("Crafting"), + data = { + text = +S("Crafting is the task of combining several items to form a new item.").."\n\n".. + +S("To craft something, you need one or more items, a crafting grid (C) and a crafting recipe. A crafting grid is like a normal inventory which can also be used for crafting. Items need to be put in a certain pattern into the crafting grid. Next to the crafting grid is an output slot (O). Here the result will appear when you placed items correctly. This is just a preview, not the actual item. Crafting grids can come in different sizes which limits the possible recipes you can craft.").."\n\n".. + +S("To complete the craft, take the result item from the output slot, which will consume items from the crafting grid and creates a new item. It is not possible to place items into the output slot.").."\n\n".. + +S("A description on how to craft an item is called a “crafting recipeâ€. You need this knowledge to craft. There are multiple ways to learn crafting recipes. One way is by using a crafting guide, which contains a list of available crafting recipes. Some subgames provide crafting guides. There are also some mods which you can download online for installing a crafting guide. Another way is by reading the online manual of the subgame (if one is available).").."\n\n".. + +S("Crafting recipes consist of at least one input item and exactly one stack of output items. When performing a single craft, it will consume exactly one item from each stack of the crafting grid, unless the crafting recipe defines replacements.").."\n\n".. + +S("There are multiple types of crafting recipes:\ +\ +• Shaped (image 2): Items need to be placed in a particular shape\ +• Shapeless (images 3 and 4): Items need to be placed somewhere in input (both images show the same recipe)\ +• Cooking: Explained in “Basics > Cookingâ€\ +• Repairing (image 5): Place two damaged tools into the crafting grid anywhere to get a tool which is repaired by a certain percentage. This recipe may not be available in all subgames").."\n\n".. + +S("In some crafting recipes, some input items do not need to be a concrete item, instead they need to be a member of a group (see “Basics > Groupsâ€). These recipes offer a bit more freedom in the input items. Images 6-8 show the same group-based recipe. Here, 8 items of the “stone†group are required, which is true for all of the shown items.").."\n\n".. + +S("Rarely, crafting recipes have replacements. This means, whenever you perform a craft, some items in the crafting grid will not be consumed, but instead will be replaced by another item."), + images = { + {image="doc_basics_craft_grid.png"}, {image="doc_basics_craft_shaped.png"}, + {image="doc_basics_craft_shapeless_1.png"}, {image="doc_basics_craft_shapeless_2.png"}, {image="doc_basics_craft_repair.png"}, + {image="doc_basics_craft_groups_1.png"}, {image="doc_basics_craft_groups_2.png"}, {image="doc_basics_craft_groups_3.png"}, + }, +}}) + +doc.add_entry("basics", "cook", { + name = S("Cooking"), + data = { + text = +S("Cooking (or smelting) is a form of crafting which does not involve a crafting grid. Cooking is done with a special block (like a furnace), an cookable item, a fuel item and time in order to yield a new item.").."\n\n".. + +S("Each fuel item has a burning time. This is the time a single item of the fuel keeps a furnace burning.").."\n\n".. + +S("Each cookable item requires time to be cooked. This time is specific to the item type and the item must be “on fire†for the whole cooking time to actually yield the result.") +}}) + +doc.add_entry("basics", "hotbar", { + name = S("Hotbar"), + data = { + text = +S("At the bottom of the screen you see some squares. This is called the “hotbarâ€. The hotbar allows you to quickly access the first items from your player inventory.").."\n".. +S("You can change the selected item with the mouse wheel or the number keys.").."\n\n".. + +S("• Select previous item in hotbar: [Mouse wheel up]").."\n".. +S("• Select next item in hotbar: [Mouse wheel down]").."\n".. +S("• Select item in hotbar directly: [0]-[9]").."\n\n".. + +S("The selected item is also your wielded item."), + images = {{image="doc_basics_hotbar.png"}, {image="doc_basics_hotbar_relations.png"}}, +}}) + +doc.add_entry("basics", "minimap", { + name = S("Minimap"), + data = { + text = +S("Press [F9] to make a minimap appear on the top right. The minimap helps you to find your way around the world. Press it again to select different minimap modes and zoom levels. The minimap also shows the positions of other players.").."\n\n".. + +S("There are 2 minimap modes and 3 zoom levels.").."\n\n".. + +S("Surface mode (image 1) is a top-down view of the world, roughly resembling the colors of the blocks this world is made of. It only shows the topmost blocks, everything below is hidden, like a satellite photo. Surface mode is useful if you got lost.").."\n\n".. + +S("Radar mode (image 2) is more complicated. It displays the “denseness†of the area around you and changes with your height. Roughly, the more green an area is, the less “dense†it is. Black areas have many blocks. Use the radar to find caverns, hidden areas, walls and more. The rectangular shapes in image 2 clearly expose the position of a dungeon.").."\n\n".. + +S("There are also two different rotation modes. In “square modeâ€, the rotation of the minimap is fixed. If you press [Shift]+[F9] to switch to “circle modeâ€, the minimap will instead rotate with your looking direction, so “up†is always your looking direction.").."\n\n".. + +S("In some subgames, the minimap may be disabled.").."\n\n".. + +S("• Toggle minimap mode: [F9]").."\n".. +S("• Toggle minimap rotation mode: [Shift]+[F9]"), + images = {{image="doc_basics_minimap_map.png"}, {image="doc_basics_minimap_radar.png"}, {image="doc_basics_minimap_round.png"}}, +}}) + +doc.add_entry("basics", "inventory", { + name="Inventory", + data = { + text = +S("Inventories are used to store item stacks. There are other uses, such as crafting. An inventory consists of a rectangular grid of item slots. Each item slot can either be empty or hold one item stack. Item stacks can be moved freely between most slots.").."\n".. +S("You have your own inventory which is called your “player inventoryâ€, you can open it with the inventory key (default: [I]). The first inventory slots are also used as slots in your hotbar.").."\n".. +S("Blocks can also have their own inventory, e.g. chests and furnaces.").."\n\n".. + +S("Inventory controls:").."\n\n".. + +S("Taking: You can take items from an occupied slot if the cursor holds nothing.").."\n".. +S("• Left click: take entire item stack").."\n".. +S("• Right click: take half from the item stack (rounded up)").."\n".. +S("• Middle click: take 10 items from the item stack").."\n\n".. + +S("Putting: You can put items onto a slot if the cursor holds 1 or more items and the slot is either empty or contains an item stack of the same item type.").."\n".. +S("• Left click: put entire item stack").."\n".. +S("• Right click: put 1 item of the item stack").."\n".. +S("• Middle click: put 10 items of the item stack").."\n\n".. + +S("Exchanging: You can exchange items if the cursor holds 1 or more items and the destination slot is occupied by a different item type.").."\n".. +S("• Click: exchange item stacks").."\n\n".. + +S("Throwing away: If you hold an item stack and click with it somewhere outside the menu, the item stack gets thrown away into the environment.").."\n\n".. + +S("Quick transfer: You can quickly transfer an item stack to/from the player inventory to/from another item's inventory slot like a furnace, chest, or any other item with an inventory slot when that item's inventory is accessed. The target inventory is generally the most relevant inventory in this context.").."\n".. +S("• Sneak+Left click: Automatically transfer item stack"), + images = {{image="doc_basics_inventory.png"}} +}}) + +doc.add_entry("advanced", "online", { + name = S("Online help"), + data = { text= +S("You may want to check out these online resources related to Minetest:").."\n\n".. + +S("Official homepage of Minetest: ").."\n".. +S("The main place to find the most recent version of Minetest.").."\n\n".. + +S("Community wiki: ").."\n".. +S("A community-based documentation website for Minetest. Anyone with an account can edit it! It also features a documentation of Minetest Game.").."\n\n".. + +S("Web forums: ").."\n".. +S("A web-based discussion platform where you can discuss everything related to Minetest. This is also a place where player-made mods and subgames are published and discussed. The discussions are mainly in English, but there is also space for discussion in other languages.").."\n\n".. + +S("Chat: ").."\n".. +S("A generic Internet Relay Chat channel for everything related to Minetest where people can meet to discuss in real-time. If you do not understand IRC, see the Community Wiki for help.") +}}) + +doc.add_entry("basics", "groups", { + name = S("Groups"), + data = { + text = +S("Items, players and objects (animate and inanimate) can be members of any number of groups. Groups serve multiple purposes:").."\n\n".. + +S("• Crafting recipes: Slots in a crafting recipe may not require a specific item, but instead an item which is a member of a particular group, or multiple groups").."\n".. +S("• Digging times: Diggable blocks belong to groups which are used to determine digging times. Mining tools are capable of digging blocks belonging to certain groups").."\n".. +S("• Block behavior: Blocks may show a special behaviour and interact with other blocks when they belong to a particular group").."\n".. +S("• Damage and armor: Objects and players have armor groups, weapons have damage groups. These groups determine damage. See also: “Basics > Weaponsâ€").."\n".. +S("• Other uses").."\n\n".. + +S("In the item help, many important groups are usually mentioned and explained.") +}}) + +doc.add_entry("basics", "glossary", { + name = S("Glossary"), + data = { + text = +S("This is a list of commonly used terms in Minetest:").."\n\n".. + +S("Controls:").."\n".. +S("• Wielding: Holding an item in hand").."\n".. +S("• Pointing: Looking with the crosshair at something in range").."\n".. +S("• Dropping: Throwing an item or item stack to the ground").."\n".. +S("• Punching: Attacking with left-click, is also used on blocks").."\n".. +S("• Sneaking: Walking slowly while (usually) avoiding to fall over edges").."\n".. +S("• Climbing: Moving up or down a climbable block").."\n\n".. + +S("Blocks:").."\n".. +S("• Block: Cubes that the worlds are made of").."\n".. +S("• Mining/digging: Using a mining tool to break a block").."\n".. +S("• Building/placing: Putting a block somewhere").."\n".. +S("• Drop: Items you get after mining a block").."\n".. +S("• Using a block: Right-clicking a block to access its special function").."\n\n".. + +S("Items:").."\n".. +S("• Item: A single thing that players can possess").."\n".. +S("• Item stack: A collection of items of the same kind").."\n".. +S("• Maximum stack size: Maximum amount of items in an item stack").."\n".. +S("• Slot / inventory slot: Can hold one item stack").."\n".. +S("• Inventory: Provides several inventory slots for storage").."\n".. +S("• Player inventory: The main inventory of a player").."\n".. +S("• Tool: An item which you can use to do special things with when wielding").."\n".. +S("• Range: How far away things can be to be pointed by an item").."\n".. +S("• Mining tool: A tool which allows to break blocks").."\n".. +S("• Craftitem: An item which is (primarily or only) used for crafting").."\n\n".. + +S("Gameplay:").."\n".. +S("• “heartâ€: A single health symbol, indicates 2 HP").."\n".. +S("• “bubbleâ€: A single breath symbol, indicates 1 BP").."\n".. +S("• HP: Hit point (equals half 1 “heartâ€)").."\n".. +S("• BP: Breath point, indicates breath when diving").."\n".. +S("• Mob: Computer-controlled enemy").."\n".. +S("• Crafting: Combining multiple items to create new ones").."\n".. +S("• Crafting guide: A helper which shows available crafting recipes").."\n".. +S("• Spawning: Appearing in the world").."\n".. +S("• Respawning: Appearing again in the world after death").."\n".. +S("• Group: Puts similar things together, often affects gameplay").."\n".. +S("• noclip: Allows to fly through walls").."\n\n".. + +S("Interface").."\n".. +S("• Hotbar: Inventory slots at the bottom").."\n".. +S("• Statbar: Indicator made out of half-symbols, used for health and breath").."\n".. +S("• Minimap: The map or radar at the top right").."\n".. +S("• Crosshair: Seen in the middle, used to point at things").."\n\n".. + +S("Online multiplayer:").."\n".. +S("• PvP: Player vs Player. If active, players can deal damage to each other").."\n".. +S("• Griefing: Destroying the buildings of other players against their will").."\n".. +S("• Protection: Mechanism to own areas of the world, which only allows the owners to modify blocks inside").."\n\n".. + +S("Technical terms:").."\n".. +S("• Minetest: This game engine").."\n".. +S("• Minetest Game: A subgame for Minetest by the Minetest developers").."\n".. +S("• Subgame: A complete playing experience to be used in Minetest; such as a game or sandbox or similar").."\n".. +S("• Mod: A single subsystem which adds or modifies functionality; is the basic building block of subgames and can be used to further enhance or modify them").."\n".. +S("• Privilege: Allows a player to do something").."\n".. +S("• Node: Other word for “blockâ€") +}}) + +doc.add_entry("advanced", "settings", { + name = S("Settings"), + data = { + text = +S("There is a large variety of settings to configure Minetest. Pretty much every aspect can be changed that way.").."\n\n".. + +S("These are a few of the most important gameplay settings:").."\n\n".. + +S("• Damage enabled (enable_damage): Enables the health and breath attributes for all players. If disabled, players are immortal").."\n".. +S("• Creative Mode (creative_mode): Enables sandbox-style gameplay focusing on creativity rather than a challenging gameplay. The meaning depends on the subgame; usual changes are: Reduced dig times, easy access to almost all items, tools never wear off, etc.").."\n".. +S("• PvP (enable_pvp): Short for “Player vs Playerâ€. If enabled, players can deal damage to each other").."\n\n".. + +S("For a full list of all available settings, use the “Advanced settings†dialog in the main menu.") +}}) + +doc.add_entry("advanced", "movement_modes", { + name = S("Movement modes"), + data = { text = +S("If you have the required privileges, you can use up to three special movement modes. Using these may be considered cheating.").."\n\n".. + +S("Fast mode:").."\n".. +S("• Description: Allows you to move much faster. Hold down the the “Use†key [E] to move faster. In the client configuration, you can further customize fast mode.").."\n".. +S("• Default key: [J]").."\n".. +S("• Required privilege: fast").."\n\n".. + +S("Fly mode:").."\n".. +S("• Description: Gravity doesn't affect you and you can move freely in all directions. Use the jump key to rise and the sneak key to sink.").."\n".. +S("• Default key: [K]").."\n".. +S("• Required privilege: fly").."\n\n".. + +S("Noclip mode:").."\n".. +S("• Description: Allows you to move through walls. Only works when fly mode is enabled, too.").."\n".. +S("• Default key: [H]").."\n".. +S("• Required privilege: noclip") +}}) + +doc.add_entry("advanced", "console", { + name = S("Console"), + data = { text = +S("With [F10] you can open and close the console. The main use of the console is to show the chat log and enter chat messages or server commands.").."\n".. +S("Using the chat or server command key also opens the console, but it is smaller and will be closed after you sent a message.").."\n\n".. + +S("Use the chat to communicate with other players. This requires you to have the “shout†privilege.").."\n".. +S("Just type in the message and hit [Enter]. Public chat messages can not begin with “/â€.").."\n\n".. + +S("You can send private messages: Say “/msg †in chat to send Ҡwhich can only be seen by .").."\n\n".. + +S("There are some special controls for the console:").."\n\n".. + +S("• [F10] Open/close console").."\n".. +S("• [Enter]: Send message or command").."\n".. +S("• [Tab]: Try to auto-complete a partially-entered player name").."\n".. +S("• [Ctrl]+[Left]: Move cursor to the beginning of the previous word").."\n".. +S("• [Ctrl]+[Right]: Move cursor to the beginning of the next word").."\n".. +S("• [Ctrl]+[Backspace]: Delete previous word").."\n".. +S("• [Ctrl]+[Delete]: Delete next word").."\n".. +S("• [Ctrl]+[U]: Delete all text before the cursor").."\n".. +S("• [Ctrl]+[K]: Delete all text after the cursor").."\n".. +S("• [Page up]: Scroll up").."\n".. +S("• [Page down]: Scroll down").."\n".. + +S("There is also an input history. Minetest saves your previous console inputs which you can quickly access later:").."\n\n".. + +S("• [Up]: Go to previous entry in history").."\n".. +S("• [Down]: Go to next entry in history") +}}) + +doc.add_entry("advanced", "commands", { + name = S("Server commands"), + data = { text = +S("Server commands (also called “chat commandsâ€) are little helpers for advanced users. You don't need to use these commands when playing. But they might come in handy to perform some more technical tasks. Server commands work both in multi-player and single-player mode.").."\n\n".. + +S("Server commands can be entered by players using the chat to perform a special server action. There are a few commands which can be issued by everyone, but some commands only work if you have certain privileges granted on the server. There is a small set of basic commands which are always available, other commands can be added by mods.").."\n\n".. + +S("To issue a command, simply type it like a chat message or press Minetest's command key (default: [/]). All commands have to begin with “/â€, for example “/modsâ€. The Minetest command key does the same as the chat key, except that the slash is already entered.").."\n".. +S("Commands may or may not give a response in the chat log, but errors will generally be shown in the chat. Try it for yourselves: Close this window and type in the “/mods†command. This will give you the list of available mods on this server.").."\n\n".. + +S("“/help all†is a very important command: You get a list of all available commands on the server, a short explanation and the allowed parameters. This command is also important because the available commands often differ per server.").."\n\n".. + +S("Commands are followed by zero or more parameters.").."\n\n".. + +S("In the command reference, you see some placeholders which you need to replace with an actual value. Here's an explanation:").."\n\n".. + +S("• Text in greater-than and lower-than signs (e.g. “â€): Placeholder for a parameter").."\n".. +S("• Anything in square brackets (e.g. “[text]â€) is optional and can be omitted").."\n".. +S("• Pipe or slash (e.g. “text1 | text2 | text3â€): Alternation. One of multiple texts must be used (e.g. “text2â€)").."\n".. +S("• Parenthesis: (e.g. “(word1 word2) | word3â€): Groups multiple words together, used for alternations").."\n".. +S("• Everything else is to be read as literal text").."\n\n".. + +S("Here are some examples to illustrate the command syntax:").."\n\n".. + +S("• /mods: No parameters. Just enter “/modsâ€").."\n".. +S("• /me : 1 parameter. You have to enter “/me †followed by any text, e.g. “/me orders pizzaâ€").."\n".. +S("• /give : Two parameters. Example: “/give Player default:appleâ€").."\n".. +S("• /help [all|privs|]: Valid inputs are “/helpâ€, “/help allâ€, “/help privsâ€, or “/help †followed by a command name, like “/help timeâ€").."\n".. +S("• /spawnentity [,,]: Valid inputs include “/spawnentity boats:boat†and “/spawnentity boats:boat 0,0,0â€").."\n\n\n".. + + + +S("Some final remarks:").."\n\n".. + +S("• For /give and /giveme, you need an itemstring. This is an internally used unique item identifier which you may find in the item help if you have the “give†or “debug†privilege").."\n".. +S("• For /spawnentity you need an entity name, which is another identifier") +}}) + +doc.add_entry("advanced", "privs", { + name = S("Privileges"), + data = { text = +S("Each player has a set of privileges, which differs from server to server. Your privileges determine what you can and can't do. Privileges can be granted and revoked from other players by any player who has the privilege called “privsâ€.").."\n\n".. + +S("On a multiplayer server with the default configuration, new players start with the privileges called “interact†and “shoutâ€. The “interact†privilege is required for the most basic gameplay actions such as building, mining, using, etc. The “shout†privilege allows to chat.").."\n\n".. + +S("There is a small set of core privileges which you'll find on every server, other privileges might be added by mods.").."\n\n".. + +S("To view your own privileges, issue the server command “/privsâ€.").."\n\n".. + +S("Here are a few basic privilege-related commands:").."\n\n".. + +S("• /privs: Lists your privileges").."\n".. +S("• /privs : Lists the privileges of ").."\n".. +S("• /help privs: Shows a list and description about all privileges").."\n\n".. + +S("Players with the “privs†privilege can modify privileges at will:").."\n\n".. + +S("• /grant : Grant to ").."\n".. +S("• /revoke : Revoke from ").."\n\n".. + +S("In single-player mode, you can use “/grant singleplayer all†to unlock all abilities (which is often considered cheating).") +}}) + +doc.add_entry("basics", "light", { + name = S("Light"), + data = { text = +S("As the world is entirely block-based, so is the light in the world. Each block has its own brightness. The brightness of a block is expressed in a “light level†which ranges from 0 (total darkness) to 15 (as bright as the sun).").."\n\n".. + +S("There are two types of light: Sunlight and artificial light.").."\n\n".. + +S("Artificial light is emitted by luminous blocks. Artificial light has a light level from 1-14.").."\n".. +S("Sunlight is the brightest light and always goes perfectly straight down from the sky at each time of the day. blocks. At night, the sunlight will become moonlight instead, which still provides a small amount of light. The light level of sunlight is 15.").."\n\n".. + +S("Blocks have 3 levels of transparency:").."\n\n".. + +S("• Transparent: Sunlight goes through limitless, artificial light goes through with losses").."\n".. +S("• Semi-transparent: Sunlight and artificial light go through with losses").."\n".. +S("• Opaque: No light passes through").."\n\n".. + +S("Artificial light will lose one level of brightness for each transparent or semi-transparent block it passes through, until only darkness remains (image 1).").."\n".. +S("Sunlight will preserve its brightness as long it only passes fully transparent blocks. When it passes through a semi-transparent block, it turns to artificial light. Image 2 shows the difference.").."\n\n".. + +S("Note that “transparency†here only means that the block is able to carry brightness from its neighboring blocks. It is possible for a block to be transparent to light but you can't see trough the other side."), + images = {{image="doc_basics_light_torch.png"}, {image="doc_basics_light_test.png"}} +}}) + +doc.add_entry("advanced", "coordinates", { + name = S("Coordinates"), + data = { text = +S("The Minetest world is a large cube. And because of this, a position in the world can be easily expressed with Cartesian coordinates. That is, for each position in the world, there are 3 values X, Y and Z.").."\n\n".. + +S("Like this: (5, 45, -12)").."\n\n".. + +S("This refers to the position where X=5, Y=45 and Z=-12. The 3 letters are called “axesâ€: Y is for the height. X and Z are for the horizontal position.").."\n\n".. + +S("The values for X, Y and Z work like this:").."\n\n".. + +S("• If you go up, Y increases").."\n".. +S("• If you go down, Y decreases").."\n".. +S("• If you follow the sun, X increases").."\n".. +S("• If you go to the reverse direction, X decreases").."\n".. +S("• Follow the sun, then go right: Z increases").."\n".. +S("• Follow the sun, then go left: Z decreases").."\n".. +S("• The side length of a full cube is 1").."\n\n".. + +S("You can view your current position in the debug screen (open with [F5]). This is considered cheating in some games.") +}}) diff --git a/mods/doc_modpack/doc_basics/mod.conf b/mods/doc_modpack/doc_basics/mod.conf new file mode 100644 index 0000000..8138f7d --- /dev/null +++ b/mods/doc_modpack/doc_basics/mod.conf @@ -0,0 +1 @@ +name = doc_basics diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_build.png b/mods/doc_modpack/doc_basics/textures/doc_basics_build.png new file mode 100644 index 0000000..f91c89e Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_build.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_camera_behind.png b/mods/doc_modpack/doc_basics/textures/doc_basics_camera_behind.png new file mode 100644 index 0000000..062afb9 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_camera_behind.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_camera_ego.png b/mods/doc_modpack/doc_basics/textures/doc_basics_camera_ego.png new file mode 100644 index 0000000..ced40c5 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_camera_ego.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_camera_front.png b/mods/doc_modpack/doc_basics/textures/doc_basics_camera_front.png new file mode 100644 index 0000000..392d96d Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_camera_front.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_craft_grid.png b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_grid.png new file mode 100644 index 0000000..3dfafec Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_grid.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_1.png b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_1.png new file mode 100644 index 0000000..eb48132 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_1.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_2.png b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_2.png new file mode 100644 index 0000000..77999ea Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_2.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_3.png b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_3.png new file mode 100644 index 0000000..89177b6 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_groups_3.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_craft_repair.png b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_repair.png new file mode 100644 index 0000000..e0f628a Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_repair.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shaped.png b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shaped.png new file mode 100644 index 0000000..27494d8 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shaped.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shapeless_1.png b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shapeless_1.png new file mode 100644 index 0000000..6ffb7a7 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shapeless_1.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shapeless_2.png b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shapeless_2.png new file mode 100644 index 0000000..9367518 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_craft_shapeless_2.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_carbone_ng.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_carbone_ng.png new file mode 100644 index 0000000..50c841d Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_carbone_ng.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_hades.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_hades.png new file mode 100644 index 0000000..0386aba Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_hades.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_lott.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_lott.png new file mode 100644 index 0000000..3303d03 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_lott.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_moontest.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_moontest.png new file mode 100644 index 0000000..9f1504a Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_moontest.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_mtg_1.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_mtg_1.png new file mode 100644 index 0000000..9e3f573 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_mtg_1.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_mtg_2.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_mtg_2.png new file mode 100644 index 0000000..4a24233 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_mtg_2.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_outback.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_outback.png new file mode 100644 index 0000000..30eff6c Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_outback.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_pixture.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_pixture.png new file mode 100644 index 0000000..8ffcb16 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_pixture.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_xtraores_xtension.png b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_xtraores_xtension.png new file mode 100644 index 0000000..e642121 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_gameplay_xtraores_xtension.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_hotbar.png b/mods/doc_modpack/doc_basics/textures/doc_basics_hotbar.png new file mode 100644 index 0000000..72f30b5 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_hotbar.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_hotbar_relations.png b/mods/doc_modpack/doc_basics/textures/doc_basics_hotbar_relations.png new file mode 100644 index 0000000..ba4a2c6 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_hotbar_relations.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_inventory.png b/mods/doc_modpack/doc_basics/textures/doc_basics_inventory.png new file mode 100644 index 0000000..c8cdc90 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_inventory.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_inventory_detail.png b/mods/doc_modpack/doc_basics/textures/doc_basics_inventory_detail.png new file mode 100644 index 0000000..9fabf96 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_inventory_detail.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_items_dropped.png b/mods/doc_modpack/doc_basics/textures/doc_basics_items_dropped.png new file mode 100644 index 0000000..09e2184 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_items_dropped.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_light_test.png b/mods/doc_modpack/doc_basics/textures/doc_basics_light_test.png new file mode 100644 index 0000000..882f603 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_light_test.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_light_torch.png b/mods/doc_modpack/doc_basics/textures/doc_basics_light_torch.png new file mode 100644 index 0000000..f98a16d Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_light_torch.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_nonrenewable.png b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_nonrenewable.png new file mode 100644 index 0000000..015f215 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_nonrenewable.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_range.png b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_range.png new file mode 100644 index 0000000..c7b08ff Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_range.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_renewable_1.png b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_renewable_1.png new file mode 100644 index 0000000..b1385b1 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_renewable_1.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_renewable_2.png b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_renewable_2.png new file mode 100644 index 0000000..abcd5fd Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_renewable_2.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_types.png b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_types.png new file mode 100644 index 0000000..e554fa7 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_liquids_types.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_map.png b/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_map.png new file mode 100644 index 0000000..506470b Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_map.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_radar.png b/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_radar.png new file mode 100644 index 0000000..5f1f0fb Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_radar.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_round.png b/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_round.png new file mode 100644 index 0000000..0986f80 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_minimap_round.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_nodes.png b/mods/doc_modpack/doc_basics/textures/doc_basics_nodes.png new file mode 100644 index 0000000..05c8404 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_nodes.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_players_flat.png b/mods/doc_modpack/doc_basics/textures/doc_basics_players_flat.png new file mode 100644 index 0000000..e85b48b Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_players_flat.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_players_lott.png b/mods/doc_modpack/doc_basics/textures/doc_basics_players_lott.png new file mode 100644 index 0000000..af7e7ac Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_players_lott.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_players_sam.png b/mods/doc_modpack/doc_basics/textures/doc_basics_players_sam.png new file mode 100644 index 0000000..3909168 Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_players_sam.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_pointing.png b/mods/doc_modpack/doc_basics/textures/doc_basics_pointing.png new file mode 100644 index 0000000..dc8adde Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_pointing.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_sneak.png b/mods/doc_modpack/doc_basics/textures/doc_basics_sneak.png new file mode 100644 index 0000000..2a747ed Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_sneak.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_tools.png b/mods/doc_modpack/doc_basics/textures/doc_basics_tools.png new file mode 100644 index 0000000..71fd6ec Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_tools.png differ diff --git a/mods/doc_modpack/doc_basics/textures/doc_basics_tools_mining.png b/mods/doc_modpack/doc_basics/textures/doc_basics_tools_mining.png new file mode 100644 index 0000000..c705e5b Binary files /dev/null and b/mods/doc_modpack/doc_basics/textures/doc_basics_tools_mining.png differ diff --git a/mods/doc_modpack/doc_encyclopedia/README.md b/mods/doc_modpack/doc_encyclopedia/README.md new file mode 100644 index 0000000..a306ca1 --- /dev/null +++ b/mods/doc_modpack/doc_encyclopedia/README.md @@ -0,0 +1,29 @@ +# Encyclopedia [`doc_encyclopedia`] +This mod adds an item to access the help (based on the +Documentation System [`doc`]. Just hold the item in hand and punch. + +Version: 1.2.0. + +## Crafting +The encyclopedia is crafted with this shaped recipe: + + SS + S S + SS + +* `S`: Any item in group “stick†+ +If you use Minetest Game (mod `default`), there's another recipe +possible: + + B + B + B + +* `B`: Book + +## Itemstring +The itemstring of this item is `doc_encyclopedia:encyclopedia`. + +## License +Everything in this mod is licensed under the MIT License. diff --git a/mods/doc_modpack/doc_encyclopedia/depends.txt b/mods/doc_modpack/doc_encyclopedia/depends.txt new file mode 100644 index 0000000..c8f3ef6 --- /dev/null +++ b/mods/doc_modpack/doc_encyclopedia/depends.txt @@ -0,0 +1,3 @@ +doc +intllib? +default? diff --git a/mods/doc_modpack/doc_encyclopedia/description.txt b/mods/doc_modpack/doc_encyclopedia/description.txt new file mode 100644 index 0000000..4227bd1 --- /dev/null +++ b/mods/doc_modpack/doc_encyclopedia/description.txt @@ -0,0 +1 @@ +Adds an encyclopedia item which allows you to access the help. diff --git a/mods/doc_modpack/doc_encyclopedia/init.lua b/mods/doc_modpack/doc_encyclopedia/init.lua new file mode 100644 index 0000000..8312b68 --- /dev/null +++ b/mods/doc_modpack/doc_encyclopedia/init.lua @@ -0,0 +1,41 @@ +local S +if minetest.get_modpath("intllib") then + S = intllib.Getter(minetest.get_current_modname()) +else + S = function(s) return s end +end + +minetest.register_craftitem("doc_encyclopedia:encyclopedia", { + description = S("Encyclopedia"), + _doc_items_longdesc = S("Allows you to access the help."), + _doc_items_usagehelp = S("Wield it, then leftclick to access the help."), + _doc_items_hidden = false, + stack_max = 1, + inventory_image = "doc_encyclopedia_encyclopedia.png", + wield_image = "doc_encyclopedia_encyclopedia.png", + wield_scale = { x=1, y=1, z=2.25 }, + on_use = function(itemstack, user) + doc.show_doc(user:get_player_name()) + end, + groups = { book=1 }, +}) + +minetest.register_craft({ + output = "doc_encyclopedia:encyclopedia 2", + recipe = { + {"doc_encyclopedia:encyclopedia", "default:book"}, + } +}) + +minetest.register_craft({ + output = "doc_encyclopedia:encyclopedia", + recipe = { + {"epic:float_crystal_shard", "default:book", "epic:bloodstone_shard"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doc_encyclopedia:encyclopedia", + burntime = 6, +}) diff --git a/mods/doc_modpack/doc_encyclopedia/locale/de.txt b/mods/doc_modpack/doc_encyclopedia/locale/de.txt new file mode 100644 index 0000000..aaef350 --- /dev/null +++ b/mods/doc_modpack/doc_encyclopedia/locale/de.txt @@ -0,0 +1,3 @@ +Encyclopedia = Enzyklopädie +Allows you to access the help. = Damit kann man auf die Hilfe zuzugreifen. +Wield it, then leftclick to access the help. = Halten Sie sie in der Hand und linksklicken Sie, um auf die Hilfe zuzugreifen. diff --git a/mods/doc_modpack/doc_encyclopedia/locale/template.txt b/mods/doc_modpack/doc_encyclopedia/locale/template.txt new file mode 100644 index 0000000..1cbd581 --- /dev/null +++ b/mods/doc_modpack/doc_encyclopedia/locale/template.txt @@ -0,0 +1,3 @@ +Encyclopedia = +Allows you to access the help. = +Wield it, then leftclick to access the help. = diff --git a/mods/doc_modpack/doc_encyclopedia/mod.conf b/mods/doc_modpack/doc_encyclopedia/mod.conf new file mode 100644 index 0000000..318d238 --- /dev/null +++ b/mods/doc_modpack/doc_encyclopedia/mod.conf @@ -0,0 +1 @@ +name = doc_encyclopedia diff --git a/mods/doc_modpack/doc_encyclopedia/textures/doc_encyclopedia_encyclopedia.png b/mods/doc_modpack/doc_encyclopedia/textures/doc_encyclopedia_encyclopedia.png new file mode 100644 index 0000000..2d5014b Binary files /dev/null and b/mods/doc_modpack/doc_encyclopedia/textures/doc_encyclopedia_encyclopedia.png differ diff --git a/mods/doc_modpack/doc_identifier/API.md b/mods/doc_modpack/doc_identifier/API.md new file mode 100644 index 0000000..fb7f88c --- /dev/null +++ b/mods/doc_modpack/doc_identifier/API.md @@ -0,0 +1,40 @@ +# Minimal API for `doc_identifier` +## Introduction +The tool can identify blocks and players natively, and also handles falling +nodes (`__builtin:falling_node`) and dropped items (`__builtin:item`) on its +own. + +However, the identifier can't “identify†(=open the appropriate entry) custom +objects because the mod doesn't know which help entry to open (if there is +any). One example would be the boat object (`boats:boat`) from the boats mod +in Minetest Game. +If the player tries to use the tool on an unknown object, an error message is +shown. + +Because of this, this mod provides a minimal API for mods to assign a help +entry to an object type: `doc_identifier.register_object`. + +## `doc.sub.identifier.register_object(object_name, category_id, entry_id)` +Registers the object/entity with the internal name `object_name` to the +entry `entry_id` in the category `category_id`. +It is in the modder's responsibility to make sure that both the category and +entry already exist (use `doc.entry_exists` or depend (optionally or not) on +the respective mods) at the time of the function call, otherwise, stability can +not be guaranteed. + +Returns `nil`. + +### Example +From `doc_minetest_game`: + + if minetest.get_modpath("doc_identifier") ~= nil then + doc.sub.identifier.register_object("boats:boat", "craftitems", "boats:boat") + end + +This enables the tool to be used on the boat object itself. The conditional is +an idiom to check for the existence of this mod. + +## Note on dependencies +If you just need `doc.sub.identifier.register_object` using only an **optional** +dependency for your mod is probably enough. + diff --git a/mods/doc_modpack/doc_identifier/README.md b/mods/doc_modpack/doc_identifier/README.md new file mode 100644 index 0000000..1bf3234 --- /dev/null +++ b/mods/doc_modpack/doc_identifier/README.md @@ -0,0 +1,29 @@ +# Lookup Tool [`doc_identifier`] +Version: 1.2.0 + +## Description +The lookup tool is an useful little helper which can be used to quickly learn +more about about one's closer environment. It identifies blocks, dropped items +and other objects and it shows extensive information about the item on which it +is used, provided documentation is available. + +## How to use the lookup tool +Punch any block or item about you wish to learn more about. This will open up +the help entry of this particular item. +The tool comes in two modes which are changed by a right-click. In liquid mode +(blue) this tool points to liquids as well while in solid mode (red) this is not +the case. Liquid mode is required if you want to identify a liquid. + +## For modders +If you want the tool to identify nodes and (dropped) items, you probably don't +have to do anything, it is probably already supported. The only thing you have +to make sure is that all pointable blocks and items have a help entry, which +is already the case for most items, but you may want to do some testing on +“tricky†items. Consult the documentation of Documentation System [`doc`] +and Item Help [`doc_items`] for getting the item documentation right. + +For the lookup tool to be able to work on custom objects/entities, you have to +use the tiny API of this mod, see `API.md`. + +## License +Everything in this mod is licensed under the MIT License. diff --git a/mods/doc_modpack/doc_identifier/depends.txt b/mods/doc_modpack/doc_identifier/depends.txt new file mode 100644 index 0000000..b5ad06b --- /dev/null +++ b/mods/doc_modpack/doc_identifier/depends.txt @@ -0,0 +1,5 @@ +doc +doc_items +doc_basics? +default? +intllib? diff --git a/mods/doc_modpack/doc_identifier/description.txt b/mods/doc_modpack/doc_identifier/description.txt new file mode 100644 index 0000000..8294c74 --- /dev/null +++ b/mods/doc_modpack/doc_identifier/description.txt @@ -0,0 +1 @@ +Adds a tool which shows help entries about almost anything which it punches. diff --git a/mods/doc_modpack/doc_identifier/init.lua b/mods/doc_modpack/doc_identifier/init.lua new file mode 100644 index 0000000..455a9f1 --- /dev/null +++ b/mods/doc_modpack/doc_identifier/init.lua @@ -0,0 +1,190 @@ +-- Boilerplate to support localized strings if intllib mod is installed. +local S +if minetest.get_modpath("intllib") then + S = intllib.Getter() +else + S = function(s) return s end +end + +local doc_identifier = {} + +doc_identifier.registered_objects = {} + +-- API +doc.sub.identifier = {} +doc.sub.identifier.register_object = function(object_name, category_id, entry_id) + doc_identifier.registered_objects[object_name] = { category = category_id, entry = entry_id } +end + +-- END OF API + +doc_identifier.identify = function(itemstack, user, pointed_thing) + local username = user:get_player_name() + local show_message = function(username, itype, param) + local vsize = 2 + local message + if itype == "error_item" then + message = S("No help entry for this item could be found.") + elseif itype == "error_node" then + message = S("No help entry for this block could be found.") + elseif itype == "error_unknown" then + vsize = vsize + 3 + local mod + if param ~= nil then + local colon = string.find(param, ":") + if colon ~= nil and colon > 1 then + mod = string.sub(param,1,colon-1) + end + end + message = S("Error: This node, item or object is undefined. This is always an error.\nThis can happen for the following reasons:\n• The mod which is required for it is not enabled\n• The author of the subgame or a mod has made a mistake") + message = message .. "\n\n" + + if mod ~= nil then + if minetest.get_modpath(mod) ~= nil then + message = message .. string.format(S("It appears to originate from the mod “%sâ€, which is enabled."), mod) + message = message .. "\n" + else + message = message .. string.format(S("It appears to originate from the mod “%sâ€, which is not enabled!"), mod) + message = message .. "\n" + end + end + if param ~= nil then + message = message .. string.format(S("Its identifier is “%sâ€."), param) + end + elseif itype == "error_ignore" then + message = S("This block cannot be identified because the world has not materialized at this point yet. Try again in a few seconds.") + elseif itype == "error_object" or itype == "error_unknown_thing" then + message = S("No help entry for this object could be found.") + elseif itype == "player" then + message = S("This is a player.") + end + minetest.show_formspec( + username, + "doc_identifier:error_missing_item_info", + "size[12,"..vsize..";]" .. + "label[0,0.2;"..minetest.formspec_escape(message).."]" .. + "button_exit[4.5,"..(-0.5+vsize)..";3,1;okay;"..minetest.formspec_escape(S("OK")).."]" + ) + end + if pointed_thing.type == "node" then + local pos = pointed_thing.under + local node = minetest.get_node(pos) + if minetest.registered_nodes[node.name] ~= nil then + local nodedef = minetest.registered_nodes[node.name] + if(node.name == "ignore") then + show_message(username, "error_ignore") + elseif doc.entry_exists("nodes", node.name) then + doc.show_entry(username, "nodes", node.name, true) + else + show_message(username, "error_node") + end + else + show_message(username, "error_unknown", node.name) + end + elseif pointed_thing.type == "object" then + local object = pointed_thing.ref + local le = object:get_luaentity() + if object:is_player() then + if minetest.get_modpath("doc_basics") ~= nil and doc.entry_exists("basics", "players") then + doc.show_entry(username, "basics", "players", true) + else + -- Fallback message + show_message(username, "player") + end + -- luaentity exists + elseif le ~= nil then + local ro = doc_identifier.registered_objects[le.name] + -- Dropped items + if le.name == "__builtin:item" then + local itemstring = ItemStack(minetest.deserialize(le:get_staticdata()).itemstring):get_name() + if doc.entry_exists("nodes", itemstring) then + doc.show_entry(username, "nodes", itemstring, true) + elseif doc.entry_exists("tools", itemstring) then + doc.show_entry(username, "tools", itemstring, true) + elseif doc.entry_exists("craftitems", itemstring) then + doc.show_entry(username, "craftitems", itemstring, true) + elseif minetest.registered_items[itemstring] == nil or itemstring == "unknown" then + show_message(username, "error_unknown", itemstring) + else + show_message(username, "error_item") + end + -- Falling nodes + elseif le.name == "__builtin:falling_node" then + local itemstring = minetest.deserialize(le:get_staticdata()).name + if doc.entry_exists("nodes", itemstring) then + doc.show_entry(username, "nodes", itemstring, true) + end + -- A known registered object + elseif ro ~= nil then + doc.show_entry(username, ro.category, ro.entry, true) + -- Undefined object (error) + elseif minetest.registered_entities[le.name] == nil then + show_message(username, "error_unknown", le.name) + -- Other object (undocumented) + else + show_message(username, "error_object") + end + else + --show_message(username, "error_object") + show_message(username, "error_unknown") + end + elseif pointed_thing.type ~= "nothing" then + show_message(username, "error_unknown_thing") + end + return itemstack +end + +function doc_identifier.solid_mode(itemstack, user, pointed_thing) + return ItemStack("doc_identifier:identifier_solid") +end + +function doc_identifier.liquid_mode(itemstack, user, pointed_thing) + return ItemStack("doc_identifier:identifier_liquid") +end + +minetest.register_tool("doc_identifier:identifier_solid", { + description = S("Lookup tool"), + _doc_items_longdesc = S("This useful little helper can be used to quickly learn more about about one's closer environment. It identifies and analyzes blocks, items and other things and it shows extensive information about the thing on which it is used."), + _doc_items_usagehelp = S("Punch any block, item or other thing about you wish to learn more about. This will open up the appropriate help entry. The tool comes in two modes which are changed by a rightclick. In liquid mode (blue) this tool points to liquids as well while in solid mode (red) this is not the case. Liquid mode is required if you want to identify a liquid."), + _doc_items_hidden = false, + tool_capabilities = {}, + range = 10, + wield_image = "doc_identifier_identifier.png", + inventory_image = "doc_identifier_identifier.png", + liquids_pointable = false, + on_use = doc_identifier.identify, + on_place = doc_identifier.liquid_mode, + on_secondary_use = doc_identifier.liquid_mode, +}) +minetest.register_tool("doc_identifier:identifier_liquid", { + description = S("Lookup tool"), + _doc_items_create_entry = false, + tool_capabilities = {}, + range = 10, + groups = { not_in_creative_inventory = 1, }, + wield_image = "doc_identifier_identifier_liquid.png", + inventory_image = "doc_identifier_identifier_liquid.png", + liquids_pointable = true, + on_use = doc_identifier.identify, + on_place = doc_identifier.solid_mode, + on_secondary_use = doc_identifier.solid_mode, +}) +--[[ +minetest.register_craft({ + output = "doc_identifier:identifier_solid", + recipe = { {"group:stick", "group:stick" }, + {"", "group:stick"}, + {"group:stick", ""} } +}) + +if minetest.get_modpath("default") ~= nil then + minetest.register_craft({ + output = "doc_identifier:identifier_solid", + recipe = { { "default:glass" }, + { "group:stick" } } + }) +end +--]] +minetest.register_alias("doc_identifier:identifier", "doc_identifier:identifier_solid") + +doc.add_entry_alias("tools", "doc_identifier:identifier_solid", "tools", "doc_identifier:identifier_liquid") diff --git a/mods/doc_modpack/doc_identifier/locale/de.txt b/mods/doc_modpack/doc_identifier/locale/de.txt new file mode 100644 index 0000000..996c369 --- /dev/null +++ b/mods/doc_modpack/doc_identifier/locale/de.txt @@ -0,0 +1,13 @@ +Error: This node, item or object is undefined. This is always an error.\nThis can happen for the following reasons:\n• The mod which is required for it is not enabled\n• The author of the subgame or a mod has made a mistake = Fehler: Dieser Node, Gegenstand oder dieses Objekt ist nicht definiert.\nDas ist immer ein Fehler.\nDies kann aus folgenden Gründen passieren:\n• Die Mod, die dafür benötigt wird, ist nicht aktiv\n• Der Subgame-Autor oder ein Mod-Autor machte einen Fehler +It appears to originate from the mod “%sâ€, which is enabled. = Es scheint von der Mod »%s« zu stammen. Sie ist aktiv. +It appears to originate from the mod “%sâ€, which is not enabled! = Es scheint von der Mod »%s« zu stammen. Sie ist nicht aktiv! +Its identifier is “%sâ€. = Der Identifkator ist »%s«. +Lookup tool = Nachschlagewerkzeug +No help entry for this block could be found. = Für diesen Block konnte kein Hilfseintrag gefunden werden. +No help entry for this item could be found. = Für diesen Gegenstand konnte kein Hilfseintrag gefunden werden. +No help entry for this object could be found. = Für dieses Objekt konnte kein Hilfseintrag gefunden werden. +OK = OK +Punch any block, item or other thing about you wish to learn more about. This will open up the appropriate help entry. The tool comes in two modes which are changed by a rightclick. In liquid mode (blue) this tool points to liquids as well while in solid mode (red) this is not the case. Liquid mode is required if you want to identify a liquid. = Schlagen Sie einen beliebigen Block, Gegenstand oder irgendwas, worüber Sie mehr erfahren wollen. Das wird den passenden Hilfseintrag öffnen. Das Werkzeug hat zwei Modi, welcher mit einem Rechtsklick gewechselt werden kann. Im Flüssigmodus (blau) zeigt das Werkzeug auch auf Flüssigkeiten. Im Festmodus (rot) ist das nicht der Fall. Der Flüssigmodis ist notwendig, wenn Sie eine Flüssigkeit identifizieren wollen. +This block cannot be identified because the world has not materialized at this point yet. Try again in a few seconds. = Dieser Block kann nicht identifiziert werden, weil sich die Welt an dieser Stelle noch nicht materialisiert hat. Versuch es in ein paar Sekunden erneut. +This is a player. = Dies ist ein Spieler. +This useful little helper can be used to quickly learn more about about one's closer environment. It identifies and analyzes blocks, items and other things and it shows extensive information about the thing on which it is used. = Dieser nützliche kleine Helfer kann benutzt werden, um schnell etwas über die nähere Umgebung zu erfahren. Er identifiziert und analysiert Blöcke, Gegenstände und andere Dinge und zeigt ausführliche Informationen über all das, worauf man ihn anwendet. diff --git a/mods/doc_modpack/doc_identifier/locale/template.txt b/mods/doc_modpack/doc_identifier/locale/template.txt new file mode 100644 index 0000000..b0ede61 --- /dev/null +++ b/mods/doc_modpack/doc_identifier/locale/template.txt @@ -0,0 +1,13 @@ +Error: This node, item or object is undefined. This is always an error.\\nThis can happen for the following reasons:\\n• The mod which is required for it is not enabled\\n• The author of the subgame or a mod has made a mistake = +It appears to originate from the mod “%sâ€, which is enabled. = +It appears to originate from the mod “%sâ€, which is not enabled! = +Its identifier is “%sâ€. = +Lookup tool = +No help entry for this block could be found. = +No help entry for this item could be found. = +No help entry for this object could be found. = +OK = +Punch any block, item or other thing about you wish to learn more about. This will open up the appropriate help entry. The tool comes in two modes which are changed by a rightclick. In liquid mode (blue) this tool points to liquids as well while in solid mode (red) this is not the case. Liquid mode is required if you want to identify a liquid. = +This block cannot be identified because the world has not materialized at this point yet. Try again in a few seconds. = +This is a player. = +This useful little helper can be used to quickly learn more about about one's closer environment. It identifies and analyzes blocks, items and other things and it shows extensive information about the thing on which it is used. = diff --git a/mods/doc_modpack/doc_identifier/mod.conf b/mods/doc_modpack/doc_identifier/mod.conf new file mode 100644 index 0000000..df963a0 --- /dev/null +++ b/mods/doc_modpack/doc_identifier/mod.conf @@ -0,0 +1 @@ +name = doc_identifier diff --git a/mods/doc_modpack/doc_identifier/textures/doc_identifier_identifier.png b/mods/doc_modpack/doc_identifier/textures/doc_identifier_identifier.png new file mode 100644 index 0000000..00b3147 Binary files /dev/null and b/mods/doc_modpack/doc_identifier/textures/doc_identifier_identifier.png differ diff --git a/mods/doc_modpack/doc_identifier/textures/doc_identifier_identifier_liquid.png b/mods/doc_modpack/doc_identifier/textures/doc_identifier_identifier_liquid.png new file mode 100644 index 0000000..9f3aef9 Binary files /dev/null and b/mods/doc_modpack/doc_identifier/textures/doc_identifier_identifier_liquid.png differ diff --git a/mods/doc_modpack/doc_items/API.md b/mods/doc_modpack/doc_items/API.md new file mode 100644 index 0000000..4724328 --- /dev/null +++ b/mods/doc_modpack/doc_items/API.md @@ -0,0 +1,318 @@ +# API documentation for `doc_items` +## Introduction +This document explains the API of `doc_items`. It contains a reference of +all functions. + +## Quick start +The most common use case for using this API requires only to set some +hand-written help texts for your items. + +The preferred way is to add the following optional fields to the +item definition when using `minetest.register_node`, etc.: + +* `_doc_items_longdesc`: Long description of this item. + Describe here what this item is, what it is for, its purpose, etc. +* `_doc_items_usagehelp`: Description of *how* this item can be used. + Only set this if needed, e.g. standard mining tools don't need this. + +Example: + + minetest.register_node("example:dice", { + description = "Dice", + _doc_items_longdesc = "A decorative dice which shows the numbers 1-6 on its sides.", + _doc_items_usagehelp = "Right-click the dice to roll it.", + tiles = { "example_dice.png" }, + is_ground_content = false, + --[[ and so on … ]] + }) + +When using this method, your mod does not need additional dependencies. + +See below for some recommendations on writing good help texts. + +If you need more customization, read ahead. ;-) + +## New item fields +This mod adds support for new fields of the item definition. They allow for +easy and quick manipulation of the item help entries. All fields are optional. + +* `_doc_items_longdesc`: Long description +* `_doc_items_usagehelp`: Usage help +* `_doc_items_image`: Entry image (default: inventory image) +* `_doc_items_hidden`: Whether entry is hidden (default: `false` for air and hand, `true` for everything else) +* `_doc_items_create_entry`: Whether to create an entry for this item (default: `true`) +* `_doc_items_entry_name`: The title of the entry. By default, this is the same as the `description` field + of the item. This field is required if the `description` is empty +* `_doc_items_durability`: This field is for describing how long a tool can be used before it breaks. Choose one data type: + * It it is a `number`: Fixed number of uses before it breaks + * If it is a `string`: Free-form text which explains how the durability works. Try to keep it short and only use it if the other types won't work + +A full explanation of these fields is provided below. + +## Concepts +This section explains the core concepts of an item help entry in-depth. + +### Factoids +Basically, a factoid is usually a single sentence telling the player a specific +fact about the item. The task of each factoid is to basically convert parts +of the item definition to useful, readable, understandable text. + +Example: It's a fact that `default:sand` has the group `falling_node=1`. +A factoid for this is basically just a simple conditional which puts the +the sentence “This block is affected to gravity and can fall.†into the +text if the node is member of said group. + +Factoids can be more complex than that. The factoid for node drops needs to +account for different drop types and probabilities, etc. + +`doc_items` has many predefined factoids already. This includes all “special†+groups (like `falling_node`), drops, mining capabilities, punch interval, +and much more. + +Custom factoids can be added with `doc.sub.items.register_factoid`. + +The idea behind factoids is to generate as much information as possible +automatically to reduce redundancy, inconsistencies and the workload of hand- +written descriptions. + +### Long description and usage help +Factoids are not always sufficient to describe an item. This is the case +for facts where the item definition can not be used to automatically +generate texts. Examples: Custom formspecs, ABMs, special tool action +on right-click. + +That's where the long description and usage help comes into play. +Those are two texts which are written manually for a specific item. + +Roughly, the long description is for describing **what** the item is, how it +acts, what it is for. The usage help is for explaining **how** the +item can be used. It is less important for standard mining tools and weapons. + +There is no hard length limit for the long description and the usage help. + +#### Recommendations for long description +The long description should roughly contain the following info: + +* What the item does +* What it is good for +* How it may be generated in the world +* Maybe some background info if you're in a funny mood +* Notable information which doesn't fit elsewhere + +The description should normally **not** contain: + +* Information which is already covered by factoids, like digging groups, + damage, group memberships, etc. +* How the item can be used +* Direct information about other items +* Any other redundant information +* Crafting recipes + +One exception from the rule may be for highlighting the most important +purpose of a simple item, like that coal lumps are primarily used as fuel. + +Sometimes, a long description is not necessary because the item is already +exhaustively explained by factoids. + +For very simple items, consider using one of the template texts (see below). + +Minimal style guide: Use complete sentences. + +#### Recommendations for usage help +The usage help should only be set for items which are in some way special +in their usage. Standard tools and weapons should never have an usage help. + +The rule of thumb is this: If a new player who already knows the Minetest +basics, but not this item, will not directly know how to use this item, +then the usage help should be added. If basic Minetest knowledge or +existing factoids are completely sufficient, usage help should not be added. + +The recommendations for what not to put into the usage help is the same +as for long descriptions. + +#### Template texts +For your convenience, a few template texts are provided for common texts +to avoid redundancy and to increase consistency for simple things. Read +`init.lua` to see the actual texts. + +##### Long description +* `doc.sub.items.temp.build`: For building blocks like the brick block in Minetest Game +* `doc.sub.items.temp.deco`: For other decorational blocks. +* `doc.sub.items.temp.craftitem`: For items solely or almost solely used for crafting + +##### Usage help +* `doc.sub.items.temp.eat`: For eatable items using the `on_use=minetest.item_eat(1)` idiom +* `doc.sub.items.temp.eat_bad`: Same as above, but eating them is considered a bad idea + +### Entry creation +By default, an entry for each item is added automatically, except for items +without a description (`description == nil`). This behaviour can be changed +on a per-item basis. + +By setting the item definition's field `_doc_items_create_entry` to `true` +or `false`you can explicitly define whether this item should get its own +entry. + +Suppressing an entry is useful for items which aren't supposed to be directly +seen or obtained by the player or if they are only used for technical +and/or internal purposes. Another possible reason to suppress an entry is +to scrub the entry list of lots of very similar related items where the +difference is too small to justify two separate entries (e.g. +burning furnace vs inactive furnace, because the gameplay mechanics are +identical for both). + +### Hidden entries +Hidden entries are entries which are not visible in the list of entries. This +concept directly comes from the Documentation System. The entry will still be +created, it is just not selectable by normal means. Players might be able to +“unlock†an entry later. Refer to the API documentation of the Documentation +System to learn more. + +By default, all entries are hidden except air and the hand. + +To mark an entry as hidden, add the field `_doc_items_hidden=true` to its +item definition. To make sure an entry is never hidden, add +`_doc_items_hidden=false` instead (this rarely needs to be specified +explicitly). + +### Hand and air +The mod adds some default help texts for the hand and the air which are +written in a way that they probably are true for most subgames out of the +box, but especially the hand help text is kept intentionally vague. +If you want to change these help texts or the entry names or other +attributes, just add `_doc_items_*` fields to the item definition, either +by re-defining or overwriting these items (e.g. with +`minetest.override_item`). + +In the mod `doc_minetest_game`, the default hand help text is overwritten +to explain the hand in more detail, especially the hand behaviour in +Creative Mode. + +## Functions +This is the reference of all available functions in this API. + +### `doc.sub.items.register_factoid(category_id, factoid_type, factoid_generator)` +Add a custom factoid (see above) for the specified category. + +* `category_id`: The help category for which the factoid applies: + * `"nodes"`: Blocks + * `"tools"`: Tools and weapons + * `"craftitems"`: Misc. items + * `nil`: All of the above +* `factoid_type`: Rough categorization of the factoid's content, used to + optimize the final text display. This currently determines where in the + entry text the factoid appears. Possible values: + * For all items: + * `"use"`: It's about using the item in some way (written right after the fixed usage help) + * `"groups"`: Group-related factoid (very vague) + * `"misc"`: Factoid doesn't fit anywhere else, is shown near the end + * For nodes only: + * `damage`: Related to player/mob damage or health + * `movement`: Related to player movement on, in or at node + * `sound`: Related to node sounds + * `gravity`: Related to gravity (e.g. falling node) + * `drop_destroy`: Related to node being destroyed or node dropping as an item + * `light`: Related to node light (luminance) + * `mining`: Related to mining +* `factoid_generator`: A function which turns item definition into a string + (see blow) + +#### `factoid_generator(itemstring, def)` +`itemstring` is the itemstring of the item to be documented, and `def` is the +complete item definition table (from Minetest). + +This function must return a helpful string which turns a part of the item's +definition into an useful sentence or text. The text can contain newlines, +but it must not end with a newline. + +This function must **always** return a string. If you don't want to add any text, +return the empty string. + +Style guide: Try to use complete sentences and avoid too many newlines. + +#### Example +This factoid will add the sentence “This block will extinguish nearby fire.†+to all blocks which are member of the group `puts_out_fire`. + + doc.sub.items.register_factoid("nodes", "groups", function(itemstring, def) + if def.groups.puts_out_fire ~= nil then + return "This block will extinguish nearby fire." + else + return "" + end + end) + +### `doc.sub.items.add_friendly_group_names(groupnames)` +Use this function so set some more readable group names to show them +in the formspec, since the internal group names are somewhat cryptic +to players. + +`groupnames` is a table where the keys are the “internal†group names and +the values are the group names which will be actually shown in the +Documentation System. + +***Note***: This function is mostly there to work around a problem in +Minetest as it does not support “friendly†group names, which means exposing +groups to an interface is not pretty. Therefore, this function may be +deprecated when Minetest supports such a thing. + +### `doc.sub.items.get_group_name(internal_group_name)` +Returns the group name of the specified group as displayed by this mod. +If the setting `doc_items_friendly_group_names` is `true`, this might +return a “friendly†group name (see above). If no friendly group name +exists, `internal_group_name` is returned. +If `doc_items_friendly_group_names` is `false`, the argument is always +returned. + +### `doc.sub.items.add_notable_groups(groupnames)` +Add a list of groups you think are notable enough to be mentioned in the +“This item belongs to the following groups: (…)†factoid. This factoid +is intended to give a quick rundown of misc. groups which don't fit +to other factoids, yet they are still somewhat relevant to gameplay. + +`groupnames` is a table of group names you wish to add. + +#### What groups should be added +What is “notable†is subjective, but there are some guidelines: + +Do add a group if: + +* It is used in an ABM +* It is used for a custom interaction with another item +* It is simple enough for the player to know an item is member of this group +* You want to refer to this group in help texts +* The “don'ts†below don't apply + +Do not add a group if: + +* It is *only* used for crafting, `connects_to`, mining times or damage groups +* A factoid covering this group already exists +* The group membership itself requires an explanation (consider writing a factoid instead) +* The group has no gameplay relevance +* Group rating is important to gameplay (consider writing a factoid instead) + +Groups which are used for crafting or in the `connects_to` field of item +definitions are already automatically added to this factoid. + +##### Examples for good additions + +* A group where its members can be placed in bookshelves. + so this group meets the “custom interaction†criterion +* `water` in Minetest Game: Used for water nodes in the obsidian ABM +* `sand` in Minetest Game: Used for the cactus growth ABM, but also crafting. + Since it is not *only* used for crafting, it is OK to be added + +##### Examples for bad additions + +* `stick` in Minetest Game: This group appears in many crafting recipes and + has no other use. It is already added automatically +* A group in which members turn into obsidian when they touch water (ABM): + This group is not trivial and should be introduced in a factoid instead +* `cracky` in Min +* `dig_immediate`: This group is already covered by the default factoids of this + mod + +## Dependencies +If you only add the custom fields to your items, you do *not* need to depend +on this mod. If you use anything else from this mod (e.g. a function), you +probably *do* need to depend (optionally or mandatorily) on this mod. diff --git a/mods/doc_modpack/doc_items/README.md b/mods/doc_modpack/doc_items/README.md new file mode 100644 index 0000000..fe99942 --- /dev/null +++ b/mods/doc_modpack/doc_items/README.md @@ -0,0 +1,68 @@ +# Item Help [`doc_items`] (Version 1.0.0) +## Description +Automatically generated help texts of blocks, tools, weapons, crafting +items and other items. + +The goal is to tell the player as much about basically almost all items as +possible, making it very convenient to look up simple things. + +The ultimate goal of this mod is that eventually all relevant items have +a complete in-game documentation so no item leaves you confused. + +This mod is useful to learn the hard facts about practically all items, like +how much damage weapon XYZ deals or whether you can dig that block. +This mod does *not* give you long explanations about how to use certain +nontrivial things, like the furnace from Minetest Game. This info might be +provided by other mods and insert it into the help. + +This mod provides 3 new help categories (using the +Documentation System [`doc`]): + +* Blocks (e.g. dirt, stone, wooden stair) +* Tools and weapons (e.g. wooden pickaxe, steel sword, screwdriver) +* Misc. items (e.g. dye, stick, flour) + +Entries are automatically added. The information in the entries is +mostly automatically generated. It contains information about a wide range +of topics: + +* Blocks + * Physics + * Digging properties + * Drops (including probabilities) + * Liquid information + * Pointability + * Luminance + * Much more +* Tools and weapons + * Mining capabilities + * Damage + * Durability + * More +* All items + * Range + * Stack size + * Group memberships + * Other information added by mods + +This mod also allows for mods to adding custom written description +and usage help texts in free-form and even custom automatically generated texts +for mod-specific information like flammability in Minetest Game. This is +one of the core features of this mod; the mod relies on other mods to +provide their custom help texts for a complete help. + +If you find a particular item which is lacking an explanation on usage, +request the mod author to add `doc_items` support. + +## API +This mod has an API so that modders can add their own custom help texts, +custom factoids (single pieces of information extracted from the +item definition) and more. + +For example, if your mods have some complex items which need +explanation, this mod can help you in adding help texts for them. + +Read `API.md` to learn more. + +## License +Everything in this mod is licensed under the MIT License. diff --git a/mods/doc_modpack/doc_items/depends.txt b/mods/doc_modpack/doc_items/depends.txt new file mode 100644 index 0000000..31aa390 --- /dev/null +++ b/mods/doc_modpack/doc_items/depends.txt @@ -0,0 +1,2 @@ +doc +intllib? diff --git a/mods/doc_modpack/doc_items/description.txt b/mods/doc_modpack/doc_items/description.txt new file mode 100644 index 0000000..7291077 --- /dev/null +++ b/mods/doc_modpack/doc_items/description.txt @@ -0,0 +1 @@ +Adds automatically generated help texts for items. diff --git a/mods/doc_modpack/doc_items/init.lua b/mods/doc_modpack/doc_items/init.lua new file mode 100644 index 0000000..92f8519 --- /dev/null +++ b/mods/doc_modpack/doc_items/init.lua @@ -0,0 +1,1341 @@ +-- Boilerplate to support localized strings if intllib mod is installed. +local S +if minetest.get_modpath("intllib") then + S = intllib.Getter() +else + S = function(s,a,...)a={a,...}return s:gsub("@(%d+)",function(n)return a[tonumber(n)]end)end +end + +doc.sub.items = {} + +-- Template texts +doc.sub.items.temp = {} +doc.sub.items.temp.deco = S("This is a decorational block.") +doc.sub.items.temp.build = S("This block is a building block for creating various buildings.") +doc.sub.items.temp.craftitem = S("This item is primarily used for crafting other items.") + +doc.sub.items.temp.eat = S("Hold it in your hand, then leftclick to eat it.") +doc.sub.items.temp.eat_bad = S("Hold it in your hand, then leftclick to eat it. But why would you want to do this?") + +doc.sub.items.settings = {} +doc.sub.items.settings.friendly_group_names = false +local setting = minetest.setting_getbool("doc_items_friendly_group_names") +if setting ~= nil then + doc.sub.items.settings.friendly_group_names = setting +end +doc.sub.items.settings.itemstring = false +setting = minetest.setting_getbool("doc_items_show_itemstrings") +if setting ~= nil then + doc.sub.items.settings.itemstring = setting +end + +-- Local stuff +local groupdefs = {} +local mininggroups = {} +local miscgroups = {} +local item_name_overrides = { + [""] = S("Hand"), + ["air"] = S("Air") +} +local suppressed = { + ["ignore"] = true, +} + +-- Helper functions +local yesno = function(bool) + if bool==true then return S("Yes") + elseif bool==false then return S("No") + else return "N/A" end +end + +local groups_to_string = function(grouptable, filter) + local gstring = "" + local groups_count = 0 + for id, value in pairs(grouptable) do + if (filter == nil or filter[id] == true) then + -- Readable group name + if groups_count > 0 then + -- List seperator + gstring = gstring .. S(", ") + end + if groupdefs[id] ~= nil and doc.sub.items.settings.friendly_group_names == true then + gstring = gstring .. groupdefs[id] + else + gstring = gstring .. id + end + groups_count = groups_count + 1 + end + end + if groups_count == 0 then + return nil, 0 + else + return gstring, groups_count + end +end + +-- Replaces all newlines with spaces +local scrub_newlines = function(text) + local new, x = string.gsub(text, "\n", " ") + return new +end + +--[[ Append a newline to text, unless it already ends with a newline. ]] +local newline = function(text) + if string.sub(text, #text, #text) == "\n" or text == "" then + return text + else + return text .. "\n" + end +end + +--[[ Make sure the text ends with two newlines by appending any missing newlines at the end, if neccessary. ]] +local newline2 = function(text) + if string.sub(text, #text-1, #text) == "\n\n" or text == "" then + return text + elseif string.sub(text, #text, #text) == "\n" then + return text .. "\n" + else + return text .. "\n\n" + end +end + + +-- Extract suitable item description for formspec +local description_for_formspec = function(itemstring) + if minetest.registered_items[itemstring] == nil then + -- Huh? The item doesn't exist for some reason. Better give a dummy string + minetest.log("warning", "[doc] Unknown item detected: "..tostring(itemstring)) + return S("Unknown item (@1)", tostring(itemstring)) + end + local description = minetest.registered_items[itemstring].description + if description == nil or description == "" then + return minetest.formspec_escape(itemstring) + else + return minetest.formspec_escape(scrub_newlines(description)) + end +end + +local get_entry_name = function(itemstring) + local def = minetest.registered_items[itemstring] + if def._doc_items_entry_name ~= nil then + return def._doc_items_entry_name + elseif item_name_overrides[itemstring] ~= nil then + return item_name_overrides[itemstring] + else + return def.description + end +end + +doc.sub.items.get_group_name = function(groupname) + if groupdefs[groupname] ~= nil and doc.sub.items.settings.friendly_group_names == true then + return groupdefs[groupname] + else + return groupname + end +end + +local burntime_to_text = function(burntime) + if burntime == nil then + return S("unknown") + elseif burntime == 1 then + return S("1 second") + else + return S("@1 seconds", burntime) + end +end + +--[[ Convert tool capabilities to readable text. Extracted information: +* Mining capabilities +* Durability (when mining +* Full punch interval +* Damage groups +]] +local factoid_toolcaps = function(tool_capabilities, check_uses) + local formstring = "" + if check_uses == nil then check_uses = false end + if tool_capabilities ~= nil and tool_capabilities ~= {} then + local groupcaps = tool_capabilities.groupcaps + if groupcaps ~= nil then + local miningcapstr = "" + local miningtimesstr = "" + local miningusesstr = "" + local caplines = 0 + local timelines = 0 + local useslines = 0 + for k,v in pairs(groupcaps) do + -- Mining capabilities + local minrating, maxrating + for rating, time in pairs(v.times) do + if minrating == nil then minrating = rating else + if minrating > rating then minrating = rating end + end + if maxrating == nil then maxrating = rating else + if maxrating < rating then maxrating = rating end + end + end + local maxlevel = v.maxlevel + if not maxlevel then + -- Default from tool.h + maxlevel = 1 + end + miningcapstr = miningcapstr .. S("• @1: @2", doc.sub.items.get_group_name(k), maxlevel) + miningcapstr = miningcapstr .. "\n" + caplines = caplines + 1 + + for rating=3, 1, -1 do + if v.times ~= nil and v.times[rating] ~= nil then + local maxtime = v.times[rating] + local mintime + local mintimestr, maxtimestr + local maxlevel_calc = maxlevel + if maxlevel_calc < 1 then + maxlevel_calc = 1 + end + mintime = maxtime / maxlevel_calc + mintimestr = string.format("%.1f", mintime) + maxtimestr = string.format("%.1f", maxtime) + if mintimestr ~= maxtimestr then + miningtimesstr = miningtimesstr .. + S("• @1, rating @2: @3 s - @4 s", + doc.sub.items.get_group_name(k), rating, + mintimestr, maxtimestr) + else + miningtimesstr = miningtimesstr .. + S("• @1, rating @2: @3 s", + doc.sub.items.get_group_name(k), rating, + mintimestr) + end + miningtimesstr = miningtimesstr.. "\n" + timelines = timelines + 1 + end + end + + -- Number of mining uses + local base_uses = v.uses + if not base_uses then + -- Default from tool.h + base_uses = 20 + end + if check_uses and base_uses > 0 then + for level=0, maxlevel do + local real_uses = base_uses * math.pow(3, maxlevel - level) + if real_uses < 65535 then + miningusesstr = miningusesstr .. S("• @1, level @2: @3 uses", doc.sub.items.get_group_name(k), level, real_uses) + else + miningusesstr = miningusesstr .. S("• @1, level @2: Unlimited", doc.sub.items.get_group_name(k), level) + end + miningusesstr = miningusesstr .. "\n" + useslines = useslines + 1 + end + end + end + if caplines > 0 then + formstring = formstring .. S("This tool is capable of mining.") .. "\n" + formstring = formstring .. S("Maximum toughness levels:") .. "\n" + formstring = formstring .. miningcapstr + formstring = newline(formstring) + end + if timelines > 0 then + formstring = formstring .. S("Mining times:") .. "\n" + formstring = formstring .. miningtimesstr + end + if useslines > 0 then + formstring = formstring .. S("Mining durability:") .. "\n" + formstring = formstring .. miningusesstr + end + if caplines > 0 or useslines > 0 or timelines > 0 then + formstring = newline2(formstring) + end + end + + -- Weapon data + local damage_groups = tool_capabilities.damage_groups + if damage_groups ~= nil then + formstring = formstring .. S("This is a melee weapon which deals damage by punching.") .. "\n" + -- Damage groups + formstring = formstring .. S("Maximum damage per hit:") .. "\n" + for k,v in pairs(damage_groups) do + formstring = formstring .. S("• @1: @2 HP", doc.sub.items.get_group_name(k), v) + formstring = formstring .. "\n" + end + + -- Full punch interval + local punch = 1.0 + if tool_capabilities.full_punch_interval ~= nil then + punch = tool_capabilities.full_punch_interval + end + formstring = formstring .. S("Full punch interval: @1 s", string.format("%.1f", punch)) + formstring = formstring .. "\n" + end + + end + return formstring +end + +-- Pointing range of itmes +local range_factoid = function(itemstring, def) + local handrange = minetest.registered_items[""].range + local itemrange = def.range + if itemstring == "" then + if handrange ~= nil then + return S("Range: @1", itemrange) + else + return S("Range: 4") + end + else + if handrange == nil then handrange = 4 end + if itemrange ~= nil then + return S("Range: @1", itemrange) + else + return S("Range: @1 (@2)", get_entry_name(""), handrange) + end + end +end + +-- Smelting fuel factoid +local factoid_fuel = function(itemstring, ctype) + local formstring = "" + local result, decremented = minetest.get_craft_result({method = "fuel", items = {itemstring}}) + if result ~= nil and result.time > 0 then + local base + local burntext = burntime_to_text(result.time) + if ctype == "tools" then + base = S("This tool can serve as a smelting fuel with a burning time of @1.", burntext) + elseif ctype == "nodes" then + base = S("This block can serve as a smelting fuel with a burning time of @1.", burntext) + else + base = S("This item can serve as a smelting fuel with a burning time of @1.", burntext) + end + formstring = formstring .. base + local replaced = decremented.items[1]:get_name() + if not decremented.items[1]:is_empty() and replaced ~= itemstring then + formstring = formstring .. S(" Using it as fuel turns it into: @1.", description_for_formspec(replaced)) + end + formstring = newline(formstring) + end + return formstring +end + +-- Shows the itemstring of an item +local factoid_itemstring = function(itemstring, playername) + local privs = minetest.get_player_privs(playername) + if doc.sub.items.settings.itemstring or (privs.give or privs.debug) then + return S("Itemstring: \"@1\"", itemstring) + else + return "" + end +end + +local entry_image = function(data) + local formstring = "" + -- No image for air + if data.itemstring ~= "air" then + -- Hand + if data.itemstring == "" then + formstring = formstring .. "image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;".. + minetest.registered_items[""].wield_image.."]" + -- Other items + elseif data.image ~= nil then + formstring = formstring .. "image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.image.."]" + else + formstring = formstring .. "item_image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.itemstring.."]" + end + end + return formstring +end + +-- Stuff for factoids +local factoid_generators = {} +factoid_generators.nodes = {} +factoid_generators.tools = {} +factoid_generators.craftitems = {} + +--[[ Returns a list of all registered factoids for the specified category and type +* category_id: Identifier of the Documentation System category in which the factoid appears +* factoid_type: If set, oly returns factoid with a matching factoid_type. + If nil, all factoids for this category will be generated +* data: Entry data to parse ]] +local factoid_custom = function(category_id, factoid_type, data) + local ftable = factoid_generators[category_id] + local datastring = "" + -- Custom factoids are inserted here + for i=1,#ftable do + if factoid_type == nil or ftable[i].ftype == factoid_type then + datastring = datastring .. ftable[i].fgen(data.itemstring, data.def) + if datastring ~= "" then + datastring = newline(datastring) + end + end + end + return datastring +end + +-- Shows core information shared by all items, to be inserted at the top +local factoids_header = function(data, ctype) + local longdesc = data.longdesc + local usagehelp = data.usagehelp + local crafting = data.crafting + local datastring = "" + if longdesc ~= nil then + datastring = datastring .. S("Description: @1", longdesc) + datastring = newline2(datastring) + end + if usagehelp ~= nil then + datastring = datastring .. S("Usage help: @1", usagehelp) + datastring = newline2(datastring) + end + if crafting ~= nil then + datastring = datastring .. crafting + datastring = newline2(datastring) + end + datastring = datastring .. factoid_custom(ctype, "use", data) + datastring = newline2(datastring) + + if data.itemstring ~= "" then + datastring = datastring .. S("Maximum stack size: @1", data.def.stack_max) + datastring = newline(datastring) + end + datastring = datastring .. range_factoid(data.itemstring, data.def) + + datastring = newline2(datastring) + + if data.def.liquids_pointable == true then + if ctype == "nodes" then + datastring = datastring .. S("This block points to liquids.").."\n" + elseif ctype == "tools" then + datastring = datastring .. S("This tool points to liquids.").."\n" + elseif ctype == "craftitems" then + datastring = datastring .. S("This item points to liquids.").."\n" + end + end + if data.def.on_use ~= nil then + if ctype == "nodes" then + datastring = datastring .. S("Punches with this block don't work as usual; melee combat and mining are either not possible or work differently.").."\n" + elseif ctype == "tools" then + datastring = datastring .. S("Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently.").."\n" + elseif ctype == "craftitems" then + datastring = datastring .. S("Punches with this item don't work as usual; melee combat and mining are either not possible or work differently.").."\n" + end + end + + datastring = newline(datastring) + + -- Show tool capability stuff, including durability if not overwritten by custom field + local check_uses = false + if ctype == "tools" then + check_uses = data.def._doc_items_durability == nil + end + datastring = datastring .. factoid_toolcaps(data.def.tool_capabilities, check_uses) + datastring = newline2(datastring) + + return datastring +end + +-- Shows less important information shared by all items, to be inserted at the bottom +local factoids_footer = function(data, playername, ctype) + local datastring = "" + datastring = datastring .. factoid_custom(ctype, "groups", data) + datastring = newline2(datastring) + + -- Show other “exposable†groups + local gstring, gcount = groups_to_string(data.def.groups, miscgroups) + if gstring ~= nil then + if gcount == 1 then + if ctype == "nodes" then + datastring = datastring .. S("This block belongs to the @1 group.", gstring) .. "\n" + elseif ctype == "tools" then + datastring = datastring .. S("This tool belongs to the @1 group.", gstring) .. "\n" + elseif ctype == "craftitems" then + datastring = datastring .. S("This item belongs to the @1 group.", gstring) .. "\n" + end + else + if ctype == "nodes" then + datastring = datastring .. S("This block belongs to these groups: @1.", gstring) .. "\n" + elseif ctype == "tools" then + datastring = datastring .. S("This tool belongs to these groups: @1.", gstring) .. "\n" + elseif ctype == "craftitems" then + datastring = datastring .. S("This item belongs to these groups: @1.", gstring) .. "\n" + end + end + end + datastring = newline2(datastring) + + -- Show fuel recipe + datastring = datastring .. factoid_fuel(data.itemstring, ctype) + datastring = newline2(datastring) + + -- Other custom factoids + datastring = datastring .. factoid_custom(ctype, "misc", data) + datastring = newline2(datastring) + + -- Itemstring + datastring = datastring .. factoid_itemstring(data.itemstring, playername) + + return datastring +end + +function doc.sub.items.register_factoid(category_id, factoid_type, factoid_generator) + local ftable = { fgen = factoid_generator, ftype = factoid_type } + if category_id == "nodes" or category_id == "tools" or category_id == "craftitems" then + table.insert(factoid_generators[category_id], ftable) + return true + elseif category_id == nil then + table.insert(factoid_generators.nodes, ftable) + table.insert(factoid_generators.tools, ftable) + table.insert(factoid_generators.craftitems, ftable) + return false + end +end + +doc.add_category("nodes", { + hide_entries_by_default = true, + name = S("Blocks"), + description = S("Item reference of blocks and other things which are capable of occupying space"), + build_formspec = function(data, playername) + if data then + local formstring = "" + local datastring = "" + + formstring = entry_image(data) + datastring = factoids_header(data, "nodes") + + datastring = datastring .. S("Collidable: @1", yesno(data.def.walkable)) .. "\n" + local liquid + if data.def.liquidtype ~= "none" then liquid = true else liquid = false end + if data.def.pointable == true then + datastring = datastring .. S("Pointable: Yes") .. "\n" + elseif liquid then + datastring = datastring .. S("Pointable: Only by special items") .. "\n" + else + datastring = datastring .. S("Pointable: No") .. "\n" + end + datastring = newline2(datastring) + if liquid then + datastring = newline(datastring, false) + datastring = datastring .. S("This block is a liquid with these properties:") .. "\n" + local range, renew, viscos + if data.def.liquid_range then range = data.def.liquid_range else range = 8 end + if data.def.liquid_renewable ~= nil then renew = data.def.liquid_renewable else renew = true end + if data.def.liquid_viscosity then viscos = data.def.liquid_viscosity else viscos = 0 end + if renew then + datastring = datastring .. S("• Renewable") .. "\n" + else + datastring = datastring .. S("• Not renewable") .. "\n" + end + if range == 0 then + datastring = datastring .. S("• No flowing") .. "\n" + else + datastring = datastring .. S("• Flowing range: @1", range) .. "\n" + end + datastring = datastring .. S("• Viscosity: @1", viscos) .. "\n" + end + datastring = newline2(datastring) + + -- Global factoids + --- Direct interaction with the player + ---- Damage (very important) + if data.def.damage_per_second ~= nil and data.def.damage_per_second > 1 then + datastring = datastring .. S("This block causes a damage of @1 hit points per second.", data.def.damage_per_second) .. "\n" + elseif data.def.damage_per_second == 1 then + datastring = datastring .. S("This block causes a damage of @1 hit point per second.", data.def.damage_per_second) .. "\n" + end + if data.def.drowning then + if data.def.drowning > 1 then + datastring = datastring .. S("This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.", data.def.drowning) .. "\n" + elseif data.def.drowning == 1 then + datastring = datastring .. S("This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds.", data.def.drowning) .. "\n" + end + end + local fdap = data.def.groups.fall_damage_add_percent + if fdap ~= nil then + if fdap > 0 then + datastring = datastring .. S("The fall damage on this block is increased by @1%.", fdap) .. "\n" + elseif fdap <= -100 then + datastring = datastring .. S("This block negates all fall damage.") .. "\n" + else + datastring = datastring .. S("The fall damage on this block is reduced by @1%.", math.abs(fdap)) .. "\n" + end + end + datastring = datastring .. factoid_custom("nodes", "damage", data) + datastring = newline2(datastring) + + ---- Movement + if data.def.groups.disable_jump == 1 then + datastring = datastring .. S("You can not jump while standing on this block.").."\n" + end + if data.def.climbable == true then + datastring = datastring .. S("This block can be climbed.").."\n" + end + local bouncy = data.def.groups.bouncy + if bouncy ~= nil then + datastring = datastring .. S("This block will make you bounce off with an elasticity of @1%.", bouncy).."\n" + end + datastring = datastring .. factoid_custom("nodes", "movement", data) + datastring = newline2(datastring) + + ---- Sounds + local function is_silent(def, soundtype) + return type(def.sounds) ~= "table" or def.sounds[soundtype] == nil or def.sounds[soundtype] == "" or (type(data.def.sounds[soundtype]) == "table" and (data.def.sounds[soundtype].name == nil or data.def.sounds[soundtype].name == "")) + end + local silentstep, silentdig, silentplace = false, false, false + if data.def.walkable and is_silent(data.def, "footstep") then + silentstep = true + end + if data.def.diggable and is_silent(data.def, "dig") and is_silent(data.def, "dug") then + silentdig = true + end + if is_silent(data.def, "place") and is_silent(data.def, "place_failed") and data.itemstring ~= "air" then + silentplace = true + end + if silentstep and silentdig and silentplace then + datastring = datastring .. S("This block is completely silent when walked on, mined or built.").."\n" + elseif silentdig and silentplace then + datastring = datastring .. S("This block is completely silent when mined or built.").."\n" + else + if silentstep then + datastring = datastring .. S("Walking on this block is completely silent.").."\n" + end + if silentdig then + datastring = datastring .. S("Mining this block is completely silent.").."\n" + end + if silentplace then + datastring = datastring .. S("Building this block is completely silent.").."\n" + end + end + datastring = datastring .. factoid_custom("nodes", "sound", data) + datastring = newline2(datastring) + + -- Block activity + --- Gravity + if data.def.groups.falling_node == 1 then + datastring = datastring .. S("This block is affected by gravity and can fall.").."\n" + end + datastring = datastring .. factoid_custom("nodes", "gravity", data) + datastring = newline2(datastring) + + --- Dropping and destruction + if data.def.buildable_to == true then + datastring = datastring .. S("Building another block at this block will place it inside and replace it.").."\n" + if data.def.walkable then + datastring = datastring .. S("Falling blocks can go through this block; they destroy it when doing so.").."\n" + end + end + if data.def.walkable == false then + if data.def.buildable_to == false and data.def.drop ~= "" then + datastring = datastring .. S("This block will drop as an item when a falling block ends up inside it.").."\n" + else + datastring = datastring .. S("This block is destroyed when a falling block ends up inside it.").."\n" + end + end + if data.def.groups.attached_node == 1 then + if data.def.paramtype2 == "wallmounted" then + datastring = datastring .. S("This block will drop as an item when it is not attached to a surrounding block.").."\n" + else + datastring = datastring .. S("This block will drop as an item when no collidable block is below it.").."\n" + end + end + if data.def.floodable == true then + datastring = datastring .. S("Liquids can flow into this block and destroy it.").."\n" + end + datastring = datastring .. factoid_custom("nodes", "drop_destroy", data) + datastring = newline2(datastring) + + -- Block appearance + --- Light + if data.def.light_source then + if data.def.light_source > 3 then + datastring = datastring .. S("This block is a light source with a light level of @1.", data.def.light_source).."\n" + elseif data.def.light_source > 0 then + datastring = datastring .. S("This block glows faintly with a light level of @1.", data.def.light_source).."\n" + end + if data.def.paramtype == "light" and data.def.sunlight_propagates then + datastring = datastring .. S("This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly.").."\n" + elseif data.def.paramtype == "light" then + datastring = datastring .. S("This block allows light to propagate with a small loss of brightness.").."\n" + elseif data.def.sunlight_propagates then + datastring = datastring .. S("This block allows sunlight to propagate without loss in brightness.").."\n" + end + end + datastring = datastring .. factoid_custom("nodes", "light", data) + datastring = newline2(datastring) + + --- List nodes/groups to which this node connects to + if data.def.connects_to ~= nil then + local nodes = {} + local groups = {} + for c=1,#data.def.connects_to do + local itemstring = data.def.connects_to[c] + if string.sub(itemstring,1,6) == "group:" then + groups[string.sub(itemstring,7,#itemstring)] = 1 + else + table.insert(nodes, itemstring) + end + end + + local nstring = "" + for n=1,#nodes do + local name + if item_name_overrides[nodes[n]] ~= nil then + name = item_name_overrides[nodes[n]] + else + name = description_for_formspec(minetest.registered_nodes[nodes[n]]) + end + if n > 1 then + nstring = nstring .. S(", ") + end + if name ~= nil then + nstring = nstring .. name + else + nstring = nstring .. S("Unknown Node") + end + end + if #nodes == 1 then + datastring = datastring .. S("This block connects to this block: @1.", nstring) .. "\n" + elseif #nodes > 1 then + datastring = datastring .. S("This block connects to these blocks: @1.", nstring) .. "\n" + end + + local gstring, gcount = groups_to_string(groups) + if gcount == 1 then + datastring = datastring .. S("This block connects to blocks of the @1 group.", gstring) .. "\n" + elseif gcount > 1 then + datastring = datastring .. S("This block connects to blocks of the following groups: @1.", gstring) .. "\n" + end + end + + datastring = newline2(datastring) + + -- Mining groups + datastring = datastring .. factoid_custom("nodes", "mining", data) + datastring = newline(datastring) + if data.def.pointable ~= false and (data.def.liquid_type == "none" or data.def.liquid_type == nil) then + -- Check if there are no mining groups at all + local nogroups = true + for groupname,_ in pairs(mininggroups) do + if data.def.groups[groupname] ~= nil or groupname == "dig_immediate" then + nogroups = false + break + end + end + -- dig_immediate + if data.def.drop ~= "" then + if data.def.groups.dig_immediate == 2 then + datastring = datastring .. S("This block can be mined by any mining tool in half a second.").."\n" + elseif data.def.groups.dig_immediate == 3 then + datastring = datastring .. S("This block can be mined by any mining tool immediately.").."\n" + -- Note: “unbreakable†is an unofficial group for undiggable blocks + elseif data.def.diggable == false or nogroups or data.def.groups.immortal == 1 or data.def.groups.unbreakable == 1 then + datastring = datastring .. S("This block can not be mined by ordinary mining tools.").."\n" + end + else + if data.def.groups.dig_immediate == 2 then + datastring = datastring .. S("This block can be destroyed by any mining tool in half a second.").."\n" + elseif data.def.groups.dig_immediate == 3 then + datastring = datastring .. S("This block can be destroyed by any mining tool immediately.").."\n" + elseif data.def.diggable == false or nogroups or data.def.groups.immortal == 1 or data.def.groups.unbreakable == 1 then + datastring = datastring .. S("This block can not be destroyed by ordinary mining tools.").."\n" + end + end + -- Expose “ordinary†mining groups (crumbly, cracky, etc.) and level group + -- Skip this for immediate digging to avoid redundancy + if data.def.groups.dig_immediate ~= 3 then + local mstring = S("This block can be mined by mining tools which match any of the following mining ratings and its toughness level.").."\n" + mstring = mstring .. S("Mining ratings:").."\n" + local minegroupcount = 0 + for group,_ in pairs(mininggroups) do + local rating = data.def.groups[group] + if rating ~= nil then + mstring = mstring .. S("• @1: @2", doc.sub.items.get_group_name(group), rating).."\n" + minegroupcount = minegroupcount + 1 + end + end + local level = data.def.groups.level + if not level then + level = 0 + end + mstring = mstring .. S("Toughness level: @1", level).."\n" + + if minegroupcount > 0 then + datastring = datastring .. mstring + end + end + end + datastring = newline2(datastring) + + -- Non-default drops + --[[ + if data.def.drop ~= nil and data.def.drop ~= data.itemstring and data.itemstring ~= "air" then + -- TODO: Calculate drop probabilities of max > 1 like for max == 1 + local get_desc = function(stack) + return description_for_formspec(stack:get_name()) + end + if data.def.drop == "" then + datastring = datastring .. S("This block won't drop anything when mined.").."\n" + elseif type(data.def.drop) == "string" then + local dropstack = ItemStack(data.def.drop) + if dropstack:get_name() ~= data.itemstring and dropstack:get_name() ~= 1 then + local desc = get_desc(dropstack) + local count = dropstack:get_count() + if count > 1 then + datastring = datastring .. S("This block will drop the following when mined: @1×@2.", count, desc).."\n" + else + datastring = datastring .. S("This block will drop the following when mined: @1.", desc).."\n" + end + end + elseif type(data.def.drop) == "table" and data.def.drop.items ~= nil then + local max = data.def.drop.max_items + local dropstring = "" + local dropstring_base = "" + if max == nil then + dropstring_base = S("This block will drop the following items when mined: %s.") + elseif max == 1 then + if #data.def.drop.items == 1 then + dropstring_base = S("This block will drop the following when mined: %s.") + else + dropstring_base = S("This block will randomly drop one of the following when mined: %s.") + end + else + dropstring_base = S("This block will randomly drop up to %d drops of the following possible drops when mined: %s.") + end + -- Save calculated probabilities into a table for later output + local probtables = {} + local probtable + local rarity_history = {} + for i=1,#data.def.drop.items do + local local_rarity = data.def.drop.items[i].rarity + local chance = 1 + local rarity = 1 + if local_rarity == nil then + local_rarity = 1 + end + if max == 1 then + -- Chained probability + table.insert(rarity_history, local_rarity) + chance = 1 + for r=1, #rarity_history do + local chance_factor + if r > 1 and rarity_history[r-1] == 1 then + chance = 0 + break + end + if r == #rarity_history then + chance_factor = 1/rarity_history[r] + else + chance_factor = (rarity_history[r]-1)/rarity_history[r] + end + chance = chance * chance_factor + end + if chance > 0 then + rarity = 1/chance + end + else + rarity = local_rarity + chance = 1/rarity + end + -- Exclude impossible drops + if chance > 0 then + probtable = {} + probtable.items = {} + for j=1,#data.def.drop.items[i].items do + local dropstack = ItemStack(data.def.drop.items[i].items[j]) + local itemstring = dropstack:get_name() + local desc = get_desc(dropstack) + local count = dropstack:get_count() + if not(itemstring == nil or itemstring == "" or count == 0) then + if probtable.items[itemstring] == nil then + probtable.items[itemstring] = {desc = desc, count = count} + else + probtable.items[itemstring].count = probtable.items[itemstring].count + count + end + end + end + probtable.rarity = rarity + if #data.def.drop.items[i].items > 0 then + table.insert(probtables, probtable) + end + end + end + -- Do some cleanup of the probability table + if max == 1 or max == nil then + -- Sort by rarity + local comp = function(p1, p2) + return p1.rarity < p2.rarity + end + table.sort(probtables, comp) + end + -- Output probability table + local pcount = 0 + for i=1, #probtables do + if pcount > 0 then + -- List seperator + dropstring = dropstring .. S(", ") + end + local probtable = probtables[i] + local icount = 0 + local dropstring_this = "" + for _, itemtable in pairs(probtable.items) do + if icount > 0 then + -- Final list seperator + dropstring_this = dropstring_this .. S(" and ") + end + local desc = S(itemtable.desc) + local count = itemtable.count + if count ~= 1 then + desc = S("@1×@2", count, desc) + end + dropstring_this = dropstring_this .. desc + icount = icount + 1 + end + + local rarity = probtable.rarity + local raritystring = "" + -- No percentage if there's only one possible guaranteed drop + if not(rarity == 1 and #data.def.drop.items == 1) then + local chance = (1/rarity)*100 + if rarity > 200 then -- <0.5% + -- For very low percentages + dropstring_this = S("@1 (<0.5%)", dropstring_this) + else + -- Add circa indicator for percentages with decimal point + local fchance = string.format("%.0f", chance) + if math.fmod(chance, 1) > 0 then + dropstring_this = S("@1 (ca. @2%)", dropstring_this, fchance) + else + dropstring_this = S("@1 (@2%)", dropstring_this, fchance) + end + end + end + dropstring = dropstring .. dropstring_this + pcount = pcount + 1 + end + if max ~= nil and max > 1 then + datastring = datastring .. string.format(dropstring_base, max, dropstring) + else + datastring = datastring .. string.format(dropstring_base, dropstring) + end + datastring = newline(datastring) + end + --]] + --end + --datastring = newline2(datastring) + + datastring = datastring .. factoids_footer(data, playername, "nodes") + + formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2) + + return formstring + else + return "label[0,1;NO DATA AVALIABLE!]" + end + end +}) + +doc.add_category("tools", { + hide_entries_by_default = true, + name = S("Tools and weapons"), + description = S("Item reference of all wieldable tools and weapons"), + sorting = "function", + -- Roughly sort tools based on their capabilities. Tools which dig the same stuff end up in the same group + sorting_data = function(entry1, entry2) + local entries = { entry1, entry2 } + -- Hand beats all + if entries[1].eid == "" then return true end + if entries[2].eid == "" then return false end + + local comp = {} + for e=1, 2 do + comp[e] = {} + end + -- No tool capabilities: Instant loser + if entries[1].data.def.tool_capabilities == nil and entries[2].data.def.tool_capabilities ~= nil then return false end + if entries[2].data.def.tool_capabilities == nil and entries[1].data.def.tool_capabilities ~= nil then return true end + -- No tool capabilities for both: Compare by uses + if entries[1].data.def.tool_capabilities == nil and entries[2].data.def.tool_capabilities == nil then + for e=1, 2 do + if type(entries[e].data.def._doc_items_durability) == "number" then + comp[e].uses = entries[e].data.def._doc_items_durability + else + comp[e].uses = 0 + end + end + return comp[1].uses > comp[2].uses + end + for e=1, 2 do + comp[e].gc = entries[e].data.def.tool_capabilities.groupcaps + end + -- No group capabilities = instant loser + if comp[1].gc == nil then return false end + if comp[2].gc == nil then return true end + for e=1, 2 do + local groups = {} + local gc = comp[e].gc + local group = nil + local mintime = nil + local groupcount = 0 + local uses = nil + for k,v in pairs(gc) do + local maxlevel = v.maxlevel + if maxlevel == nil then + maxlevel = 1 + end + if groupcount == 0 then + group = k + uses = v.uses * math.pow(3, v.maxlevel) + end + for rating, time in pairs(v.times) do + local realtime = time / v.maxlevel + if mintime == nil or realtime < mintime then + mintime = realtime + end + end + if groups[k] ~= true then + groupcount = groupcount + 1 + groups[k] = true + end + end + comp[e].count = groupcount + comp[e].group = group + comp[e].mintime = mintime + if uses ~= nil then + comp[e].uses = uses + elseif type(entries[e].data.def._doc_items_durability) == "number" then + comp[e].uses = entries[e].data.def._doc_items_durability + else + comp[e].uses = 0 + end + end + + -- We want to sort out digging tools with multiple capabilities + if comp[1].count > 1 and comp[1].count > comp[2].count then + return false + elseif comp[1].group == comp[2].group then + -- Tiebreaker 1: Minimum digging time + if comp[1].mintime == comp[2].mintime then + -- Tiebreaker 2: Use count + return comp[1].uses > comp[2].uses + else + return comp[1].mintime < comp[2].mintime + end + -- Final tiebreaker: Sort by group name + else + return comp[1].group < comp[2].group + end + end, + build_formspec = function(data, playername) + if data then + local formstring = "" + local datastring = "" + + formstring = entry_image(data) + datastring = factoids_header(data, "tools") + + -- Overwritten durability info + if type(data.def._doc_items_durability) == "number" then + -- Fixed number of uses + datastring = datastring .. S("Durability: @1 uses", data.def._doc_items_durability) + datastring = newline2(datastring) + elseif type(data.def._doc_items_durability) == "string" then + -- Manually described durability + datastring = datastring .. S("Durability: @1", data.def._doc_items_durability) + datastring = newline2(datastring) + end + + datastring = datastring .. factoids_footer(data, playername, "tools") + + formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2) + + return formstring + else + return "label[0,1;NO DATA AVALIABLE!]" + end + end +}) + +doc.add_category("craftitems", { + hide_entries_by_default = true, + name = S("Miscellaneous items"), + description = S("Item reference of items which are neither blocks, tools or weapons (esp. crafting items)"), + build_formspec = function(data, playername) + if data then + local formstring = "" + local datastring = "" + + formstring = entry_image(data) + datastring = factoids_header(data, "craftitems") + datastring = datastring .. factoids_footer(data, playername, "craftitems") + + formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2) + + return formstring + else + return "label[0,1;NO DATA AVALIABLE!]" + end + end +}) + +-- Register group definition stuff +-- More (user-)friendly group names to replace the rather technical names +-- for better understanding +function doc.sub.items.add_friendly_group_names(groupnames) + for internal, real in pairs(groupnames) do + groupdefs[internal] = real + end +end + +-- Adds groups to be displayed in the generic “misc.†groups +-- factoid. Those groups should be neither be used as mining +-- groups nor as damage groups and should be relevant to the +-- player in someway. +function doc.sub.items.add_notable_groups(groupnames) + for g=1,#groupnames do + miscgroups[groupnames[g]] = true + end +end + +-- Collect information about all items +local function gather_descs() + -- Internal help texts for default items + local help = { + longdesc = {}, + usagehelp = {}, + } + + -- 1st pass: Gather groups of interest + for id, def in pairs(minetest.registered_items) do + -- Gather all groups used for mining + if def.tool_capabilities ~= nil then + local groupcaps = def.tool_capabilities.groupcaps + if groupcaps ~= nil then + for k,v in pairs(groupcaps) do + if mininggroups[k] ~= true then + mininggroups[k] = true + end + end + end + end + + -- ... and gather all groups which appear in crafting recipes + local crafts = minetest.get_all_craft_recipes(id) + if crafts ~= nil then + for c=1,#crafts do + for k,v in pairs(crafts[c].items) do + if string.sub(v,1,6) == "group:" then + local groupstring = string.sub(v,7,-1) + local groups = string.split(groupstring, ",") + for g=1, #groups do + miscgroups[groups[g]] = true + end + end + end + end + end + + -- ... and gather all groups used in connects_to + if def.connects_to ~= nil then + for c=1, #def.connects_to do + if string.sub(def.connects_to[c],1,6) == "group:" then + local group = string.sub(def.connects_to[c],7,-1) + miscgroups[group] = true + end + end + end + end + + -- 2nd pass: Add entries + + -- Set default air text + -- Custom longdesc and usagehelp may be set by mods through the add_helptexts function + if minetest.registered_items["air"]._doc_items_longdesc then + help.longdesc["air"] = minetest.registered_items["air"]._doc.items_longdesc + else + help.longdesc["air"] = S("A transparent block, basically empty space. It is usually left behind after digging something.") + end + if minetest.registered_items["ignore"]._doc_items_create_entry ~= nil then + suppressed["ignore"] = minetest.registered_items["ignore"]._doc_items_create_entry == true + end + + -- Add entry for the default tool (“handâ€) + -- Custom longdesc and usagehelp may be set by mods through the add_helptexts function + local handdef = minetest.registered_items[""] + if handdef._doc_items_create_entry ~= false then + if handdef._doc_items_longdesc then + help.longdesc[""] = handdef._doc_items_longdesc + else + -- Default text + help.longdesc[""] = S("Whenever you are not wielding any item, you use the hand which acts as a tool with its own capabilities. When you are wielding an item which is not a mining tool or a weapon it will behave as if it would be the hand.") + end + if handdef._doc_items_entry_name then + item_name_overrides[""] = handdef._doc_items_entry_name + end + doc.add_entry("tools", "", { + name = item_name_overrides[""], + hidden = handdef._doc_items_hidden == true, + data = { + longdesc = help.longdesc[""], + usagehelp = help.usagehelp[""], + itemstring = "", + def = handdef, + } + }) + end + + local add_entries = function(deftable, category_id) + for id, def in pairs(deftable) do + local name, ld, uh, im, cr + local forced = false + if def._doc_items_create_entry == true and def ~= nil then forced = true end + name = get_entry_name(id) + if not (((def.description == nil or def.description == "") and def._doc_items_entry_name == nil) or (def._doc_items_create_entry == false) or (suppressed[id] == true)) or forced then + if def._doc_items_longdesc then + ld = def._doc_items_longdesc + end + if help.longdesc[id] ~= nil then + ld = help.longdesc[id] + end + if def._doc_items_usagehelp then + uh = def._doc_items_usagehelp + end + if help.usagehelp[id] ~= nil then + uh = help.usagehelp[id] + end + if def._doc_items_image then + im = def._doc_items_image + end + if def._doc_items_crafting then + cr = def._doc_items_crafting + end + local hidden + if id == "air" or id == "" then hidden = false end + if type(def._doc_items_hidden) == "boolean" then + hidden = def._doc_items_hidden + end + local custom_image + name = scrub_newlines(name) + local infotable = { + name = name, + hidden = hidden, + data = { + longdesc = ld, + usagehelp = uh, + crafting = cr, + image = im, + itemstring = id, + def = def, + } + } + doc.add_entry(category_id, id, infotable) + end + end + end + + -- Add node entries + add_entries(minetest.registered_nodes, "nodes") + + -- Add tool entries + add_entries(minetest.registered_tools, "tools") + + -- Add craftitem entries + add_entries(minetest.registered_craftitems, "craftitems") +end + +--[[ Reveal items as the player progresses through the game. +Items are revealed by: +* Digging, punching or placing node, +* Crafting +* Having item in inventory (not instantly revealed) ]] + +local function reveal_item(playername, itemstring) + local category_id + if itemstring == nil or itemstring == "" or playername == nil or playername == "" then + return false + end + if minetest.registered_nodes[itemstring] ~= nil then + category_id = "nodes" + elseif minetest.registered_tools[itemstring] ~= nil then + category_id = "tools" + elseif minetest.registered_craftitems[itemstring] ~= nil then + category_id = "craftitems" + elseif minetest.registered_items[itemstring] ~= nil then + category_id = "craftitems" + else + return false + end + doc.mark_entry_as_revealed(playername, category_id, itemstring) + return true +end + +local function reveal_items_in_inventory(player) + local inv = player:get_inventory() + local list = inv:get_list("main") + for l=1, #list do + reveal_item(player:get_player_name(), list[l]:get_name()) + end +end + +minetest.register_on_dignode(function(pos, oldnode, digger) + if digger == nil then return end + local playername = digger:get_player_name() + if playername ~= nil and playername ~= "" and oldnode ~= nil then + reveal_item(playername, oldnode.name) + reveal_items_in_inventory(digger) + end +end) + +minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing) + if puncher == nil then return end + local playername = puncher:get_player_name() + if playername ~= nil and playername ~= "" and node ~= nil then + reveal_item(playername, node.name) + end +end) + +minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing) + if placer == nil then return end + local playername = placer:get_player_name() + if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then + reveal_item(playername, itemstack:get_name()) + end +end) + +minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) + if player == nil then return end + local playername = player:get_player_name() + if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then + reveal_item(playername, itemstack:get_name()) + end +end) + +minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing) + if user == nil then return end + local playername = user:get_player_name() + if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then + reveal_item(playername, itemstack:get_name()) + if replace_with_item ~= nil then + reveal_item(playername, replace_with_item) + end + end +end) + +minetest.register_on_joinplayer(function(player) + reveal_items_in_inventory(player) +end) + +--[[ Periodically check all items in player inventory and reveal them all. +TODO: Check whether there's a serious performance impact on servers with many players. +TODO: If possible, try to replace this functionality by updating the revealed items as + soon the player obtained a new item (probably needs new Minetest callbacks). ]] +local checktime = 8 +local timer = 0 +minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer > checktime then + local players = minetest.get_connected_players() + for p=1, #players do + reveal_items_in_inventory(players[p]) + end + + timer = math.fmod(timer, checktime) + end +end) + +minetest.after(0, gather_descs) diff --git a/mods/doc_modpack/doc_items/locale/de.txt b/mods/doc_modpack/doc_items/locale/de.txt new file mode 100644 index 0000000..3c6b94a --- /dev/null +++ b/mods/doc_modpack/doc_items/locale/de.txt @@ -0,0 +1,139 @@ +\sUsing it as fuel turns it into: @1. = \sWird dieser Gegenstand als Brennstoff verwendet, verwandelt er sich zu: @1. +@1 seconds = @1 Sekunden +# Item count times item name +@1×@2 = @1×@2 +# Itemname (25%) +@1 (@2%) = @1 (@2%) +# Itemname (<0.5%) +@1 (<0.5%) = @1 (<0,5%) +# Itemname (ca. 25%) +@1 (ca. @2%) = @1 (ca. @2%) +# List separator (e.g. “one, two, threeâ€) +,\s = ,\s +# Final list separator (e.g. “One, two and threeâ€) +\sand\s = \sund\s +1 second = 1 Sekunde +A transparent block, basically empty space. It is usually left behind after digging something. = Ein transparenter Block, praktisch leerer Raum. Er wird üblicherweise hinterlassen, nachdem man etwas ausgegraben hat. +Air = Luft +Blocks = Blöcke +Building another block at this block will place it inside and replace it. = Wird ein anderer Block an diesem Block gebaut, wird dieser andere Block seine Stelle einnehmen. +Building this block is completely silent. = Das Bauen dieses Blocks ist völlig lautlos. +Collidable: @1 = Kollidiert: @1 +Description: @1 = Beschreibung: @1 +Falling blocks can go through this block; they destroy it when doing so. = Fallende Blöcke können diesen Block durchdringen; sie zerstören ihn dabei. +Full punch interval: @1 s = Schlagintervall: @1 s +Hand = Hand +Hold it in your hand, then leftclick to eat it. = Halten Sie es in Ihrer Hand, dann klicken Sie mit der linken Maustaste, um es zu essen. +Hold it in your hand, then leftclick to eat it. But why would you want to do this? = Halten Sie es in Ihrer Hand, dann klicken Sie mit der linken Maustaste, um es zu essen. Aber warum sollten Sie das tun wollen? +Item reference of all wieldable tools and weapons = Gegenstandsreferenz aller tragbaren Werkzeugen und Waffen +Item reference of blocks and other things which are capable of occupying space = Gegenstandsreferenz aller Blöcke und anderen Dingen, die Raum belegen +Item reference of items which are neither blocks, tools or weapons (esp. crafting items) = Gegenstandsreferenz aller Gegenstände, welche weder Blöcke, Werkzeuge oder Waffen sind (insb. Fertigungsgegenstände) +Liquids can flow into this block and destroy it. = Flüssigkeiten können in diesen Block hereinfließen und ihn zerstören. +Maximum stack size: @1 = Maximale Stapelgröße: @1 +Mining level: @1 = Grabestufe: @1 +Mining ratings: = Grabewertungen: +• @1, rating @2: @3 s - @4 s = • @1, Wertung @2: @3 s - @4 s +• @1, rating @2: @3 s = • @1, Wertung @2: @3 s +Mining times: = Grabezeiten: +Mining this block is completely silent. = Das Abbauen dieses Blocks ist völlig lautlos. +Miscellaneous items = Sonstige Gegenstände +No = Nein +Pointable: No = Zeigbar: Nein +Pointable: Only by special items = Zeigbar: Nur von besonderen Gegenständen +Pointable: Yes = Zeigbar: Ja +Punches with this block don't work as usual; melee combat and mining are either not possible or work differently. = Schläge mit diesem Block funktionieren nicht auf die übliche Weise; Nahkampf und Graben sind damit entweder nicht möglich oder funktionieren auf andere Weise. +Punches with this item don't work as usual; melee combat and mining are either not possible or work differently. = Schläge mit diesem Gegenstand funktionieren nicht auf die übliche Weise; Nahkampf und Graben sind damit entweder nicht möglich oder funktionieren auf andere Weise. +Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently. = Schläge mit diesem Werkzeug funktionieren nicht auf die übliche Weise; Nahkampf und Graben sind damit entweder nicht möglich oder funktionieren auf andere Weise. +Range: @1 = Reichweite: @1 +# Range: () +Range: @1 (@2) = Reichweite: @1 (@2) +Range: 4 = Reichweite: 4 +# Rating used for digging times +Rating @1 = Wertung @1 +Rating @1-@2 = Wertung @1-@2 +The fall damage on this block is increased by @1%. = Der Fallschaden auf diesem Block ist um @1% erhöht. +The fall damage on this block is reduced by @1%. = Der Fallschaden auf diesem Block ist um @1% reduziert. +This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly. = Dieser Block ist lichtdurchlässig mit einen geringfügigen Helligkeitsverlust; Sonnenlicht passiert jedoch ohne Verlust. +This block allows light to propagate with a small loss of brightness. = Dieser Block ist lichtdurchlässig mit einen geringfügigen Helligkeitsverlust. +This block allows sunlight to propagate without loss in brightness. = Dieser Block ist vollkommen durchlässig für Sonnenlicht. +This block belongs to the @1 group. = Dieser Block gehört zur Gruppe »@1«. +This block belongs to these groups: @1. = Dieser Block gehört zu den folgenden Gruppen: @1. +This block can be climbed. = Dieser Block kann beklettert werden. +This block can be destroyed by any mining tool immediately. = Dieser Block kann von einem beliebigen Grabewerkzeug sofort zerstört werden. +This block can be destroyed by any mining tool in half a second. = Dieser Block kann von einem beliebigen Grabewerkzeug in einer halben Sekunde zerstört werden. +This block can be mined by any mining tool immediately. = Dieser Block kann von einem beliebigen Grabewerkzeug sofort abgebaut werden. +This block can be mined by any mining tool in half a second. = Dieser Block kann von einem beliebigen Grabewerkzeug in einer halben Sekunde abgebaut werden. +This block can be mined by mining tools which match any of the following mining ratings and its toughness level. = Dieser Block kann von Grabewerkzeugen abgebaut werden, falls sie auf eine der folgenden Grabewertungen sowie seinem Härtegrad passen. +This block can not be destroyed by ordinary mining tools. = Dieser Block kann nicht von Grabewerkzeugen zerstört werden. +This block can not be mined by ordinary mining tools. = Dieser Block kann nicht von gewöhnlichen Grabewerkzeugen abgebaut werden. +This block can serve as a smelting fuel with a burning time of @1. = Dieser Block kann als Brennstoff mit einer Brenndauer von @1 dienen. +This block causes a damage of @1 hit point per second. = Dieser Block richtet einen Schaden von @1 Trefferpunkt pro Sekunde an. +This block causes a damage of @1 hit points per second. = Dieser Block richtet einen Schaden von @1 Trefferpunkten pro Sekunde an. +This block connects to blocks of the @1 group. = Dieser Block verbindet sich mit Blöcken der Gruppe »@1«. +This block connects to blocks of the following groups: @1. = Dieser Block verbindet sich mit Blöcken der folgenden Gruppen: @1. +This block connects to these blocks: @1. = Dieser Block verbindet sich mit den folgenden Blöcken: @1. +This block connects to this block: @1. = Dieser Block verbindet sich mit diesem Block: @1. +This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds. = Dieser Block reduziert Ihren Atem und verursacht beim Ertrinken einen Schaden von @1 Trefferpunkt alle 2 Sekunden. +This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds. = Dieser Block reduziert Ihren Atem und verursacht beim Ertrinken einen Schaden von @1 Trefferpunkten alle 2 Sekunden. +This block glows faintly. It is barely noticable. = Dieser Block leuchtet schwach. Es ist kaum merklich. +This block is a light source with a light level of @1. = Dieser Block ist eine Lichtquelle mit einer Helligkeitsstufe von @1. +This block glows faintly with a light level of @1. = Dieser Block leuchtet schwach mit einer Helligkeitsstufe von @1. +This block is a building block for creating various buildings. = Dieser Block ist für den Bau diverser Gebäude vorgesehen. +This block is a liquid with these properties: = Dieser Block ist eine Flüssigkeit mit folgenden Eigenschaften: +This block is affected by gravity and can fall. = Dieser Block wird von der Schwerkraft beeinflusst und kann fallen. +This block is completely silent when mined or built. = Dieser Block kann vollkommen lautlos gebaut oder abgebaut werden. +This block is completely silent when walked on, mined or built. = Es ist vollkommen lautlos, wenn man auf diesen Block geht, ihn baut oder abbaut. +This block is destroyed when a falling block ends up inside it. = Dieser Block wird zerstört, wenn ein fallender Block in ihm landet. +This block negates all fall damage. = Auf diesem Block gibt es keinen Fallschaden. +This block points to liquids. = Mit diesem Block zeigt man auf Flüssigkeiten. +This block will drop as an item when a falling block ends up inside it. = Dieser Block wird sich als Gegenstand abwerfen, wenn ein fallender Block in ihn landet. +This block will drop as an item when it is not attached to a surrounding block. = Dieser Block wird sich als Gegenstand abwerfen, wenn er nicht an einen benachbarten Block befestigt ist. +This block will drop as an item when no collidable block is below it. = Dieser Block wird sich als Gegenstand abwerfen, wenn kein kollidierender Block unter ihn liegt. +This block will drop the following items when mined: %s. = Dieser Block wird nach dem Abbauen die folgenden Gegenstände abwerfen: %s. +This block will drop the following when mined: @1×@2. = Dieser Block wird nach dem Abbauen folgendes abwerfen: @1×@2. +This block will drop the following when mined: @1. = Dieser Block wird nach dem Abbauen folgendes abwerfen: @1. +This block will drop the following when mined: %s. = Dieser Block wird nach dem Abbauen folgendes abwerfen: %s. +This block will make you bounce off with an elasticity of @1%. = Dieser Block wird Sie mit einer Elastizität von @1% abprallen lassen. +This block will randomly drop one of the following when mined: %s. = Dieser Block wird nach dem Abbauen zufällig eines von den folgenden Dingen abwerfen: %s. +This block will randomly drop up to %d drops of the following possible drops when mined: %s. = Dieser Block nach dem Abbauen wird zufällig bis zu %d Abwürfe von den folgenden möglichen Abwürfen abwerfen: %s. +This block won't drop anything when mined. = Dieser Block wird nach dem Abbauen nichts abwerfen. +This is a decorational block. = Dieser Block dient zur Dekoration. +This is a melee weapon which deals damage by punching. = Dies ist eine Nahkampfwaffe, welche Schaden durch Schläge verursacht. +Maximum damage per hit: = Maximaler Schaden pro Treffer: +This item belongs to the @1 group. = Dieser Gegenstand gehört zur Gruppe »@1«. +This item belongs to these groups: @1. = Dieser Gegenstand gehört zu den folgenden Gruppen: @1. +This item can serve as a smelting fuel with a burning time of @1. = Dieser Gegenstand kann als Brennstoff mit einer Brenndauer von @1 dienen. +This item is primarily used for crafting other items. = Dieser Gegenstand wird primär für die Fertigung von anderen Gegenständen benutzt. +This item points to liquids. = Mit diesem Gegenstand zeigt man auf Flüssigkeiten. +This tool belongs to the @1 group. = Dieses Werkzeug gehört zur Gruppe »@1«. +This tool belongs to these groups: @1. = Dieses Werkzeug gehört zu den folgenden Gruppen: @1. +This tool can serve as a smelting fuel with a burning time of @1. = Dieses Werkzeug kann als Brennstoff mit einer Brenndauer von @1 dienen. +This tool is capable of mining. = Dies ist ein Grabewerkzeug. +Maximum toughness levels: = Maximale Härtegrade: +This tool points to liquids. = Mit diesem Werkzeug zeigt man auf Flüssigkeiten. +Tools and weapons = Werkzeuge und Waffen +Unknown Node = Unbekannter Node +Usage help: @1 = Benutzung: @1 +Walking on this block is completely silent. = Auf diesem Block sind Schritte lautlos. +Whenever you are not wielding any item, you use the hand which acts as a tool with its own capabilities. When you are wielding an item which is not a mining tool or a weapon it will behave as if it would be the hand. = Wenn Sie keinen Gegenstand halten, benutzen Sie die Hand, welches als ein Werkzeug mit seinen eigenen Fägihkeiten dient. Wenn Sie einen Gegenstand halten, der kein Grabewerkzeug oder eine Waffe ist, wird er sich verhalten als wäre er die Hand. +Yes = Ja +You can not jump while standing on this block. = Man kann von diesem Block nicht abspringen. +any level = beliebige Stufe +level 0 = Stufe 0 +level 0-@1 = Stufen 0-@1 +unknown = unbekannt +Unknown item (@1) = Unbekannter Gegenstand (@1) +• @1: @2 = • @1: @2 +• @1: @2 HP = • @1: @2 TP +• @1: @2, @3 = • @1: @2, @3 +• Flowing range: @1 = • Fließweite: @1 +• No flowing = • Kein Fließen +• Not renewable = • Nicht erneuerbar +• Renewable = • Erneuerbar +• Viscosity: @1 = • Zähflüssigkeit: @1 +Itemstring: "@1" = Itemstring: »@1« +Durability: @1 uses = Haltbarkeit: @1 Benutzungen +Durability: @1 = Haltbarkeit: @1 +Mining durability: = Grabehaltbarkeit: +• @1, level @2: @3 uses = • @1, Stufe @2: @3 Benutzungen +• @1, level @2: Unlimited = • @1, Stufe @2: Unbegrenzt diff --git a/mods/doc_modpack/doc_items/locale/template.txt b/mods/doc_modpack/doc_items/locale/template.txt new file mode 100644 index 0000000..0de5c3a --- /dev/null +++ b/mods/doc_modpack/doc_items/locale/template.txt @@ -0,0 +1,139 @@ +\sUsing it as fuel turns it into: @1. = +@1 seconds = +# Item count times item name +%@1×@2 = +# Itemname (25%) +@1 (@2%) = +# Itemname (<0.5%) +@1 (<0.5%) = +# Itemname (ca. 25%) +@1 (ca. @2%) = +# List separator (e.g. “one, two, threeâ€) +,\s = +# Final list separator (e.g. “One, two and threeâ€) +\sand\s = +1 second = +A transparent block, basically empty space. It is usually left behind after digging something. = +Air = +Blocks = +Building another block at this block will place it inside and replace it. = +Building this block is completely silent. = +Collidable: @1 = +Description: @1 = +Falling blocks can go through this block; they destroy it when doing so. = +Full punch interval: @1 s = +Hand = +Hold it in your hand, then leftclick to eat it. = +Hold it in your hand, then leftclick to eat it. But why would you want to do this? = +Item reference of all wieldable tools and weapons = +Item reference of blocks and other things which are capable of occupying space = +Item reference of items which are neither blocks, tools or weapons (esp. crafting items) = +Liquids can flow into this block and destroy it. = +Maximum stack size: @1 = +Mining level: @1 = +Mining ratings: = +• @1, rating @2: @3 s - @4 s = +• @1, rating @2: @3 s = +Mining times: = +Mining this block is completely silent. = +Miscellaneous items = +No = +Pointable: No = +Pointable: Only by special items = +Pointable: Yes = +Punches with this block don't work as usual; melee combat and mining are either not possible or work differently. = +Punches with this item don't work as usual; melee combat and mining are either not possible or work differently. = +Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently. = +Range: @1 = +# Range: () +Range: @1 (@2) = +Range: 4 = +# Rating used for digging times +Rating @1 = +# @1 is minimal rating, @2 is maximum rating +Rating @1-@2 = +The fall damage on this block is increased by @1%. = +The fall damage on this block is reduced by @1%. = +This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly. = +This block allows light to propagate with a small loss of brightness. = +This block allows sunlight to propagate without loss in brightness. = +This block belongs to the @1 group. = +This block belongs to these groups: @1. = +This block can be climbed. = +This block can be destroyed by any mining tool immediately. = +This block can be destroyed by any mining tool in half a second. = +This block can be mined by any mining tool immediately. = +This block can be mined by any mining tool in half a second. = +This block can be mined by mining tools which match any of the following mining ratings and its toughness level. = +This block can not be destroyed by ordinary mining tools. = +This block can not be mined by ordinary mining tools. = +This block can serve as a smelting fuel with a burning time of @1. = +This block causes a damage of @1 hit point per second. = +This block causes a damage of @1 hit points per second. = +This block connects to blocks of the @1 group. = +This block connects to blocks of the following groups: @1. = +This block connects to these blocks: @1. = +This block connects to this block: @1. = +This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds. = +This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds. = +This block is a light source with a light level of @1. = +This block glows faintly with a light level of @1. = +This block is a building block for creating various buildings. = +This block is a liquid with these properties: = +This block is affected by gravity and can fall. = +This block is completely silent when mined or built. = +This block is completely silent when walked on, mined or built. = +This block is destroyed when a falling block ends up inside it. = +This block negates all fall damage. = +This block points to liquids. = +This block will drop as an item when a falling block ends up inside it. = +This block will drop as an item when it is not attached to a surrounding block. = +This block will drop as an item when no collidable block is below it. = +This block will drop the following items when mined: %s. = +This block will drop the following when mined: @1×@2. = +This block will drop the following when mined: @1. = +This block will drop the following when mined: %s. = +This block will make you bounce off with an elasticity of @1%. = +This block will randomly drop one of the following when mined: %s. = +This block will randomly drop up to %d drops of the following possible drops when mined: %s. = +This block won't drop anything when mined. = +This is a decorational block. = +This is a melee weapon which deals damage by punching. = +Maximum damage per hit: = +This item belongs to the @1 group. = +This item belongs to these groups: @1. = +This item can serve as a smelting fuel with a burning time of @1. = +This item is primarily used for crafting other items. = +This item points to liquids. = +This tool belongs to the @1 group. = +This tool belongs to these groups: @1. = +This tool can serve as a smelting fuel with a burning time of @1. = +This tool is capable of mining. = +Maximum toughness levels: = +This tool points to liquids. = +Tools and weapons = +Unknown Node = +Usage help: @1 = +Walking on this block is completely silent. = +Whenever you are not wielding any item, you use the hand which acts as a tool with its own capabilities. When you are wielding an item which is not a mining tool or a weapon it will behave as if it would be the hand. = +Yes = +You can not jump while standing on this block. = +any level = +level 0 = +level 0-@1 = +unknown = +Unknown item (@1) = +• @1: @2 = +• @1: @2 HP = +• @1: @2, @3 = +• Flowing range: @1 = +• No flowing = +• Not renewable = +• Renewable = +• Viscosity: @1 = +Itemstring: "@1" = +Durability: @1 uses = +Durability: @1 = +Mining durability: = +• @1, level @2: @3 uses = +• @1, level @2: Unlimited = diff --git a/mods/doc_modpack/doc_items/mod.conf b/mods/doc_modpack/doc_items/mod.conf new file mode 100644 index 0000000..74fa80d --- /dev/null +++ b/mods/doc_modpack/doc_items/mod.conf @@ -0,0 +1 @@ +name = doc_items diff --git a/mods/doc_modpack/doc_items/settingtypes.txt b/mods/doc_modpack/doc_items/settingtypes.txt new file mode 100644 index 0000000..8b9d635 --- /dev/null +++ b/mods/doc_modpack/doc_items/settingtypes.txt @@ -0,0 +1,16 @@ +#This feature is experimental! +#If enabled, the mod will show alternative group names which are a bit +#more readable than the internally used (but canonical) group names. For +#example, the group “wood†may be rendered as “Woodâ€, “leaves†as +#“Leaves and Needlesâ€, “oddly_breakable_by_hand†as “Hand-breakableâ€, +#and so on. Note that these alternative names are only used for better +#understanding, they are not official. +#This feature might be removed in later versions if it becomes obsolete. +doc_items_friendly_group_names (Show “friendly†group names) bool false + +#If enabled, the mod will show the itemstring of the entry for each item to +#all players. If disabled, the itemstring will only be shown to players +#with the “give†or “debug†privilege. +#The itemstring is useful to power users and programmers and +#is used e.g. for the /give and /giveme commands. +doc_items_show_itemstrings (Show itemstrings) bool false diff --git a/mods/doc_modpack/modpack.conf b/mods/doc_modpack/modpack.conf new file mode 100644 index 0000000..f126895 --- /dev/null +++ b/mods/doc_modpack/modpack.conf @@ -0,0 +1,2 @@ +name = doc +description = Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage. diff --git a/mods/doc_modpack/modpack.txt b/mods/doc_modpack/modpack.txt new file mode 100644 index 0000000..e69de29 diff --git a/mods/doors/README.txt b/mods/doors/README.txt new file mode 100644 index 0000000..f9caaff --- /dev/null +++ b/mods/doors/README.txt @@ -0,0 +1,87 @@ +Minetest Game mod: doors +======================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by PilzAdam (MIT) + +Modified by BlockMen (MIT): Added sounds, glass doors (glass, obsidian glass) and trapdoor. + +Modified by sofar (sofar@foo-projects.org) (MIT): +Added Steel trapdoor. +Re-implemented most of the door algorithms, added meshes, UV wrapped texture. +Added doors API to facilitate coding mods accessing and operating doors. +Added Fence Gate model, code, and sounds. + +Various Minetest developers and contributors (MIT) + + +Authors of media (textures) +--------------------------- +Following textures created by Fernando Zapata (CC BY-SA 3.0): + door_wood.png + door_wood_a.png + door_wood_a_r.png + door_wood_b.png + door_wood_b_r.png + +Following textures created by BlockMen (CC BY-SA 3.0): + door_trapdoor.png + door_obsidian_glass_side.png + +Following textures created by celeron55 (CC BY-SA 3.0): + door_glass_a.png + door_glass_b.png + +Following textures created by PenguinDad (CC BY-SA 4.0): + door_glass.png + door_obsidian_glass.png + +Following textures created by sofar (CC-BY-SA-3.0): + doors_trapdoor_steel.png + +Following textures created by paramat (CC-BY-SA-3.0): + door_trapdoor_side.png + doors_trapdoor_steel_side.png + +Obsidian door textures by red-001 based on textures by Pilzadam and BlockMen (CC BY-SA 3.0): + door_obsidian_glass.png + +Glass door textures by Krock and paramat based on textures by VanessaE (CC BY-SA 3.0): + doors_door_glass.png + doors_item_glass.png + +All other textures (created by PilzAdam) (CC BY-SA 3.0): + +Door textures were converted to the new texture map by sofar, paramat and +red-001, under the same license as the originals. + + +Authors of media (models) +------------------------- +Door 3d models by sofar (CC-BY-SA-3.0) + - door_a.obj + - door_b.obj +Fence gate models by sofar (CC-BY-SA-3.0) + - fencegate_open.obj + - fencegate_closed.obj + + +Authors of media (sounds) +------------------------- +Opening-Sound created by CGEffex (CC BY 3.0), modified by BlockMen + door_open.ogg +Closing-Sound created by bennstir (CC BY 3.0) + door_close.ogg +fencegate_open.ogg: + http://www.freesound.org/people/mhtaylor67/sounds/126041/ - (CC0 1.0) +fencegate_close.ogg: + http://www.freesound.org/people/BarkersPinhead/sounds/274807/ - (CC-BY-3.0) + http://www.freesound.org/people/rivernile7/sounds/249573/ - (CC-BY-3.0) +Steel door sounds open & close (CC-BY-3.0) by HazMatt + - http://www.freesound.org/people/HazMattt/sounds/187283/ + doors_steel_door_open.ogg + doors_steel_door_close.ogg +doors_glass_door_open.ogg, doors_glass_door_close.ogg: + https://www.freesound.org/people/SkeetMasterFunk69/sounds/235546/ (CC0 1.0) diff --git a/mods/doors/init.lua b/mods/doors/init.lua new file mode 100644 index 0000000..2048a64 --- /dev/null +++ b/mods/doors/init.lua @@ -0,0 +1,882 @@ +-- doors/init.lua + +-- our API object +doors = {} + +doors.registered_doors = {} +doors.registered_trapdoors = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("doors") + + +local function replace_old_owner_information(pos) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("doors_owner") + if owner and owner ~= "" then + meta:set_string("owner", owner) + meta:set_string("doors_owner", "") + end +end + +-- returns an object to a door object or nil +function doors.get(pos) + local node_name = minetest.get_node(pos).name + if doors.registered_doors[node_name] then + -- A normal upright door + return { + pos = pos, + open = function(self, player) + if self:state() then + return false + end + return doors.door_toggle(self.pos, nil, player) + end, + close = function(self, player) + if not self:state() then + return false + end + return doors.door_toggle(self.pos, nil, player) + end, + toggle = function(self, player) + return doors.door_toggle(self.pos, nil, player) + end, + state = function(self) + local state = minetest.get_meta(self.pos):get_int("state") + return state %2 == 1 + end + } + elseif doors.registered_trapdoors[node_name] then + -- A trapdoor + return { + pos = pos, + open = function(self, player) + if self:state() then + return false + end + return doors.trapdoor_toggle(self.pos, nil, player) + end, + close = function(self, player) + if not self:state() then + return false + end + return doors.trapdoor_toggle(self.pos, nil, player) + end, + toggle = function(self, player) + return doors.trapdoor_toggle(self.pos, nil, player) + end, + state = function(self) + return minetest.get_node(self.pos).name:sub(-5) == "_open" + end + } + else + return nil + end +end + +-- this hidden node is placed on top of the bottom, and prevents +-- nodes from being placed in the top half of the door. +minetest.register_node("doors:hidden", { + description = S("Hidden Door Segment"), + drawtype = "airlike", + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + -- has to be walkable for falling nodes to stop falling. + walkable = true, + pointable = false, + diggable = false, + buildable_to = false, + floodable = false, + drop = "", + groups = {not_in_creative_inventory = 1}, + on_blast = function() end, + -- 1px block inside door hinge near node top + collision_box = { + type = "fixed", + fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32}, + }, +}) + +-- table used to aid door opening/closing +local transform = { + { + {v = "_a", param2 = 3}, + {v = "_a", param2 = 0}, + {v = "_a", param2 = 1}, + {v = "_a", param2 = 2}, + }, + { + {v = "_c", param2 = 1}, + {v = "_c", param2 = 2}, + {v = "_c", param2 = 3}, + {v = "_c", param2 = 0}, + }, + { + {v = "_b", param2 = 1}, + {v = "_b", param2 = 2}, + {v = "_b", param2 = 3}, + {v = "_b", param2 = 0}, + }, + { + {v = "_d", param2 = 3}, + {v = "_d", param2 = 0}, + {v = "_d", param2 = 1}, + {v = "_d", param2 = 2}, + }, +} + +function doors.door_toggle(pos, node, clicker) + local meta = minetest.get_meta(pos) + node = node or minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + local name = def.door.name + + local state = meta:get_string("state") + if state == "" then + -- fix up lvm-placed right-hinged doors, default closed + if node.name:sub(-2) == "_b" then + state = 2 + else + state = 0 + end + else + state = tonumber(state) + end + + replace_old_owner_information(pos) + + if clicker and not default.can_interact_with_node(clicker, pos) then + return false + end + + -- until Lua-5.2 we have no bitwise operators :( + if state % 2 == 1 then + state = state - 1 + else + state = state + 1 + end + + local dir = node.param2 + + -- It's possible param2 is messed up, so, validate before using + -- the input data. This indicates something may have rotated + -- the door, even though that is not supported. + if not transform[state + 1] or not transform[state + 1][dir + 1] then + return false + end + + if state % 2 == 0 then + minetest.sound_play(def.door.sounds[1], + {pos = pos, gain = 0.3, max_hear_distance = 10}, true) + else + minetest.sound_play(def.door.sounds[2], + {pos = pos, gain = 0.3, max_hear_distance = 10}, true) + end + + minetest.swap_node(pos, { + name = name .. transform[state + 1][dir+1].v, + param2 = transform[state + 1][dir+1].param2 + }) + meta:set_int("state", state) + + return true +end + + +local function on_place_node(place_to, newnode, + placer, oldnode, itemstack, pointed_thing) + -- Run script hook + for _, callback in ipairs(minetest.registered_on_placenodes) do + -- Deepcopy pos, node and pointed_thing because callback can modify them + local place_to_copy = {x = place_to.x, y = place_to.y, z = place_to.z} + local newnode_copy = + {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2} + local oldnode_copy = + {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2} + local pointed_thing_copy = { + type = pointed_thing.type, + above = vector.new(pointed_thing.above), + under = vector.new(pointed_thing.under), + ref = pointed_thing.ref, + } + callback(place_to_copy, newnode_copy, placer, + oldnode_copy, itemstack, pointed_thing_copy) + end +end + +local function can_dig_door(pos, digger) + replace_old_owner_information(pos) + return default.can_interact_with_node(digger, pos) +end + +function doors.register(name, def) + if not name:find(":") then + name = "doors:" .. name + end + + -- replace old doors of this type automatically + minetest.register_lbm({ + name = ":doors:replace_" .. name:gsub(":", "_"), + nodenames = {name.."_b_1", name.."_b_2"}, + action = function(pos, node) + local l = tonumber(node.name:sub(-1)) + local meta = minetest.get_meta(pos) + local h = meta:get_int("right") + 1 + local p2 = node.param2 + local replace = { + {{type = "a", state = 0}, {type = "a", state = 3}}, + {{type = "b", state = 1}, {type = "b", state = 2}} + } + local new = replace[l][h] + -- retain infotext and doors_owner fields + minetest.swap_node(pos, {name = name .. "_" .. new.type, param2 = p2}) + meta:set_int("state", new.state) + -- properly place doors:hidden at the right spot + local p3 = p2 + if new.state >= 2 then + p3 = (p3 + 3) % 4 + end + if new.state % 2 == 1 then + if new.state >= 2 then + p3 = (p3 + 1) % 4 + else + p3 = (p3 + 3) % 4 + end + end + -- wipe meta on top node as it's unused + minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, + {name = "doors:hidden", param2 = p3}) + end + }) + + minetest.register_craftitem(":" .. name, { + description = def.description, + inventory_image = def.inventory_image, + groups = table.copy(def.groups), + + on_place = function(itemstack, placer, pointed_thing) + local pos + + if not pointed_thing.type == "node" then + return itemstack + end + + local node = minetest.get_node(pointed_thing.under) + local pdef = minetest.registered_nodes[node.name] + if pdef and pdef.on_rightclick and + not (placer and placer:is_player() and + placer:get_player_control().sneak) then + return pdef.on_rightclick(pointed_thing.under, + node, placer, itemstack, pointed_thing) + end + + if pdef and pdef.buildable_to then + pos = pointed_thing.under + else + pos = pointed_thing.above + node = minetest.get_node(pos) + pdef = minetest.registered_nodes[node.name] + if not pdef or not pdef.buildable_to then + return itemstack + end + end + + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local top_node = minetest.get_node_or_nil(above) + local topdef = top_node and minetest.registered_nodes[top_node.name] + + if not topdef or not topdef.buildable_to then + return itemstack + end + + local pn = placer and placer:get_player_name() or "" + if minetest.is_protected(pos, pn) or minetest.is_protected(above, pn) then + return itemstack + end + + local dir = placer and minetest.dir_to_facedir(placer:get_look_dir()) or 0 + + local ref = { + {x = -1, y = 0, z = 0}, + {x = 0, y = 0, z = 1}, + {x = 1, y = 0, z = 0}, + {x = 0, y = 0, z = -1}, + } + + local aside = { + x = pos.x + ref[dir + 1].x, + y = pos.y + ref[dir + 1].y, + z = pos.z + ref[dir + 1].z, + } + + local state = 0 + if minetest.get_item_group(minetest.get_node(aside).name, "door") == 1 then + state = state + 2 + minetest.set_node(pos, {name = name .. "_b", param2 = dir}) + minetest.set_node(above, {name = "doors:hidden", param2 = (dir + 3) % 4}) + else + minetest.set_node(pos, {name = name .. "_a", param2 = dir}) + minetest.set_node(above, {name = "doors:hidden", param2 = dir}) + end + + local meta = minetest.get_meta(pos) + meta:set_int("state", state) + + if def.protected then + meta:set_string("owner", pn) + meta:set_string("infotext", def.description .. "\n" .. S("Owned by @1", pn)) + end + + if not (creative and creative.is_enabled_for and creative.is_enabled_for(pn)) then + itemstack:take_item() + end + + minetest.sound_play(def.sounds.place, {pos = pos}, true) + + on_place_node(pos, minetest.get_node(pos), + placer, node, itemstack, pointed_thing) + + return itemstack + end + }) + def.inventory_image = nil + + if def.recipe then + minetest.register_craft({ + output = name, + recipe = def.recipe, + }) + end + def.recipe = nil + + if not def.sounds then + def.sounds = default.node_sound_wood_defaults() + end + + if not def.sound_open then + def.sound_open = "doors_door_open" + end + + if not def.sound_close then + def.sound_close = "doors_door_close" + end + + def.groups.not_in_creative_inventory = 1 + def.groups.door = 1 + def.drop = name + def.door = { + name = name, + sounds = { def.sound_close, def.sound_open }, + } + if not def.on_rightclick then + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + doors.door_toggle(pos, node, clicker) + return itemstack + end + end + def.after_dig_node = function(pos, node, meta, digger) + 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 = function(pos, node, user, mode, new_param2) + return false + end + + if def.protected then + def.can_dig = can_dig_door + def.on_blast = function() end + def.on_key_use = function(pos, player) + local door = doors.get(pos) + door:toggle(player) + end + def.on_skeleton_key_use = function(pos, player, newsecret) + replace_old_owner_information(pos) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local pname = player:get_player_name() + + -- verify placer is owner of lockable door + if owner ~= pname then + minetest.record_protection_violation(pos, pname) + minetest.chat_send_player(pname, S("You do not own this locked door.")) + return nil + end + + local secret = meta:get_string("key_lock_secret") + if secret == "" then + secret = newsecret + meta:set_string("key_lock_secret", secret) + end + + return secret, S("a locked door"), owner + end + def.node_dig_prediction = "" + else + def.on_blast = function(pos, intensity) + minetest.remove_node(pos) + -- hidden node doesn't get blasted away. + minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) + return {name} + end + end + + def.on_destruct = function(pos) + minetest.remove_node({x = pos.x, y = pos.y + 1, z = pos.z}) + end + + def.drawtype = "mesh" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.sunlight_propagates = true + def.walkable = true + def.is_ground_content = false + def.buildable_to = false + def.selection_box = {type = "fixed", fixed = {-1/2,-1/2,-1/2,1/2,3/2,-6/16}} + def.collision_box = {type = "fixed", fixed = {-1/2,-1/2,-1/2,1/2,3/2,-6/16}} + + def.mesh = "door_a.obj" + minetest.register_node(":" .. name .. "_a", def) + + def.mesh = "door_b.obj" + minetest.register_node(":" .. name .. "_b", def) + + def.mesh = "door_a2.obj" + minetest.register_node(":" .. name .. "_c", def) + + def.mesh = "door_b2.obj" + minetest.register_node(":" .. name .. "_d", def) + + doors.registered_doors[name .. "_a"] = true + doors.registered_doors[name .. "_b"] = true + doors.registered_doors[name .. "_c"] = true + doors.registered_doors[name .. "_d"] = true +end + +doors.register("door_wood", { + tiles = {{ name = "doors_door_wood.png", backface_culling = true }}, + description = S("Wooden Door"), + inventory_image = "doors_item_wood.png", + groups = {node = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 2}, + recipe = { + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"}, + } +}) + +doors.register("door_steel", { + tiles = {{name = "doors_door_steel.png", backface_culling = true}}, + description = S("Steel Door"), + inventory_image = "doors_item_steel.png", + protected = true, + groups = {node = 1, cracky = 1, level = 2}, + sounds = default.node_sound_metal_defaults(), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + recipe = { + {"default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot"}, + } +}) + +doors.register("door_glass", { + tiles = {"doors_door_glass.png"}, + description = S("Glass Door"), + inventory_image = "doors_item_glass.png", + groups = {node = 1, cracky=3, oddly_breakable_by_hand=3}, + sounds = default.node_sound_glass_defaults(), + sound_open = "doors_glass_door_open", + sound_close = "doors_glass_door_close", + recipe = { + {"default:glass", "default:glass"}, + {"default:glass", "default:glass"}, + {"default:glass", "default:glass"}, + } +}) + +doors.register("door_obsidian_glass", { + tiles = {"doors_door_obsidian_glass.png"}, + description = S("Obsidian Glass Door"), + inventory_image = "doors_item_obsidian_glass.png", + groups = {node = 1, cracky=3}, + sounds = default.node_sound_glass_defaults(), + sound_open = "doors_glass_door_open", + sound_close = "doors_glass_door_close", + recipe = { + {"default:obsidian_glass", "default:obsidian_glass"}, + {"default:obsidian_glass", "default:obsidian_glass"}, + {"default:obsidian_glass", "default:obsidian_glass"}, + }, +}) + +-- Capture mods using the old API as best as possible. +function doors.register_door(name, def) + if def.only_placer_can_open then + def.protected = true + end + def.only_placer_can_open = nil + + local i = name:find(":") + local modname = name:sub(1, i - 1) + if not def.tiles then + if def.protected then + def.tiles = {{name = "doors_door_steel.png", backface_culling = true}} + else + def.tiles = {{name = "doors_door_wood.png", backface_culling = true}} + end + minetest.log("warning", modname .. " registered door \"" .. name .. "\" " .. + "using deprecated API method \"doors.register_door()\" but " .. + "did not provide the \"tiles\" parameter. A fallback tiledef " .. + "will be used instead.") + end + + doors.register(name, def) +end + +----trapdoor---- + +function doors.trapdoor_toggle(pos, node, clicker) + node = node or minetest.get_node(pos) + + replace_old_owner_information(pos) + + if clicker and not default.can_interact_with_node(clicker, pos) then + return false + end + + local def = minetest.registered_nodes[node.name] + + if string.sub(node.name, -5) == "_open" then + minetest.sound_play(def.sound_close, + {pos = pos, gain = 0.3, max_hear_distance = 10}, true) + minetest.swap_node(pos, {name = string.sub(node.name, 1, + string.len(node.name) - 5), param1 = node.param1, param2 = node.param2}) + else + minetest.sound_play(def.sound_open, + {pos = pos, gain = 0.3, max_hear_distance = 10}, true) + minetest.swap_node(pos, {name = node.name .. "_open", + param1 = node.param1, param2 = node.param2}) + end +end + +function doors.register_trapdoor(name, def) + if not name:find(":") then + name = "doors:" .. name + end + + local name_closed = name + local name_opened = name.."_open" + + def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + doors.trapdoor_toggle(pos, node, clicker) + return itemstack + end + + -- Common trapdoor configuration + def.drawtype = "nodebox" + def.paramtype = "light" + def.paramtype2 = "facedir" + def.is_ground_content = false + + if def.protected then + def.can_dig = can_dig_door + def.after_place_node = function(pos, placer, itemstack, pointed_thing) + local pn = placer:get_player_name() + local meta = minetest.get_meta(pos) + meta:set_string("owner", pn) + meta:set_string("infotext", def.description .. "\n" .. S("Owned by @1", pn)) + + return (creative and creative.is_enabled_for and creative.is_enabled_for(pn)) + end + + def.on_blast = function() end + def.on_key_use = function(pos, player) + local door = doors.get(pos) + door:toggle(player) + end + def.on_skeleton_key_use = function(pos, player, newsecret) + replace_old_owner_information(pos) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local pname = player:get_player_name() + + -- verify placer is owner of lockable door + if owner ~= pname then + minetest.record_protection_violation(pos, pname) + minetest.chat_send_player(pname, S("You do not own this trapdoor.")) + return nil + end + + local secret = meta:get_string("key_lock_secret") + if secret == "" then + secret = newsecret + meta:set_string("key_lock_secret", secret) + end + + return secret, S("a locked trapdoor"), owner + end + def.node_dig_prediction = "" + else + def.on_blast = function(pos, intensity) + minetest.remove_node(pos) + return {name} + end + end + + if not def.sounds then + def.sounds = default.node_sound_wood_defaults() + end + + if not def.sound_open then + def.sound_open = "doors_door_open" + end + + if not def.sound_close then + def.sound_close = "doors_door_close" + end + + local def_opened = table.copy(def) + local def_closed = table.copy(def) + + def_closed.node_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5} + } + def_closed.selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5} + } + def_closed.tiles = { + def.tile_front, + def.tile_front .. '^[transformFY', + def.tile_side, + def.tile_side, + def.tile_side, + def.tile_side + } + + def_opened.node_box = { + type = "fixed", + fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5} + } + def_opened.selection_box = { + type = "fixed", + fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5} + } + def_opened.tiles = { + def.tile_side, + def.tile_side .. '^[transform2', + def.tile_side .. '^[transform3', + def.tile_side .. '^[transform1', + def.tile_front .. '^[transform46', + def.tile_front .. '^[transform6' + } + + def_opened.drop = name_closed + def_opened.groups.not_in_creative_inventory = 1 + + minetest.register_node(name_opened, def_opened) + minetest.register_node(name_closed, def_closed) + + doors.registered_trapdoors[name_opened] = true + doors.registered_trapdoors[name_closed] = true +end + +doors.register_trapdoor("doors:trapdoor", { + description = S("Wooden Trapdoor"), + inventory_image = "doors_trapdoor.png", + wield_image = "doors_trapdoor.png", + tile_front = "doors_trapdoor.png", + tile_side = "doors_trapdoor_side.png", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2, door = 1}, +}) + +doors.register_trapdoor("doors:trapdoor_steel", { + description = S("Steel Trapdoor"), + inventory_image = "doors_trapdoor_steel.png", + wield_image = "doors_trapdoor_steel.png", + tile_front = "doors_trapdoor_steel.png", + tile_side = "doors_trapdoor_steel_side.png", + protected = true, + sounds = default.node_sound_metal_defaults(), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + groups = {cracky = 1, level = 2, door = 1}, +}) + +minetest.register_craft({ + output = "doors:trapdoor 2", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + {"", "", ""}, + } +}) + +minetest.register_craft({ + output = "doors:trapdoor_steel", + recipe = { + {"default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot"}, + } +}) + + +----fence gate---- +local fence_collision_extra = minetest.settings:get_bool("enable_fence_tall") and 3/8 or 0 + +function doors.register_fencegate(name, def) + local fence = { + description = def.description, + drawtype = "mesh", + tiles = {}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + is_ground_content = false, + drop = name .. "_closed", + connect_sides = {"left", "right"}, + groups = def.groups, + sounds = def.sounds, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local node_def = minetest.registered_nodes[node.name] + minetest.swap_node(pos, {name = node_def.gate, param2 = node.param2}) + minetest.sound_play(node_def.sound, {pos = pos, gain = 0.3, + max_hear_distance = 8}, true) + return itemstack + end, + selection_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/4, 1/2, 1/2, 1/4} + }, + } + + + if type(def.texture) == "string" then + fence.tiles[1] = {name = def.texture, backface_culling = true} + elseif def.texture.backface_culling == nil then + fence.tiles[1] = table.copy(def.texture) + fence.tiles[1].backface_culling = true + else + fence.tiles[1] = def.texture + end + + if not fence.sounds then + fence.sounds = default.node_sound_wood_defaults() + end + + fence.groups.fence = 1 + + local fence_closed = table.copy(fence) + fence_closed.mesh = "doors_fencegate_closed.obj" + fence_closed.gate = name .. "_open" + fence_closed.sound = "doors_fencegate_open" + fence_closed.collision_box = { + type = "fixed", + fixed = {-1/2, -1/2, -1/8, 1/2, 1/2 + fence_collision_extra, 1/8} + } + + local fence_open = table.copy(fence) + fence_open.mesh = "doors_fencegate_open.obj" + fence_open.gate = name .. "_closed" + fence_open.sound = "doors_fencegate_close" + fence_open.groups.not_in_creative_inventory = 1 + fence_open.collision_box = { + type = "fixed", + fixed = {{-1/2, -1/2, -1/8, -3/8, 1/2 + fence_collision_extra, 1/8}, + {-1/2, -3/8, -1/2, -3/8, 3/8, 0 }} + } + + minetest.register_node(":" .. name .. "_closed", fence_closed) + minetest.register_node(":" .. name .. "_open", fence_open) + + minetest.register_craft({ + output = name .. "_closed", + recipe = { + {"group:stick", def.material, "group:stick"}, + {"group:stick", def.material, "group:stick"} + } + }) +end + +doors.register_fencegate("doors:gate_wood", { + description = S("Apple Wood Fence Gate"), + texture = "default_wood.png", + material = "default:wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} +}) + +doors.register_fencegate("doors:gate_acacia_wood", { + description = S("Acacia Wood Fence Gate"), + texture = "default_acacia_wood.png", + material = "default:acacia_wood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} +}) + +doors.register_fencegate("doors:gate_junglewood", { + description = S("Jungle Wood Fence Gate"), + texture = "default_junglewood.png", + material = "default:junglewood", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 2} +}) + +doors.register_fencegate("doors:gate_pine_wood", { + description = S("Pine Wood Fence Gate"), + texture = "default_pine_wood.png", + material = "default:pine_wood", + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3} +}) + +doors.register_fencegate("doors:gate_aspen_wood", { + description = S("Aspen Wood Fence Gate"), + texture = "default_aspen_wood.png", + material = "default:aspen_wood", + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3} +}) + + +----fuels---- + +minetest.register_craft({ + type = "fuel", + recipe = "doors:trapdoor", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:door_wood", + burntime = 14, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_wood_closed", + burntime = 7, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_acacia_wood_closed", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_junglewood_closed", + burntime = 9, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_pine_wood_closed", + burntime = 6, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "doors:gate_aspen_wood_closed", + burntime = 5, +}) diff --git a/mods/doors/license.txt b/mods/doors/license.txt new file mode 100644 index 0000000..8ce73c4 --- /dev/null +++ b/mods/doors/license.txt @@ -0,0 +1,164 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2015-2016 sofar (sofar@foo-projects.org) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures, models and sounds) +----------------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2011-2016 Fernando Zapata +Copyright (C) 2014-2016 celeron55 +Copyright (C) 2012-2016 PilzAdam +Copyright (C) 2014-2016 BlockMen +Copyright (C) 2015-2016 sofar +Copyright (C) 2016 red-001 +Copyright (C) 2016 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ + +----------------------- + +Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) +Copyright (C) 2014-2016 PenguinDad + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/4.0/ + +----------------------- + +Attribution 3.0 Unported (CC BY 3.0) +Copyright (C) 2014 CGEffex +Copyright (C) 2014 bennstir +Copyright (C) 2016 BarkersPinhead +Copyright (C) 2016 rivernile7 +Copyright (C) 2016 HazMatt + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by/3.0/ + +----------------------- + +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication +mhtaylor67 +SkeetMasterFunk69 + +No Copyright + +The person who associated a work with this deed has dedicated the work to the public +domain by waiving all of his or her rights to the work worldwide under copyright law, +including all related and neighboring rights, to the extent allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial purposes, all +without asking permission. See Other Information below. + +Other Information + +In no way are the patent or trademark rights of any person affected by CC0, nor are the +rights that other persons may have in the work or in how the work is used, such as +publicity or privacy rights. +Unless expressly stated otherwise, the person who associated a work with this deed makes +no warranties about the work, and disclaims liability for all uses of the work, to the +fullest extent permitted by applicable law. +When using or citing the work, you should not imply endorsement by the author or the +affirmer. + +For more details: +https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/mods/doors/locale/doors.de.tr b/mods/doors/locale/doors.de.tr new file mode 100644 index 0000000..79707ce --- /dev/null +++ b/mods/doors/locale/doors.de.tr @@ -0,0 +1,18 @@ +# textdomain: doors +Hidden Door Segment=Verborgenes Türsegment +Owned by @1=Eigentum von @1 +You do not own this locked door.=Diese abgeschlossene Tür gehört Ihnen nicht. +a locked door=eine abgeschlossene Tür +Wooden Door=Holztür +Steel Door=Stahltür +Glass Door=Glastür +Obsidian Glass Door=Obsidianglastür +You do not own this trapdoor.=Diese Falltür gehört Ihnen nicht. +a locked trapdoor=eine abgeschlossene Falltür +Wooden Trapdoor=Holzfalltür +Steel Trapdoor=Stahlfalltür +Apple Wood Fence Gate=Apfelholzzauntor +Acacia Wood Fence Gate=Akazienholzzauntor +Jungle Wood Fence Gate=Dschungelholzzauntor +Pine Wood Fence Gate=Kiefernholzzauntor +Aspen Wood Fence Gate=Espenholzzauntor diff --git a/mods/doors/locale/doors.es.tr b/mods/doors/locale/doors.es.tr new file mode 100644 index 0000000..677f2df --- /dev/null +++ b/mods/doors/locale/doors.es.tr @@ -0,0 +1,18 @@ +# textdomain: doors +Hidden Door Segment=Segmento de puerta oculta +Owned by @1=Propiedad de @1 +You do not own this locked door.=Esta puerta cerrada no te pertenece. +a locked door=una puerta cerrada +Wooden Door=Puerta de madera +Steel Door=Puerta de acero +Glass Door=Puerta de vidrio +Obsidian Glass Door=Puerta de vidrio de obsidiana +You do not own this trapdoor.=Esta trampilla no te pertenece. +a locked trapdoor=una trampilla cerrada +Wooden Trapdoor=Trampilla de madera +Steel Trapdoor=Trampilla de acero +Apple Wood Fence Gate=Puerta de cerca de manzano +Acacia Wood Fence Gate=Puerta de cerca de acacia +Jungle Wood Fence Gate=Puerta de cerca de madera tropical +Pine Wood Fence Gate=Puerta de cerca de pino +Aspen Wood Fence Gate=Puerta de cerca de álamo diff --git a/mods/doors/locale/doors.fr.tr b/mods/doors/locale/doors.fr.tr new file mode 100644 index 0000000..930f75c --- /dev/null +++ b/mods/doors/locale/doors.fr.tr @@ -0,0 +1,18 @@ +# textdomain: doors +Hidden Door Segment=Segment de porte cachée +Owned by @1=Possédée par @1 +You do not own this locked door.=Cette porte vérouillée ne vous appartient pas. +a locked door=une porte verouillée +Wooden Door=Porte en bois +Steel Door=Porte en acier +Glass Door=Porte en verre +Obsidian Glass Door=Porte en verre d'obsidienne +You do not own this trapdoor.=Vous ne possédez pas cette trappe. +a locked trapdoor=une trappe verouillée +Wooden Trapdoor=Trappe en bois +Steel Trapdoor=Trappe en acier +Apple Wood Fence Gate=Porte de clôture en bois de pommier +Acacia Wood Fence Gate=Porte de clôture en bois d'acacia +Jungle Wood Fence Gate=Porte de clôture en bois de la jungle +Pine Wood Fence Gate=Porte de clôture en bois de pin +Aspen Wood Fence Gate=Porte de clôture en bois de tremble diff --git a/mods/doors/locale/doors.it.tr b/mods/doors/locale/doors.it.tr new file mode 100644 index 0000000..4a9599d --- /dev/null +++ b/mods/doors/locale/doors.it.tr @@ -0,0 +1,19 @@ +# textdomain: doors +Hidden Door Segment=Segmento di porta nascosto +Owned by @1=Di proprietà di @1 +You do not own this locked door.=Non sei il proprietario di questa porta chiusa a chiave. +a locked door=una porta chiusa a chiave +Wooden Door=Porta di legno +Steel Door=Porta d'acciaio +Glass Door=Porta di vetro +Obsidian Glass Door=Porta di vetro d'ossidiana +Owned by @1=Di proprietà di @1 +You do not own this trapdoor.=Non sei il proprietario di questa botola. +a locked trapdoor=una botola chiusa a chiave +Wooden Trapdoor=Botola di legno +Steel Trapdoor=Botola d'acciaio +Apple Wood Fence Gate=Cancello della recinzione di legno di melo +Acacia Wood Fence Gate=Cancello della recinzione di legno d'acacia +Jungle Wood Fence Gate=Cancello della recinzione di legno della giungla +Pine Wood Fence Gate=Cancello della recinzione di legno di pino +Aspen Wood Fence Gate=Cancello della recinzione di legno di pioppo diff --git a/mods/doors/locale/doors.ms.tr b/mods/doors/locale/doors.ms.tr new file mode 100644 index 0000000..93d6df2 --- /dev/null +++ b/mods/doors/locale/doors.ms.tr @@ -0,0 +1,18 @@ +# textdomain: doors +Hidden Door Segment=Segmen Pintu Tersembunyi +Owned by @1=Milik @1 +You do not own this locked door.=Anda bukan pemilik pintu berkunci ini. +a locked door=pintu berkunci +Wooden Door=Pintu Kayu +Steel Door=Pintu Keluli +Glass Door=Pintu Kaca +Obsidian Glass Door=Pintu Kaca Obsidia +You do not own this trapdoor.=Anda bukan pemilik pintu kolong ini. +a locked trapdoor=pintu kolong berkunci +Wooden Trapdoor=Pintu Kolong Kayu +Steel Trapdoor=Pintu Kolong Keluli +Apple Wood Fence Gate=Pintu Pagar Kayu Epal +Acacia Wood Fence Gate=Pintu Pagar Kayu Akasia +Jungle Wood Fence Gate=Pintu Pagar Kayu Hutan +Pine Wood Fence Gate=Pintu Pagar Kayu Pain +Aspen Wood Fence Gate=Pintu Pagar Kayu Aspen diff --git a/mods/doors/locale/doors.ru.tr b/mods/doors/locale/doors.ru.tr new file mode 100644 index 0000000..dc5c3c0 --- /dev/null +++ b/mods/doors/locale/doors.ru.tr @@ -0,0 +1,18 @@ +# textdomain: doors +Hidden Door Segment=СпрÑÑ‚Ð°Ð½Ð½Ð°Ñ Ð§Ð°ÑÑ‚ÑŒ Двери +Owned by @1=Владелец: @1 +You do not own this locked door.=Ð’Ñ‹ не владелец Ñтой заблокированной двери. +a locked door=Ð·Ð°Ð±Ð»Ð¾ÐºÐ¸Ñ€Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð´Ð²ÐµÑ€ÑŒ +Wooden Door=ДеревÑÐ½Ð½Ð°Ñ Ð”Ð²ÐµÑ€ÑŒ +Steel Door=Ð¡Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð”Ð²ÐµÑ€ÑŒ +Glass Door=СтеклÑÐ½Ð½Ð°Ñ Ð”Ð²ÐµÑ€ÑŒ +Obsidian Glass Door=Дверь Из ОбÑидианового Стекла +You do not own this trapdoor.=Ð’Ñ‹ не владелец Ñтого люка. +a locked trapdoor=заблокированный люк +Wooden Trapdoor=ДеревÑнный Люк +Steel Trapdoor=Стальной Люк +Apple Wood Fence Gate=Ð¯Ð±Ð»Ð¾Ð½ÐµÐ²Ð°Ñ Ð”ÐµÑ€ÐµÐ²ÑÐ½Ð½Ð°Ñ ÐšÐ°Ð»Ð¸Ñ‚ÐºÐ° +Acacia Wood Fence Gate=ДеревÑÐ½Ð½Ð°Ñ ÐšÐ°Ð»Ð¸Ñ‚ÐºÐ° Из Ðкации +Jungle Wood Fence Gate=ДеревÑÐ½Ð½Ð°Ñ ÐšÐ°Ð»Ð¸Ñ‚ÐºÐ° Из ТропичеÑкого Дерева +Pine Wood Fence Gate=СоÑÐ½Ð¾Ð²Ð°Ñ Ð”ÐµÑ€ÐµÐ²ÑÐ½Ð½Ð°Ñ ÐšÐ°Ð»Ð¸Ñ‚ÐºÐ° +Aspen Wood Fence Gate=ОÑÐ¸Ð½Ð¾Ð²Ð°Ñ Ð”ÐµÑ€ÐµÐ²ÑÐ½Ð½Ð°Ñ ÐšÐ°Ð»Ð¸Ñ‚ÐºÐ° diff --git a/mods/doors/locale/doors.se.tr b/mods/doors/locale/doors.se.tr new file mode 100644 index 0000000..1ecbead --- /dev/null +++ b/mods/doors/locale/doors.se.tr @@ -0,0 +1,19 @@ +# textdomain: doors +Hidden Door Segment=Dold dörrsegment +Owned by @1=Ägd av @1 +You do not own this locked door.=Du äger inte denna lÃ¥sta dörr. +a locked door=en lÃ¥st dörr +Wooden Door=Trä Dörr +Steel Door=StÃ¥l Dörr +Glass Door=Glas Dörr +Obsidian Glass Door=Obsidian Glas Dörr +Owned by @1=Ägd av @1 +You do not own this trapdoor.=Du äger inte denna fallucka +a locked trapdoor=en lÃ¥st fallucka +Wooden Trapdoor=Trä Fallucka +Steel Trapdoor=StÃ¥l Fallucka +Apple Wood Fence Gate=Äpple Trä Fallucka +Acacia Wood Fence Gate=Akacia Trä Fallucka +Jungle Wood Fence Gate=Djungel Trä Fallucka +Pine Wood Fence Gate=Tall Trä Fallucka +Aspen Wood Fence Gate=Asp Trä Fallucka \ No newline at end of file diff --git a/mods/doors/locale/doors.zh_CN.tr b/mods/doors/locale/doors.zh_CN.tr new file mode 100644 index 0000000..5294558 --- /dev/null +++ b/mods/doors/locale/doors.zh_CN.tr @@ -0,0 +1,18 @@ +# textdomain: doors +Hidden Door Segment=éšè—门段 +Owned by @1=ç”±@1拥有 +You do not own this locked door.=这个门ä¸å±žäºŽä½ æ‰€æœ‰ã€‚ +a locked door=一扇已上é”çš„é—¨ +Wooden Door=木门 +Steel Door=é“é—¨ +Glass Door=玻璃门 +Obsidian Glass Door=黑曜石玻璃门 +You do not own this trapdoor.=这个活æ¿é—¨ä¸å±žäºŽä½ æ‰€æœ‰ã€‚ +a locked trapdoor=一扇已上é”çš„æ´»æ¿é—¨ +Wooden Trapdoor=木活æ¿é—¨ +Steel Trapdoor=é“æ´»æ¿é—¨ +Apple Wood Fence Gate=用苹果树åšçš„木栅æ é—¨ +Acacia Wood Fence Gate=相æ€æœ¨æ …æ é—¨ +Jungle Wood Fence Gate=丛林木栅æ é—¨ +Pine Wood Fence Gate=æ¾æœ¨æ …æ é—¨ +Aspen Wood Fence Gate=白æ¨æœ¨æ …æ é—¨ diff --git a/mods/doors/locale/doors.zh_TW.tr b/mods/doors/locale/doors.zh_TW.tr new file mode 100644 index 0000000..47959ee --- /dev/null +++ b/mods/doors/locale/doors.zh_TW.tr @@ -0,0 +1,18 @@ +# textdomain: doors +Hidden Door Segment=éš±è—門段 +Owned by @1=ç”±@1æ“有 +You do not own this locked door.=這個門ä¸å±¬æ–¼ä½ æ‰€æœ‰ã€‚ +a locked door=一扇已上鎖的門 +Wooden Door=木門 +Steel Door=éµé–€ +Glass Door=玻璃門 +Obsidian Glass Door=黑曜石玻璃門 +You do not own this trapdoor.=這個活æ¿é–€ä¸å±¬æ–¼ä½ æ‰€æœ‰ã€‚ +a locked trapdoor=一扇已上鎖的活æ¿é–€ +Wooden Trapdoor=木活æ¿é–€ +Steel Trapdoor=éµæ´»æ¿é–€ +Apple Wood Fence Gate=用蘋果樹åšçš„木柵欄門 +Acacia Wood Fence Gate=相æ€æœ¨æŸµæ¬„é–€ +Jungle Wood Fence Gate=å¢æž—木柵欄門 +Pine Wood Fence Gate=æ¾æœ¨æŸµæ¬„é–€ +Aspen Wood Fence Gate=白楊木柵欄門 diff --git a/mods/doors/locale/template.txt b/mods/doors/locale/template.txt new file mode 100644 index 0000000..8b5c349 --- /dev/null +++ b/mods/doors/locale/template.txt @@ -0,0 +1,18 @@ +# textdomain: doors +Hidden Door Segment= +Owned by @1= +You do not own this locked door.= +a locked door= +Wooden Door= +Steel Door= +Glass Door= +Obsidian Glass Door= +You do not own this trapdoor.= +a locked trapdoor= +Wooden Trapdoor= +Steel Trapdoor= +Apple Wood Fence Gate= +Acacia Wood Fence Gate= +Jungle Wood Fence Gate= +Pine Wood Fence Gate= +Aspen Wood Fence Gate= diff --git a/mods/doors/mod.conf b/mods/doors/mod.conf new file mode 100644 index 0000000..de053c2 --- /dev/null +++ b/mods/doors/mod.conf @@ -0,0 +1,4 @@ +name = doors +description = Minetest Game mod: doors +depends = default +optional_depends = screwdriver diff --git a/mods/doors/models/door_a.obj b/mods/doors/models/door_a.obj new file mode 100644 index 0000000..7948f2f --- /dev/null +++ b/mods/doors/models/door_a.obj @@ -0,0 +1,40 @@ +# Blender v2.76 (sub 0) OBJ File: 'door_a.blend' +# www.blender.org +mtllib door_a.mtl +o door_a +v 0.499000 -0.499000 -0.499000 +v 0.499000 1.499000 -0.499000 +v 0.499000 -0.499000 -0.375000 +v 0.499000 1.499000 -0.375000 +v -0.499000 -0.499000 -0.499000 +v -0.499000 1.499000 -0.499000 +v -0.499000 -0.499000 -0.375000 +v -0.499000 1.499000 -0.375000 +vt 0.842105 1.000000 +vt 0.894737 1.000000 +vt 0.894737 0.000000 +vt 0.842105 0.000000 +vt 0.421053 1.000000 +vt 0.421053 0.000000 +vt 0.947368 1.000000 +vt 0.947368 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.500000 +vt 0.947368 0.500000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/5/2 8/1/2 7/4/2 3/6/2 +f 8/2/3 6/7/3 5/8/3 7/3/3 +f 6/9/4 2/5/4 1/6/4 5/10/4 +f 1/11/5 3/12/5 7/7/5 5/13/5 +f 6/14/6 8/8/6 4/12/6 2/11/6 diff --git a/mods/doors/models/door_a2.obj b/mods/doors/models/door_a2.obj new file mode 100644 index 0000000..3bedc20 --- /dev/null +++ b/mods/doors/models/door_a2.obj @@ -0,0 +1,50 @@ +# Blender v2.79 (sub 0) OBJ File: '' +# www.blender.org +mtllib door_a2.mtl +o door_a2 +v -0.499000 1.499000 -0.499000 +v -0.499000 -0.499000 -0.499000 +v -0.499000 -0.499000 -0.375000 +v -0.499000 1.499000 -0.375000 +v 0.499000 -0.499000 -0.375000 +v 0.499000 1.499000 -0.375000 +v 0.499000 -0.499000 -0.499000 +v 0.499000 1.499000 -0.499000 +vt 0.894737 1.000000 +vt 0.894737 0.000000 +vt 0.842105 0.000000 +vt 0.842105 1.000000 +vt 0.421052 1.000000 +vt 0.421052 0.000000 +vt 0.000001 0.000000 +vt 0.000001 1.000000 +vt 0.894737 1.000000 +vt 0.894737 0.000000 +vt 0.947368 0.000000 +vt 0.947368 1.000000 +vt 0.842105 1.000000 +vt 0.842105 0.000000 +vt 0.421052 0.000000 +vt 0.421052 1.000000 +vt 0.947368 0.000000 +vt 0.947368 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.500000 +vt 0.947368 0.500000 +vt 0.947368 1.000000 +vn -1.0000 -0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl None.009 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 4/5/2 3/6/2 5/7/2 6/8/2 +f 6/9/3 5/10/3 7/11/3 8/12/3 +f 8/13/4 7/14/4 2/15/4 1/16/4 +f 2/17/5 7/18/5 5/19/5 3/20/5 +f 8/21/6 1/22/6 4/23/6 6/24/6 diff --git a/mods/doors/models/door_b.obj b/mods/doors/models/door_b.obj new file mode 100644 index 0000000..87f1729 --- /dev/null +++ b/mods/doors/models/door_b.obj @@ -0,0 +1,50 @@ +# Blender v2.79 (sub 0) OBJ File: '' +# www.blender.org +mtllib door_b.mtl +o door_b +v 0.499000 1.499000 -0.499000 +v 0.499000 1.499000 -0.375000 +v 0.499000 -0.499000 -0.375000 +v 0.499000 -0.499000 -0.499000 +v -0.499000 1.499000 -0.375000 +v -0.499000 -0.499000 -0.375000 +v -0.499000 1.499000 -0.499000 +v -0.499000 -0.499000 -0.499000 +vt 0.894736 1.000000 +vt 0.947368 1.000000 +vt 0.947368 0.000000 +vt 0.894736 0.000000 +vt 0.842105 1.000000 +vt 0.421053 1.000000 +vt 0.421053 0.000000 +vt 0.842105 0.000000 +vt 0.842105 1.000000 +vt 0.894736 1.000000 +vt 0.894736 0.000000 +vt 0.842105 0.000000 +vt 0.421053 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.421053 0.000000 +vt 1.000000 0.500000 +vt 0.947368 0.500000 +vt 0.947368 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.947368 0.000000 +vt 0.947368 0.500000 +vt 1.000000 0.500000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl None.007 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 2/5/2 5/6/2 6/7/2 3/8/2 +f 5/9/3 7/10/3 8/11/3 6/12/3 +f 7/13/4 1/14/4 4/15/4 8/16/4 +f 4/17/5 3/18/5 6/19/5 8/20/5 +f 7/21/6 5/22/6 2/23/6 1/24/6 diff --git a/mods/doors/models/door_b2.obj b/mods/doors/models/door_b2.obj new file mode 100644 index 0000000..35632a5 --- /dev/null +++ b/mods/doors/models/door_b2.obj @@ -0,0 +1,50 @@ +# Blender v2.79 (sub 0) OBJ File: '' +# www.blender.org +mtllib door_b2.mtl +o door_b2 +v 0.499000 1.499000 -0.499000 +v 0.499000 1.499000 -0.375000 +v 0.499000 -0.499000 -0.375000 +v 0.499000 -0.499000 -0.499000 +v -0.499000 1.499000 -0.375000 +v -0.499000 -0.499000 -0.375000 +v -0.499000 1.499000 -0.499000 +v -0.499000 -0.499000 -0.499000 +vt 0.842105 1.000000 +vt 0.894737 1.000000 +vt 0.894737 0.000000 +vt 0.842105 0.000000 +vt 0.421052 1.000000 +vt 0.000001 1.000000 +vt 0.000001 0.000000 +vt 0.421052 0.000000 +vt 0.894737 1.000000 +vt 0.947368 1.000000 +vt 0.947368 0.000000 +vt 0.894737 0.000000 +vt 0.842105 1.000000 +vt 0.421052 1.000000 +vt 0.421052 0.000000 +vt 0.842105 0.000000 +vt 1.000000 0.500000 +vt 0.947368 0.500000 +vt 0.947368 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.947368 0.000000 +vt 0.947368 0.500000 +vt 1.000000 0.500000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl None.010 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 2/5/2 5/6/2 6/7/2 3/8/2 +f 5/9/3 7/10/3 8/11/3 6/12/3 +f 7/13/4 1/14/4 4/15/4 8/16/4 +f 4/17/5 3/18/5 6/19/5 8/20/5 +f 7/21/6 5/22/6 2/23/6 1/24/6 diff --git a/mods/doors/models/doors_fencegate_closed.obj b/mods/doors/models/doors_fencegate_closed.obj new file mode 100644 index 0000000..0050f70 --- /dev/null +++ b/mods/doors/models/doors_fencegate_closed.obj @@ -0,0 +1,106 @@ +# Blender v2.76 (sub 0) OBJ File: 'gate_closed.blend' +# www.blender.org +mtllib gate_closed.mtl +o Cube_Cube.001 +v -0.625000 -0.500000 0.125000 +v -0.625000 0.500100 0.125000 +v -0.625000 -0.500000 -0.125000 +v -0.625000 0.500100 -0.125000 +v -0.375000 -0.500000 0.125000 +v -0.375000 0.500100 0.125000 +v -0.375000 -0.500000 -0.125000 +v -0.375000 0.500100 -0.125000 +v 0.375000 -0.500000 0.125000 +v 0.375000 0.500100 0.125000 +v 0.375000 -0.500000 -0.125000 +v 0.375000 0.500100 -0.125000 +v 0.625000 -0.500000 0.125000 +v 0.625000 0.500100 0.125000 +v 0.625000 -0.500000 -0.125000 +v 0.625000 0.500100 -0.125000 +v -0.375000 0.187500 0.062500 +v -0.375000 0.312500 0.062500 +v -0.375000 0.187500 -0.062500 +v -0.375000 0.312500 -0.062500 +v 0.375000 0.187500 0.062500 +v 0.375000 0.312500 0.062500 +v 0.375000 0.187500 -0.062500 +v 0.375000 0.312500 -0.062500 +v -0.374831 0.187348 0.062500 +v -0.156342 0.187363 0.062500 +v -0.374831 0.187348 -0.062500 +v -0.156342 0.187363 -0.062500 +v 0.374981 -0.343683 0.062500 +v 0.375065 -0.187304 0.062500 +v 0.374981 -0.343683 -0.062500 +v 0.375065 -0.187304 -0.062500 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt -0.000000 1.000000 +vt 1.000000 -0.000000 +vt 1.000000 0.250000 +vt 0.000000 0.250000 +vt -0.000000 0.000000 +vt 0.250000 0.000000 +vt 0.250000 0.250000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.500000 -0.000000 +vt 0.500000 0.250000 +vt 0.500000 0.750000 +vt 0.500000 1.000000 +vt 1.000000 0.625000 +vt 0.000000 0.625000 +vt 1.000000 0.875000 +vt 0.000000 0.875000 +vt -0.000000 0.687500 +vt 0.000000 0.562500 +vt 1.000000 0.562500 +vt 1.000000 0.687500 +vt 0.813740 0.249033 +vt 0.201557 0.249293 +vt 0.120995 0.125498 +vt 0.987404 0.125469 +vt 0.125000 0.375000 +vt 0.812500 0.375000 +vt 0.937500 0.500000 +vt 0.062500 0.500000 +vt 0.000000 0.125000 +vt 1.000000 0.125000 +vt 0.312500 0.437500 +vt 0.312500 0.312500 +vt 1.000000 0.312500 +vt 1.000000 0.437500 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn -0.578000 -0.816100 0.000000 +vn 0.576200 0.817300 0.000000 +usemtl None +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/4/2 8/5/2 7/6/2 3/1/2 +f 8/7/3 6/8/3 5/9/3 7/10/3 +f 6/2/4 2/9/4 1/8/4 5/3/4 +f 1/9/5 3/10/5 7/11/5 5/12/5 +f 6/6/6 8/1/6 4/13/6 2/14/6 +f 10/1/1 12/2/1 11/3/1 9/4/1 +f 12/2/2 16/9/2 15/8/2 11/3/2 +f 16/7/3 14/8/3 13/9/3 15/10/3 +f 14/4/4 10/5/4 9/6/4 13/1/4 +f 9/12/5 11/11/5 15/15/5 13/16/5 +f 14/14/6 16/13/6 12/17/6 10/18/6 +f 20/2/2 24/3/2 23/19/2 19/20/2 +f 22/1/4 18/4/4 17/21/4 21/22/4 +f 17/23/5 19/24/5 23/25/5 21/26/5 +f 22/21/6 24/5/6 20/6/6 18/22/6 +f 28/27/2 32/28/2 31/29/2 27/30/2 +f 30/31/4 26/32/4 25/33/4 29/34/4 +f 25/35/7 27/10/7 31/7/7 29/36/7 +f 30/37/8 32/38/8 28/39/8 26/40/8 diff --git a/mods/doors/models/doors_fencegate_open.obj b/mods/doors/models/doors_fencegate_open.obj new file mode 100644 index 0000000..3fb727f --- /dev/null +++ b/mods/doors/models/doors_fencegate_open.obj @@ -0,0 +1,112 @@ +# Blender v2.76 (sub 0) OBJ File: 'gate_open.blend' +# www.blender.org +mtllib gate_open.mtl +o Cube_Cube.001 +v -0.625000 -0.500000 0.125000 +v -0.625000 0.500100 0.125000 +v -0.625000 -0.500000 -0.125000 +v -0.625000 0.500100 -0.125000 +v -0.375000 -0.500000 0.125000 +v -0.375000 0.500100 0.125000 +v -0.375000 -0.500000 -0.125000 +v -0.375000 0.500100 -0.125000 +v 0.375000 -0.500000 0.125000 +v 0.375000 0.500100 0.125000 +v 0.375000 -0.500000 -0.125000 +v 0.375000 0.500100 -0.125000 +v 0.625000 -0.500000 0.125000 +v 0.625000 0.500100 0.125000 +v 0.625000 -0.500000 -0.125000 +v 0.625000 0.500100 -0.125000 +v 0.434859 0.187500 -0.872359 +v 0.434859 0.312500 -0.872359 +v 0.559859 0.187500 -0.872359 +v 0.559859 0.312500 -0.872359 +v 0.434859 0.187500 -0.122359 +v 0.434859 0.312500 -0.122359 +v 0.559859 0.187500 -0.122359 +v 0.559859 0.312500 -0.122359 +v 0.434859 0.187348 -0.872190 +v 0.434859 0.187363 -0.653701 +v 0.559859 0.187348 -0.872190 +v 0.559859 0.187363 -0.653701 +v 0.434859 -0.343683 -0.122379 +v 0.434859 -0.187304 -0.122294 +v 0.559859 -0.343683 -0.122379 +v 0.559859 -0.187304 -0.122294 +v 0.499560 -0.442900 0.005495 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 1.000000 1.000000 +vt -0.000000 1.000000 +vt 1.000000 -0.000000 +vt 1.000000 0.250000 +vt 0.000000 0.250000 +vt -0.000000 0.000000 +vt 0.250000 0.000000 +vt 0.250000 0.250000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.500000 -0.000000 +vt 0.500000 0.250000 +vt 0.500000 0.750000 +vt 0.500000 1.000000 +vt 1.000000 0.625000 +vt 0.000000 0.625000 +vt 1.000000 0.875000 +vt 0.000000 0.875000 +vt -0.000000 0.687500 +vt 0.000000 0.562500 +vt 1.000000 0.562500 +vt 1.000000 0.687500 +vt 0.813740 0.249033 +vt 0.201557 0.249293 +vt 0.120995 0.125498 +vt 0.987404 0.125469 +vt 0.125000 0.375000 +vt 0.812500 0.375000 +vt 0.937500 0.500000 +vt 0.062500 0.500000 +vt 0.000000 0.125000 +vt 1.000000 0.125000 +vt 0.312500 0.437500 +vt 0.312500 0.312500 +vt 1.000000 0.312500 +vt 1.000000 0.437500 +vt 0.312500 0.625000 +vt 0.312500 0.500000 +vt 0.187500 0.500000 +vt 0.187500 0.625000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +vn 0.000000 -0.816100 -0.578000 +vn 0.000000 0.817300 0.576200 +usemtl None +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/4/2 8/5/2 7/6/2 3/1/2 +f 8/7/3 6/8/3 5/9/3 7/10/3 +f 6/2/4 2/9/4 1/8/4 5/3/4 +f 1/9/5 3/10/5 7/11/5 5/12/5 +f 6/6/6 8/1/6 4/13/6 2/14/6 +f 10/1/1 12/2/1 11/3/1 9/4/1 +f 12/2/2 16/9/2 15/8/2 11/3/2 +f 16/7/3 14/8/3 13/9/3 15/10/3 +f 14/4/4 10/5/4 9/6/4 13/1/4 +f 9/12/5 11/11/5 15/15/5 13/16/5 +f 14/14/6 16/13/6 12/17/6 10/18/6 +f 20/2/3 24/3/3 23/19/3 19/20/3 +f 22/1/1 18/4/1 17/21/1 21/22/1 +f 17/23/5 19/24/5 23/25/5 21/26/5 +f 22/21/6 24/5/6 20/6/6 18/22/6 +f 28/27/3 32/28/3 31/29/3 27/30/3 +f 30/31/1 26/32/1 25/33/1 29/34/1 +f 25/35/7 27/10/7 31/7/7 29/36/7 +f 30/37/8 32/38/8 28/39/8 26/40/8 +f 17/41/2 18/42/2 20/43/2 19/44/2 diff --git a/mods/doors/sounds/doors_door_close.ogg b/mods/doors/sounds/doors_door_close.ogg new file mode 100644 index 0000000..fede4af Binary files /dev/null and b/mods/doors/sounds/doors_door_close.ogg differ diff --git a/mods/doors/sounds/doors_door_open.ogg b/mods/doors/sounds/doors_door_open.ogg new file mode 100644 index 0000000..9a4c4f1 Binary files /dev/null and b/mods/doors/sounds/doors_door_open.ogg differ diff --git a/mods/doors/sounds/doors_fencegate_close.ogg b/mods/doors/sounds/doors_fencegate_close.ogg new file mode 100644 index 0000000..d42590f Binary files /dev/null and b/mods/doors/sounds/doors_fencegate_close.ogg differ diff --git a/mods/doors/sounds/doors_fencegate_open.ogg b/mods/doors/sounds/doors_fencegate_open.ogg new file mode 100644 index 0000000..f6dfd1d Binary files /dev/null and b/mods/doors/sounds/doors_fencegate_open.ogg differ diff --git a/mods/doors/sounds/doors_glass_door_close.ogg b/mods/doors/sounds/doors_glass_door_close.ogg new file mode 100644 index 0000000..b3c1355 Binary files /dev/null and b/mods/doors/sounds/doors_glass_door_close.ogg differ diff --git a/mods/doors/sounds/doors_glass_door_open.ogg b/mods/doors/sounds/doors_glass_door_open.ogg new file mode 100644 index 0000000..66e6812 Binary files /dev/null and b/mods/doors/sounds/doors_glass_door_open.ogg differ diff --git a/mods/doors/sounds/doors_steel_door_close.ogg b/mods/doors/sounds/doors_steel_door_close.ogg new file mode 100644 index 0000000..aea7be6 Binary files /dev/null and b/mods/doors/sounds/doors_steel_door_close.ogg differ diff --git a/mods/doors/sounds/doors_steel_door_open.ogg b/mods/doors/sounds/doors_steel_door_open.ogg new file mode 100644 index 0000000..de87477 Binary files /dev/null and b/mods/doors/sounds/doors_steel_door_open.ogg differ diff --git a/mods/doors/textures/doors_door_glass.png b/mods/doors/textures/doors_door_glass.png new file mode 100644 index 0000000..c296a0f Binary files /dev/null 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 new file mode 100644 index 0000000..07ac5b2 Binary files /dev/null and b/mods/doors/textures/doors_door_obsidian_glass.png differ diff --git a/mods/doors/textures/doors_door_steel.png b/mods/doors/textures/doors_door_steel.png new file mode 100644 index 0000000..f42f335 Binary files /dev/null and b/mods/doors/textures/doors_door_steel.png differ diff --git a/mods/doors/textures/doors_door_wood.png b/mods/doors/textures/doors_door_wood.png new file mode 100644 index 0000000..7b18203 Binary files /dev/null and b/mods/doors/textures/doors_door_wood.png differ diff --git a/mods/doors/textures/doors_item_glass.png b/mods/doors/textures/doors_item_glass.png new file mode 100644 index 0000000..86406fb Binary files /dev/null and b/mods/doors/textures/doors_item_glass.png differ diff --git a/mods/doors/textures/doors_item_obsidian_glass.png b/mods/doors/textures/doors_item_obsidian_glass.png new file mode 100644 index 0000000..1026d43 Binary files /dev/null and b/mods/doors/textures/doors_item_obsidian_glass.png differ diff --git a/mods/doors/textures/doors_item_steel.png b/mods/doors/textures/doors_item_steel.png new file mode 100644 index 0000000..dd99e13 Binary files /dev/null and b/mods/doors/textures/doors_item_steel.png differ diff --git a/mods/doors/textures/doors_item_wood.png b/mods/doors/textures/doors_item_wood.png new file mode 100644 index 0000000..d3a62ab Binary files /dev/null and b/mods/doors/textures/doors_item_wood.png differ diff --git a/mods/doors/textures/doors_trapdoor.png b/mods/doors/textures/doors_trapdoor.png new file mode 100644 index 0000000..e92c8b2 Binary files /dev/null and b/mods/doors/textures/doors_trapdoor.png differ diff --git a/mods/doors/textures/doors_trapdoor_side.png b/mods/doors/textures/doors_trapdoor_side.png new file mode 100644 index 0000000..55981ea Binary files /dev/null and b/mods/doors/textures/doors_trapdoor_side.png differ diff --git a/mods/doors/textures/doors_trapdoor_steel.png b/mods/doors/textures/doors_trapdoor_steel.png new file mode 100644 index 0000000..4ba507d Binary files /dev/null and b/mods/doors/textures/doors_trapdoor_steel.png differ diff --git a/mods/doors/textures/doors_trapdoor_steel_side.png b/mods/doors/textures/doors_trapdoor_steel_side.png new file mode 100644 index 0000000..e29c59e Binary files /dev/null and b/mods/doors/textures/doors_trapdoor_steel_side.png differ diff --git a/mods/drawers/README.md b/mods/drawers/README.md new file mode 100644 index 0000000..ed90b3c --- /dev/null +++ b/mods/drawers/README.md @@ -0,0 +1,46 @@ +# Minetest Mod Storage Drawers + +![](https://github.com/minetest-mods/drawers/workflows/luacheck/badge.svg) + +Version 0.5.0, License: MIT + +## Description +This mod adds simple item storages showing the item's inventory image in the +front. By left- or right-clicking the image you can take or add stacks. If you +also hold the shift-key only a single item will be removed/added. + +## Notes +This mod requires Minetest 0.4.14 or later. The `default` mod from MTG or the +MineClone 2 mods are only optional dependencies for crafting recipes. + +## To-Do +- [x] Add usable 1x1 drawer +- [x] Add a drawer controller for auto-sorting items into a drawer-network +- [ ] Add half-sized drawers +- [x] Add 2x2 and 1x2 drawers +- [ ] Add compacting drawers for auto-crafting blocks/ingots/fragments +- [ ] Add a key (or something similar) for locking the item (so the item is + also displayed at count 0) +- [ ] Add duct tape to transport drawers +- [x] Support pipeworks +- [ ] Support hoppers (needs hoppers mod change) +- [x] Make drawers upgradable +- [x] Add drawers in all wood types + +## Bug reports and suggestions +You can report bugs and suggest ideas on [GitHub](http://github.com/lnj2/drawers/issues/new), +alternatively you can also [email](mailto:git@lnj.li) me. + +## Credits +#### Thanks to: +* Justin Aquadro ([@jaquadro](http://github.com/jaquadro)), developer of the + original Minecraft Mod (also licensed under MIT :smiley:) — Textures and Ideas +* Mango Tango <> ([@mtango688](http://github.com/mtango688)), + creator of the Minetest Mod ["Caches"](https://github.com/mtango688/caches/) + — I reused some code by you. :) + +## Links +* [Minetest Forums](https://forum.minetest.net/viewtopic.php?f=9&t=17134) +* [Minetest Wiki](http://wiki.minetest.net/Mods/Storage_Drawers) +* [Weblate](https://hosted.weblate.org/projects/minetest/mod-storage-drawers/) +* [GitHub](http://github.com/minetest-mods/drawers/) diff --git a/mods/drawers/init.lua b/mods/drawers/init.lua new file mode 100755 index 0000000..b49ddf2 --- /dev/null +++ b/mods/drawers/init.lua @@ -0,0 +1,382 @@ +--[[ +Minetest Mod Storage Drawers - A Mod adding storage drawers + +Copyright (C) 2017-2020 Linus Jahn + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]] + +-- Load support for intllib. +local MP = core.get_modpath(core.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +drawers = {} +drawers.drawer_visuals = {} + +drawers.WOOD_ITEMSTRING = "group:wood" +if core.get_modpath("default") and default then + drawers.WOOD_SOUNDS = default.node_sound_wood_defaults() + drawers.CHEST_ITEMSTRING = "default:chest" +elseif core.get_modpath("mcl_core") and mcl_core then -- MineClone 2 + drawers.CHEST_ITEMSTRING = "mcl_chests:chest" + if core.get_modpath("mcl_sounds") and mcl_sounds then + drawers.WOOD_SOUNDS = mcl_sounds.node_sound_wood_defaults() + end +else + drawers.CHEST_ITEMSTRING = "chest" +end + + +drawers.enable_1x1 = not core.settings:get_bool("drawers_disable_1x1") +drawers.enable_1x2 = not core.settings:get_bool("drawers_disable_1x2") +drawers.enable_2x2 = not core.settings:get_bool("drawers_disable_2x2") + +drawers.CONTROLLER_RANGE = 14 + +-- +-- GUI +-- + +drawers.gui_bg = "bgcolor[#080808BB;true]" +drawers.gui_slots = "listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]" +if (core.get_modpath("mcl_core")) and mcl_core then -- MCL2 + drawers.gui_bg_img = "background[5,5;1,1;crafting_creative_bg.png;true]" +else + drawers.gui_bg_img = "background[5,5;1,1;gui_formbg.png;true]" +end + +-- +-- Load API +-- + +dofile(MP .. "/lua/helpers.lua") +dofile(MP .. "/lua/visual.lua") +dofile(MP .. "/lua/api.lua") +dofile(MP .. "/lua/controller.lua") + + +-- +-- Register drawers +-- + +if core.get_modpath("default") and default then + drawers.register_drawer("drawers:wood", { + description = S("Wooden"), + tiles1 = drawers.node_tiles_front_other("drawers_wood_front_1.png", + "drawers_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_wood_front_2.png", + "drawers_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_wood_front_4.png", + "drawers_wood.png"), + groups = {choppy = 3, oddly_breakable_by_hand = 2}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 8, -- normal chest size + material = drawers.WOOD_ITEMSTRING + }) + drawers.register_drawer("drawers:acacia_wood", { + description = S("Acacia Wood"), + tiles1 = drawers.node_tiles_front_other("drawers_acacia_wood_front_1.png", + "drawers_acacia_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_acacia_wood_front_2.png", + "drawers_acacia_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_acacia_wood_front_4.png", + "drawers_acacia_wood.png"), + groups = {choppy = 3, oddly_breakable_by_hand = 2}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 8, -- normal mcl chest size + material = "default:acacia_wood" + }) + drawers.register_drawer("drawers:aspen_wood", { + description = S("Aspen Wood"), + tiles1 = drawers.node_tiles_front_other("drawers_aspen_wood_front_1.png", + "drawers_aspen_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_aspen_wood_front_2.png", + "drawers_aspen_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_aspen_wood_front_4.png", + "drawers_aspen_wood.png"), + groups = {choppy = 3, oddly_breakable_by_hand = 2}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 8, -- normal chest size + material = "default:aspen_wood" + }) + drawers.register_drawer("drawers:junglewood", { + description = S("Junglewood"), + tiles1 = drawers.node_tiles_front_other("drawers_junglewood_front_1.png", + "drawers_junglewood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_junglewood_front_2.png", + "drawers_junglewood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_junglewood_front_4.png", + "drawers_junglewood.png"), + groups = {choppy = 3, oddly_breakable_by_hand = 2}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 8, -- normal mcl chest size + material = "default:junglewood" + }) + drawers.register_drawer("drawers:pine_wood", { + description = S("Pine Wood"), + tiles1 = drawers.node_tiles_front_other("drawers_pine_wood_front_1.png", + "drawers_pine_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_pine_wood_front_2.png", + "drawers_pine_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_pine_wood_front_4.png", + "drawers_pine_wood.png"), + groups = {choppy = 3, oddly_breakable_by_hand = 2}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 8, -- normal chest size + material = "default:pine_wood" + }) +elseif core.get_modpath("mcl_core") and mcl_core then + drawers.register_drawer("drawers:oakwood", { + description = S("Oak Wood"), + tiles1 = drawers.node_tiles_front_other("drawers_oak_wood_front_1.png", + "drawers_oak_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_oak_wood_front_2.png", + "drawers_oak_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_oak_wood_front_4.png", + "drawers_oak_wood.png"), + groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 9, -- normal mcl chest size + material = drawers.WOOD_ITEMSTRING, + _mcl_blast_resistance = 15, + _mcl_hardness = 2, + }) + drawers.register_drawer("drawers:acaciawood", { + description = S("Acacia Wood"), + tiles1 = drawers.node_tiles_front_other("drawers_acacia_wood_mcl_front_1.png", + "drawers_acacia_wood_mcl.png"), + tiles2 = drawers.node_tiles_front_other("drawers_acacia_wood_mcl_front_2.png", + "drawers_acacia_wood_mcl.png"), + tiles4 = drawers.node_tiles_front_other("drawers_acacia_wood_mcl_front_4.png", + "drawers_acacia_wood_mcl.png"), + groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 9, -- normal mcl chest size + material = "mcl_core:acaciawood", + _mcl_blast_resistance = 15, + _mcl_hardness = 2, + }) + drawers.register_drawer("drawers:birchwood", { + description = S("Birch Wood"), + tiles1 = drawers.node_tiles_front_other("drawers_birch_wood_front_1.png", + "drawers_birch_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_birch_wood_front_2.png", + "drawers_birch_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_birch_wood_front_4.png", + "drawers_birch_wood.png"), + groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 9, -- normal mcl chest size + material = "mcl_core:birchwood", + _mcl_blast_resistance = 15, + _mcl_hardness = 2, + }) + drawers.register_drawer("drawers:darkwood", { + description = S("Dark Oak Wood"), + tiles1 = drawers.node_tiles_front_other("drawers_dark_oak_wood_front_1.png", + "drawers_dark_oak_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_dark_oak_wood_front_2.png", + "drawers_dark_oak_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_dark_oak_wood_front_4.png", + "drawers_dark_oak_wood.png"), + groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 9, -- normal mcl chest size + material = "mcl_core:darkwood", + _mcl_blast_resistance = 15, + _mcl_hardness = 2, + }) + drawers.register_drawer("drawers:junglewood", { + description = S("Junglewood"), + tiles1 = drawers.node_tiles_front_other("drawers_junglewood_mcl_front_1.png", + "drawers_junglewood_mcl.png"), + tiles2 = drawers.node_tiles_front_other("drawers_junglewood_mcl_front_2.png", + "drawers_junglewood_mcl.png"), + tiles4 = drawers.node_tiles_front_other("drawers_junglewood_mcl_front_4.png", + "drawers_junglewood_mcl.png"), + groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 9, -- normal mcl chest size + material = "mcl_core:junglewood", + _mcl_blast_resistance = 15, + _mcl_hardness = 2, + }) + drawers.register_drawer("drawers:sprucewood", { + description = S("Spruce Wood"), + tiles1 = drawers.node_tiles_front_other("drawers_spruce_wood_front_1.png", + "drawers_spruce_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_spruce_wood_front_2.png", + "drawers_spruce_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_spruce_wood_front_4.png", + "drawers_spruce_wood.png"), + groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 9, -- normal mcl chest size + material = "mcl_core:sprucewood", + _mcl_blast_resistance = 15, + _mcl_hardness = 2, + }) + + -- backwards compatibility + core.register_alias("drawers:wood1", "drawers:oakwood1") + core.register_alias("drawers:wood2", "drawers:oakwood2") + core.register_alias("drawers:wood4", "drawers:oakwood4") +else + drawers.register_drawer("drawers:wood", { + description = S("Wooden"), + tiles1 = drawers.node_tiles_front_other("drawers_wood_front_1.png", + "drawers_wood.png"), + tiles2 = drawers.node_tiles_front_other("drawers_wood_front_2.png", + "drawers_wood.png"), + tiles4 = drawers.node_tiles_front_other("drawers_wood_front_4.png", + "drawers_wood.png"), + groups = {choppy = 3, oddly_breakable_by_hand = 2}, + sounds = drawers.WOOD_SOUNDS, + drawer_stack_max_factor = 4 * 8, -- normal chest size + material = drawers.WOOD_ITEMSTRING + }) +end + + +-- +-- Register drawer upgrades +-- + +if core.get_modpath("default") and default then + drawers.register_drawer_upgrade("drawers:upgrade_steel", { + description = S("Steel Drawer Upgrade (x2)"), + inventory_image = "drawers_upgrade_steel.png", + groups = {drawer_upgrade = 100}, + recipe_item = "default:steel_ingot" + }) + + drawers.register_drawer_upgrade("drawers:upgrade_gold", { + description = S("Gold Drawer Upgrade (x3)"), + inventory_image = "drawers_upgrade_gold.png", + groups = {drawer_upgrade = 200}, + recipe_item = "default:gold_ingot" + }) + + drawers.register_drawer_upgrade("drawers:upgrade_obsidian", { + description = S("Obsidian Drawer Upgrade (x4)"), + inventory_image = "drawers_upgrade_obsidian.png", + groups = {drawer_upgrade = 300}, + recipe_item = "default:obsidian" + }) + + drawers.register_drawer_upgrade("drawers:upgrade_diamond", { + description = S("Diamond Drawer Upgrade (x8)"), + inventory_image = "drawers_upgrade_diamond.png", + groups = {drawer_upgrade = 700}, + recipe_item = "default:diamond" + }) +elseif core.get_modpath("mcl_core") and mcl_core then + drawers.register_drawer_upgrade("drawers:upgrade_iron", { + description = S("Iron Drawer Upgrade (x2)"), + inventory_image = "drawers_upgrade_iron.png", + groups = {drawer_upgrade = 100}, + recipe_item = "mcl_core:iron_ingot" + }) + + drawers.register_drawer_upgrade("drawers:upgrade_gold", { + description = S("Gold Drawer Upgrade (x3)"), + inventory_image = "drawers_upgrade_gold.png", + groups = {drawer_upgrade = 200}, + recipe_item = "mcl_core:gold_ingot" + }) + + drawers.register_drawer_upgrade("drawers:upgrade_obsidian", { + description = S("Obsidian Drawer Upgrade (x4)"), + inventory_image = "drawers_upgrade_obsidian.png", + groups = {drawer_upgrade = 300}, + recipe_item = "mcl_core:obsidian" + }) + + drawers.register_drawer_upgrade("drawers:upgrade_diamond", { + description = S("Diamond Drawer Upgrade (x8)"), + inventory_image = "drawers_upgrade_diamond.png", + groups = {drawer_upgrade = 700}, + recipe_item = "mcl_core:diamond" + }) + + drawers.register_drawer_upgrade("drawers:upgrade_emerald", { + description = S("Emerald Drawer Upgrade (x13)"), + inventory_image = "drawers_upgrade_emerald.png", + groups = {drawer_upgrade = 1200}, + recipe_item = "mcl_core:emerald" + }) +end + +if core.get_modpath("moreores") then + drawers.register_drawer_upgrade("drawers:upgrade_mithril", { + description = S("Mithril Drawer Upgrade (x13)"), + inventory_image = "drawers_upgrade_mithril.png", + groups = {drawer_upgrade = 1200}, + recipe_item = "moreores:mithril_ingot" + }) +end + +-- +-- Register drawer trim +-- + +if core.get_modpath("mcl_core") and mcl_core then + core.register_node("drawers:trim", { + description = S("Wooden Trim"), + tiles = {"drawers_trim.png"}, + groups = {drawer_connector = 1, handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1}, + _mcl_blast_resistance = 15, + _mcl_hardness = 2, + }) +else + core.register_node("drawers:trim", { + description = S("Wooden Trim"), + tiles = {"drawers_trim.png"}, + groups = {drawer_connector = 1, choppy = 3, oddly_breakable_by_hand = 2}, + }) +end + +core.register_craft({ + output = "drawers:trim 6", + recipe = { + {"group:stick", "group:wood", "group:stick"}, + {"group:wood", "group:wood", "group:wood"}, + {"group:stick", "group:wood", "group:stick"} + } +}) + +-- +-- Register drawer upgrade template +-- + +core.register_craftitem("drawers:upgrade_template", { + description = S("Drawer Upgrade Template"), + inventory_image = "drawers_upgrade_template.png" +}) + +core.register_craft({ + output = "drawers:upgrade_template 4", + recipe = { + {"group:stick", "group:stick", "group:stick"}, + {"group:stick", "group:drawer", "group:stick"}, + {"group:stick", "group:stick", "group:stick"} + } +}) diff --git a/mods/drawers/intllib.lua b/mods/drawers/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/drawers/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/drawers/license.txt b/mods/drawers/license.txt new file mode 100644 index 0000000..c4a802a --- /dev/null +++ b/mods/drawers/license.txt @@ -0,0 +1,118 @@ +Minetest Mod Storage Drawers +============================ +Version 0.4.3 + +License of source code: +----------------------- +Copyright (C) 2017-2020 Linus Jahn +Copyright (C) 2016 Mango Tango + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +License of translations: +------------------------ +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication + +No Copyright +Minetest Mod Storage Drawers Translators + +The person who associated a work with this deed has dedicated the work to the public +domain by waiving all of his or her rights to the work worldwide under copyright law, +including all related and neighboring rights, to the extent allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial purposes, all +without asking permission. See Other Information below. + +Other Information + +In no way are the patent or trademark rights of any person affected by CC0, nor are the +rights that other persons may have in the work or in how the work is used, such as +publicity or privacy rights. +Unless expressly stated otherwise, the person who associated a work with this deed makes +no warranties about the work, and disclaims liability for all uses of the work, to the +fullest extent permitted by applicable law. +When using or citing the work, you should not imply endorsement by the author or the +affirmer. + +For more details: +https://creativecommons.org/publicdomain/zero/1.0/ + + +License of media: +----------------- +Copyright (C) 2012 ultradust (https://www.freesound.org/people/ultradust/) (CC BY 3.0): + sounds/drawers_interact.1.ogg (edited by tacotexmex) + sounds/drawers_interact.2.ogg (edited by tacotexmex) + +Copyright (C) 2014 Justin Aquadro (MIT): + textures/drawers_acacia_wood_mcl_front_1.png + textures/drawers_acacia_wood_mcl_front_2.png + textures/drawers_acacia_wood_mcl_front_4.png + textures/drawers_acacia_wood_mcl.png + textures/drawers_aspen_wood_front_1.png + textures/drawers_aspen_wood_front_2.png + textures/drawers_aspen_wood_front_4.png + textures/drawers_aspen_wood.png + textures/drawers_birch_wood_front_1.png + textures/drawers_birch_wood_front_2.png + textures/drawers_birch_wood_front_4.png + textures/drawers_birch_wood.png + textures/drawers_controller_front.png + textures/drawers_controller_side.png + textures/drawers_controller_top.png + textures/drawers_dark_oak_wood_front_1.png + textures/drawers_dark_oak_wood_front_2.png + textures/drawers_dark_oak_wood_front_4.png + textures/drawers_dark_oak_wood.png + textures/drawers_junglewood_mcl_front_1.png + textures/drawers_junglewood_mcl_front_2.png + textures/drawers_junglewood_mcl_front_4.png + textures/drawers_junglewood_mcl.png + textures/drawers_oak_wood_front_1.png + textures/drawers_oak_wood_front_2.png + textures/drawers_oak_wood_front_4.png + textures/drawers_oak_wood.png + textures/drawers_pine_wood_front_1.png + textures/drawers_pine_wood_front_2.png + textures/drawers_pine_wood_front_4.png + textures/drawers_pine_wood.png + textures/drawers_spruce_wood_front_1.png + textures/drawers_spruce_wood_front_2.png + textures/drawers_spruce_wood_front_4.png + textures/drawers_spruce_wood.png + textures/drawers_trim.png + textures/drawers_upgrade_diamond.png + textures/drawers_upgrade_emerald.png + textures/drawers_upgrade_gold.png + textures/drawers_upgrade_iron.png + textures/drawers_upgrade_mithril.png (colors adapted by Linus Jahn , 2020) + textures/drawers_upgrade_obsidian.png + textures/drawers_upgrade_steel.png + textures/drawers_upgrade_slot_bg.png (extracted from gui/drawers_1.png by LNJ ) + textures/drawers_upgrade_template.png + textures/drawers_wood_front_1.png + textures/drawers_wood_front_2.png + textures/drawers_wood_front_4.png + textures/drawers_wood.png + +Everything not listed in here: +Copyright (C) 2017-2020 Linus Jahn (MIT) diff --git a/mods/drawers/locale/be.po b/mods/drawers/locale/be.po new file mode 100644 index 0000000..9c67c07 --- /dev/null +++ b/mods/drawers/locale/be.po @@ -0,0 +1,139 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2019-03-15 09:03+0000\n" +"Last-Translator: Zmicer Turok \n" +"Language-Team: Belarusian \n" +"Language: be\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 3.6-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "ДраўлÑны" + +#: init.lua +msgid "Acacia Wood" +msgstr "Драўніна акацыі" + +#: init.lua +msgid "Aspen Wood" +msgstr "ÐÑÑ–Ð½Ð°Ð²Ð°Ñ Ð´Ñ€Ð°ÑžÐ½Ñ–Ð½Ð°" + +#: init.lua +msgid "Junglewood" +msgstr "Ð”Ð¶ÑƒÐ½Ð³Ð»ÐµÐ²Ð°Ñ Ð´Ñ€Ð°ÑžÐ½Ñ–Ð½Ð°" + +#: init.lua +msgid "Pine Wood" +msgstr "Ð¥Ð²Ð°Ñ‘Ð²Ð°Ñ Ð´Ñ€Ð°ÑžÐ½Ñ–Ð½Ð°" + +#: init.lua +msgid "Oak Wood" +msgstr "Ð”ÑƒÐ±Ð¾Ð²Ð°Ñ Ð´Ñ€Ð°ÑžÐ½Ñ–Ð½Ð°" + +#: init.lua +msgid "Birch Wood" +msgstr "БÑÑ€Ð¾Ð·Ð°Ð²Ð°Ñ Ð´Ñ€Ð°ÑžÐ½Ñ–Ð½Ð°" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Ð¦Ñ‘Ð¼Ð½Ð°Ñ Ð´ÑƒÐ±Ð¾Ð²Ð°Ñ Ð´Ñ€Ð°ÑžÐ½Ñ–Ð½Ð°" + +#: init.lua +msgid "Spruce Wood" +msgstr "Ð¯Ð»Ñ–Ð½Ð°Ð²Ð°Ñ Ð´Ñ€Ð°ÑžÐ½Ñ–Ð½Ð°" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "МадÑÑ€Ð½Ñ–Ð·Ð°Ñ†Ñ‹Ñ Ñталёвай шуфлÑды (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "МадÑÑ€Ð½Ñ–Ð·Ð°Ñ†Ñ‹Ñ Ð·Ð°Ð»Ð°Ñ‚Ð¾Ð¹ шуфлÑды (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "МадÑÑ€Ð½Ñ–Ð·Ð°Ñ†Ñ‹Ñ Ð°Ð±ÑідыÑнавай шуфлÑды (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "МадÑÑ€Ð½Ñ–Ð·Ð°Ñ†Ñ‹Ñ Ð´Ñ‹Ñментавай шуфлÑды (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "МадÑÑ€Ð½Ñ–Ð·Ð°Ñ†Ñ‹Ñ Ð¶Ð°Ð»ÐµÐ·Ð½Ð°Ð¹ шуфлÑды (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "МадÑÑ€Ð½Ñ–Ð·Ð°Ñ†Ñ‹Ñ Ñмарагдавай шуфлÑды (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "МадÑÑ€Ð½Ñ–Ð·Ð°Ñ†Ñ‹Ñ Ñмарагдавай шуфлÑды (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "ДраўлÑнае аздабленне" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Шаблон мадÑрнізацыі шуфлÑды" + +#: lua/controller.lua +msgid "Current State: " +msgstr "БÑгучы Ñтан: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Спынены" + +#: lua/controller.lua +msgid "Running" +msgstr "Працуе" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Затрыманы" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Кантролер шуфлÑды" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "ПуÑтаÑ" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1 шуфлÑда" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1 шуфлÑды (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1 шуфлÑды (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% поўны)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% поўны)" diff --git a/mods/drawers/locale/cs.po b/mods/drawers/locale/cs.po new file mode 100644 index 0000000..768fbc3 --- /dev/null +++ b/mods/drawers/locale/cs.po @@ -0,0 +1,139 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2017-06-21 18:49+0000\n" +"Last-Translator: Jakub VanÄ›k \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Weblate 2.15-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "ze dÅ™eva" + +#: init.lua +msgid "Acacia Wood" +msgstr "ze dÅ™eva akácie" + +#: init.lua +msgid "Aspen Wood" +msgstr "ze dÅ™eva osiky" + +#: init.lua +msgid "Junglewood" +msgstr "ze dÅ™eva džunglovníku" + +#: init.lua +msgid "Pine Wood" +msgstr "ze borovicového dÅ™eva" + +#: init.lua +msgid "Oak Wood" +msgstr "ze dubového dÅ™eva" + +#: init.lua +msgid "Birch Wood" +msgstr "z bukového dÅ™eva" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "z tmavého dubového dÅ™eva" + +#: init.lua +msgid "Spruce Wood" +msgstr "ze smrkového dÅ™eva" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Ocelové vylepÅ¡ení Å¡uplíku (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Zlaté vylepÅ¡ení Å¡uplíku (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Obsidiánové vylepÅ¡ení Å¡uplíku (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Diamantové vylepÅ¡ení Å¡uplíku (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Železné vylepÅ¡ení Å¡uplíku (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Emeraldové vylepÅ¡ení Å¡uplíku (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Emeraldové vylepÅ¡ení Å¡uplíku (x13)" + +#: init.lua +#, fuzzy +msgid "Wooden Trim" +msgstr "ze dÅ™eva" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Å ablona vylepÅ¡ení Å¡uplíku" + +#: lua/controller.lua +msgid "Current State: " +msgstr "" + +#: lua/controller.lua +msgid "Stopped" +msgstr "" + +#: lua/controller.lua +msgid "Running" +msgstr "" + +#: lua/controller.lua +msgid "Jammed" +msgstr "" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Prázdný" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "Å uplík @1" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "Å uplíky @1 (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "Å uplíky @1 (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (z @2 % plný)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (z @3 % plný)" diff --git a/mods/drawers/locale/de.po b/mods/drawers/locale/de.po new file mode 100644 index 0000000..5b71689 --- /dev/null +++ b/mods/drawers/locale/de.po @@ -0,0 +1,138 @@ +# German translations for PACKAGE package. +# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# LNJ , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2018-12-08 09:04+0000\n" +"Last-Translator: LNJ \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.4-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "Holz" + +#: init.lua +msgid "Acacia Wood" +msgstr "Akazienholz" + +#: init.lua +msgid "Aspen Wood" +msgstr "Espenholz" + +#: init.lua +msgid "Junglewood" +msgstr "Tropenholz" + +#: init.lua +msgid "Pine Wood" +msgstr "Kiefernholz" + +#: init.lua +msgid "Oak Wood" +msgstr "Eichenholz" + +#: init.lua +msgid "Birch Wood" +msgstr "Birkenholz" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Dunkeleichenholz" + +#: init.lua +msgid "Spruce Wood" +msgstr "Fichtenholz" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Stahl-Schubfachverbesserung (×2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Gold-Schubfachverbesserung (×3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Obsidian-Schubfachverbesserung (×5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Diamant-Schubfachverbesserung (×8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Eisen-Schubfachverbesserung (×2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Smaragd-Schubfachverbesserung (×13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Smaragd-Schubfachverbesserung (×13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "Holzverkleidung" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Schubfachverbesserungsvorlage" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Momentaner Zustand: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Angehalten" + +#: lua/controller.lua +msgid "Running" +msgstr "Läuft" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Gestaut" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Schubfach Steuerung" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Leer" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1schubfach" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1schubfächer (1×2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1schubfächer (2×2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% voll)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% voll)" diff --git a/mods/drawers/locale/el.po b/mods/drawers/locale/el.po new file mode 100644 index 0000000..cdc870d --- /dev/null +++ b/mods/drawers/locale/el.po @@ -0,0 +1,136 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2020-01-05 21:21+0000\n" +"Last-Translator: THANOS SIOURDAKIS \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.10\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "ΞÏλινο" + +#: init.lua +msgid "Acacia Wood" +msgstr "" + +#: init.lua +msgid "Aspen Wood" +msgstr "" + +#: init.lua +msgid "Junglewood" +msgstr "" + +#: init.lua +msgid "Pine Wood" +msgstr "" + +#: init.lua +msgid "Oak Wood" +msgstr "" + +#: init.lua +msgid "Birch Wood" +msgstr "" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "" + +#: init.lua +msgid "Spruce Wood" +msgstr "" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "" + +#: init.lua +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +msgid "Mithril Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +msgid "Wooden Trim" +msgstr "" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "" + +#: lua/controller.lua +msgid "Current State: " +msgstr "ΤÏέχουσα κατάσταση: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Σταμάτησε" + +#: lua/controller.lua +msgid "Running" +msgstr "Εκτέλεση" + +#: lua/controller.lua +msgid "Jammed" +msgstr "ΜπλοκαÏισμένο" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Ελεγκτής συÏταÏιοÏ" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Κενό" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1 συÏτάÏι" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1 συÏτάÏια (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1 συÏτάÏια (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% ΠλήÏης)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "" diff --git a/mods/drawers/locale/es.po b/mods/drawers/locale/es.po new file mode 100644 index 0000000..144375c --- /dev/null +++ b/mods/drawers/locale/es.po @@ -0,0 +1,140 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2018-10-22 18:37+0000\n" +"Last-Translator: runs \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.3-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "De Madera" + +#: init.lua +msgid "Acacia Wood" +msgstr "Madera de acacia" + +#: init.lua +msgid "Aspen Wood" +msgstr "Madera de álamo" + +#: init.lua +msgid "Junglewood" +msgstr "Madera tropical" + +#: init.lua +msgid "Pine Wood" +msgstr "Madera de pino" + +#: init.lua +msgid "Oak Wood" +msgstr "Madera de roble" + +#: init.lua +msgid "Birch Wood" +msgstr "Madera de abedul" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Madera de roble oscuro" + +#: init.lua +msgid "Spruce Wood" +msgstr "Madera de pícea" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "@1 Gavetas (1x2)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "" + +#: init.lua +#, fuzzy +msgid "Iron Drawer Upgrade (x2)" +msgstr "@1 Gavetas (1x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "@1 Gavetas (1x2)" + +#: init.lua +#, fuzzy +msgid "Wooden Trim" +msgstr "De Madera" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Estado actual: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Detenido" + +#: lua/controller.lua +msgid "Running" +msgstr "Ejecutándose" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Atascado" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Controlador de gaveta" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Vacío" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1 Gaveta" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1 Gavetas (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1 Gavetas (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% lleno)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% lleno)" diff --git a/mods/drawers/locale/fr.po b/mods/drawers/locale/fr.po new file mode 100644 index 0000000..06e5ae5 --- /dev/null +++ b/mods/drawers/locale/fr.po @@ -0,0 +1,138 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2019-01-21 21:21+0000\n" +"Last-Translator: Nathan \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.4-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "En bois" + +#: init.lua +msgid "Acacia Wood" +msgstr "Bois d'acacia" + +#: init.lua +msgid "Aspen Wood" +msgstr "Bois de tremble" + +#: init.lua +msgid "Junglewood" +msgstr "Bois de jungle" + +#: init.lua +msgid "Pine Wood" +msgstr "Bois de pin" + +#: init.lua +msgid "Oak Wood" +msgstr "Bois de chêne" + +#: init.lua +msgid "Birch Wood" +msgstr "Bois de bouleau" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Bois de chêne foncé" + +#: init.lua +msgid "Spruce Wood" +msgstr "Bois d'épicéa" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Amélioration tiroir en acier (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Amélioration tiroir en or (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Amélioration tiroir en obsidienne (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Amélioration tiroir en diamant (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Amélioration tiroir en fer (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Amélioration tiroir en émeraude (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Amélioration tiroir en émeraude (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "Habillage en bois" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Amélioration modèle de tiroir" + +#: lua/controller.lua +msgid "Current State: " +msgstr "État Actuel : " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Arreté" + +#: lua/controller.lua +msgid "Running" +msgstr "En cours d'exécution" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Bloqué" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Contrôleur de Tiroirs" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Vide" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "Tiroir @1" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "Tiroirs (1x2) @1" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "Tiroirs (2x2) @1" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% plein)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% plein)" diff --git a/mods/drawers/locale/id.po b/mods/drawers/locale/id.po new file mode 100644 index 0000000..619f61f --- /dev/null +++ b/mods/drawers/locale/id.po @@ -0,0 +1,139 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2019-02-08 14:10+0000\n" +"Last-Translator: Muhammad Rifqi Priyo Susanto " +"\n" +"Language-Team: Indonesian \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.5-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "Kayu" + +#: init.lua +msgid "Acacia Wood" +msgstr "Kayu Akasia" + +#: init.lua +msgid "Aspen Wood" +msgstr "Kayu Aspen" + +#: init.lua +msgid "Junglewood" +msgstr "Kayu Rimba" + +#: init.lua +msgid "Pine Wood" +msgstr "Kayu Pinus" + +#: init.lua +msgid "Oak Wood" +msgstr "Kayu Ek" + +#: init.lua +msgid "Birch Wood" +msgstr "Kayu Birch" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Kayu Ek Gelap" + +#: init.lua +msgid "Spruce Wood" +msgstr "Kayu Cemara" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Tingkatkan menjadi Laci Baja (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Tingkatkan menjadi Laci Emas (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Tingkatkan menjadi Laci Obsidian (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Tingkatkan menjadi Laci Berlian (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Tingkatkan menjadi Laci Besi (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Tingkatkan menjadi Laci Zamrud (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Tingkatkan menjadi Laci Zamrud (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "Ukiran Kayu" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Templat Peningkatan Laci" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Keadaan Saat Ini: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Berhenti" + +#: lua/controller.lua +msgid "Running" +msgstr "Berjalan" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Macet" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Pengendali Laci" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Kosong" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "Laci @1" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "Laci @1 (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "Laci @1 (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% penuh)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% penuh)" diff --git a/mods/drawers/locale/it.po b/mods/drawers/locale/it.po new file mode 100644 index 0000000..792302d --- /dev/null +++ b/mods/drawers/locale/it.po @@ -0,0 +1,138 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2019-09-03 13:23+0000\n" +"Last-Translator: Jacques Lagrange \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.9-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "Di legno" + +#: init.lua +msgid "Acacia Wood" +msgstr "Legno di acacia" + +#: init.lua +msgid "Aspen Wood" +msgstr "Legno di pioppo" + +#: init.lua +msgid "Junglewood" +msgstr "Legno della giungla" + +#: init.lua +msgid "Pine Wood" +msgstr "Legno di pino" + +#: init.lua +msgid "Oak Wood" +msgstr "Legno di quercia" + +#: init.lua +msgid "Birch Wood" +msgstr "Legno di betulla" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Legno di quercia scura" + +#: init.lua +msgid "Spruce Wood" +msgstr "Legno di abete rosso" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Miglioramento d'acciaio della cassettiera (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Miglioramento d'oro della cassettiera (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Miglioramento d'ossidiana della cassettiera (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Miglioramento di diamante della cassettiera (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Miglioramento di ferro della cassettiera (x3)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Miglioramento di smeraldo della cassettiera (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Miglioramento di smeraldo della cassettiera (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "di legno" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Modello di miglioramento della cassettiera" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Stato attuale: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Fermo" + +#: lua/controller.lua +msgid "Running" +msgstr "In corso di esecuzione" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Bloccato" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Vuoto" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1 Cassetto" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1 Cassetti (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1 Cassetti (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% pieno)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% pieno)" diff --git a/mods/drawers/locale/ms.po b/mods/drawers/locale/ms.po new file mode 100644 index 0000000..0821497 --- /dev/null +++ b/mods/drawers/locale/ms.po @@ -0,0 +1,138 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2018-12-09 11:08+0000\n" +"Last-Translator: Muhammad Nur Hidayat Yasuyoshi \n" +"Language-Team: Malay \n" +"Language: ms\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.4-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "Kayu" + +#: init.lua +msgid "Acacia Wood" +msgstr "Papan Kayu Akasia" + +#: init.lua +msgid "Aspen Wood" +msgstr "Papan Kayu Aspen" + +#: init.lua +msgid "Junglewood" +msgstr "Papan Kayu Hutan" + +#: init.lua +msgid "Pine Wood" +msgstr "Papan Kayu Pain" + +#: init.lua +msgid "Oak Wood" +msgstr "Papan Kayu Oak" + +#: init.lua +msgid "Birch Wood" +msgstr "Papan Kayu Birch" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Papan Kayu Oak Gelap" + +#: init.lua +msgid "Spruce Wood" +msgstr "Papan Kayu Fir" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Naik Taraf Laci - Keluli (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Naik Taraf Laci - Emas (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Naik Taraf Laci - Obsidia (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Naik Taraf Laci - Intan (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Naik Taraf Laci - Besi (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Naik Taraf Laci - Zamrud (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Naik Taraf Laci - Zamrud (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "Hiasan Kayu" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Templat Naik Taraf Laci" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Keadaan Semasa: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Berhenti" + +#: lua/controller.lua +msgid "Running" +msgstr "Berjalan" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Tersekat" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Pengawal Laci" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Kosong" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "Laci @1" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "Laci @1 (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "Laci @1 (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% penuh)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% penuh)" diff --git a/mods/drawers/locale/nl.po b/mods/drawers/locale/nl.po new file mode 100644 index 0000000..d53adb6 --- /dev/null +++ b/mods/drawers/locale/nl.po @@ -0,0 +1,139 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2017-09-19 19:45+0000\n" +"Last-Translator: Oscar \n" +"Language-Team: Dutch \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 2.17-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "Houten" + +#: init.lua +msgid "Acacia Wood" +msgstr "Acacia Hout" + +#: init.lua +msgid "Aspen Wood" +msgstr "Espenhout" + +#: init.lua +msgid "Junglewood" +msgstr "Junglehout" + +#: init.lua +msgid "Pine Wood" +msgstr "Dennenhout" + +#: init.lua +msgid "Oak Wood" +msgstr "Eikenhout" + +#: init.lua +msgid "Birch Wood" +msgstr "Berken hout" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Donker Eikenhout" + +#: init.lua +msgid "Spruce Wood" +msgstr "Sparrenhout" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Stalen Lade Upgrade (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Gouden Lade Upgrade (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Obsidiaanse Lade Upgrade (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Diamanten Lade Upgrade (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Ijzeren Lade Upgrade (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Smaragden Lade upgrade (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Smaragden Lade upgrade (x13)" + +#: init.lua +#, fuzzy +msgid "Wooden Trim" +msgstr "Houten" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Lade Upgrade Template" + +#: lua/controller.lua +msgid "Current State: " +msgstr "" + +#: lua/controller.lua +msgid "Stopped" +msgstr "" + +#: lua/controller.lua +msgid "Running" +msgstr "" + +#: lua/controller.lua +msgid "Jammed" +msgstr "" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Leeg" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1 Lade" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1 Lades (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1 Lades (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% vol)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% vol)" diff --git a/mods/drawers/locale/pl.po b/mods/drawers/locale/pl.po new file mode 100644 index 0000000..5382323 --- /dev/null +++ b/mods/drawers/locale/pl.po @@ -0,0 +1,139 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2019-09-11 16:23+0000\n" +"Last-Translator: Mateusz Mendel \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 3.9-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "Drewniany" + +#: init.lua +msgid "Acacia Wood" +msgstr "Drewno akacjowe" + +#: init.lua +msgid "Aspen Wood" +msgstr "Drewno osikowe" + +#: init.lua +msgid "Junglewood" +msgstr "Drewno jungli" + +#: init.lua +msgid "Pine Wood" +msgstr "Drewno sosnowe" + +#: init.lua +msgid "Oak Wood" +msgstr "Drewno dÄ™bowe" + +#: init.lua +msgid "Birch Wood" +msgstr "Drewno brzozowe" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Drewno ciemne dÄ™bowe" + +#: init.lua +msgid "Spruce Wood" +msgstr "Drwno Å›wierkowe" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Ulepszenie stalowej szuflady(x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Ulepszenie zÅ‚otej szuflady (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Ulepszenie obsydianowej szuflady (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Ulepszenie diamentowej szuflady (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Å»elazna aktualizacja szuflady (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Ulepszenie szmaragdowej szuflady (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Ulepszenie szmaragdowej szuflady (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "Drewniane wykoÅ„czenia" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Szablon ulepszenia szuflady" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Stan aktulany: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Zatrzymany" + +#: lua/controller.lua +msgid "Running" +msgstr "Uruchomiona" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Zablokowany" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Kontroler szuflady" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Pusta" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1 Szuflada" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1 Szuflady (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1 Szuflady (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% napeÅ‚nione)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% napeÅ‚nione)" diff --git a/mods/drawers/locale/pt_BR.po b/mods/drawers/locale/pt_BR.po new file mode 100644 index 0000000..f319035 --- /dev/null +++ b/mods/drawers/locale/pt_BR.po @@ -0,0 +1,138 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2019-08-03 04:11+0000\n" +"Last-Translator: Wilker Santana da Silva \n" +"Language-Team: Portuguese (Brazil) \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.8-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "Madeira" + +#: init.lua +msgid "Acacia Wood" +msgstr "Lenha de Acácia" + +#: init.lua +msgid "Aspen Wood" +msgstr "Lenha de Ãlamo" + +#: init.lua +msgid "Junglewood" +msgstr "Lenha da selva" + +#: init.lua +msgid "Pine Wood" +msgstr "Lenha de Pinheiro" + +#: init.lua +msgid "Oak Wood" +msgstr "Lenha de Carvalho" + +#: init.lua +msgid "Birch Wood" +msgstr "Lenha de Bétula" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Lenha de Carvalho Escuro" + +#: init.lua +msgid "Spruce Wood" +msgstr "Lenha de Abeto" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Melhoria de Armário de Aço (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Melhoria de Armário de Ouro (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Melhoria de Armário de Obsidiana (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Melhoria de Armário de Diamante (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Melhoria de Armário de Ferro (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Melhoria de Armário de Esmeralda (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Melhoria de Armário de Esmeralda (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "Guarnição de Madeira" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Modelo de Melhoria de Armário" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Estado atual: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Parado" + +#: lua/controller.lua +msgid "Running" +msgstr "Ativo" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Obstruído" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Controlador de Armários" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "Vazio" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "Armário @1" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "Armários @1 (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "Armários @1 (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% cheio)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% cheio)" diff --git a/mods/drawers/locale/ru.po b/mods/drawers/locale/ru.po new file mode 100644 index 0000000..6a4eef9 --- /dev/null +++ b/mods/drawers/locale/ru.po @@ -0,0 +1,139 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2019-12-05 03:05+0000\n" +"Last-Translator: Andrei Stepanov \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 3.10-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "ДеревÑнный" + +#: init.lua +msgid "Acacia Wood" +msgstr "ÐкациÑ" + +#: init.lua +msgid "Aspen Wood" +msgstr "ОÑина" + +#: init.lua +msgid "Junglewood" +msgstr "ТропичеÑкое дерево" + +#: init.lua +msgid "Pine Wood" +msgstr "СоÑна" + +#: init.lua +msgid "Oak Wood" +msgstr "Дуб" + +#: init.lua +msgid "Birch Wood" +msgstr "Берёза" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Тёмный дуб" + +#: init.lua +msgid "Spruce Wood" +msgstr "Ель" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Стальной Ñщик Улучшение (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Золотой Ñщик Улучшение (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "ОбÑидиановый Ñщик Улучшение (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Ðлмазный Ñщик Улучшение (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Железный Ñщик Улучшение (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Изумрудный Ñщик Улучшение (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Изумрудный Ñщик Улучшение (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "ДеревÑÐ½Ð½Ð°Ñ Ð¾Ñ‚Ð´ÐµÐ»ÐºÐ°" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Шаблон ÑƒÐ»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ Ñщика" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Текущее ÑоÑтоÑние: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "оÑтановлен" + +#: lua/controller.lua +msgid "Running" +msgstr "в дейÑтвии" + +#: lua/controller.lua +msgid "Jammed" +msgstr "замкнут" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Контролер Ñщика" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "ПуÑто" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1 Ящик" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1 Ящики (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1 Ящики (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (@2% полон)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (@3% полон)" diff --git a/mods/drawers/locale/template.pot b/mods/drawers/locale/template.pot new file mode 100644 index 0000000..5e38775 --- /dev/null +++ b/mods/drawers/locale/template.pot @@ -0,0 +1,134 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "" + +#: init.lua +msgid "Acacia Wood" +msgstr "" + +#: init.lua +msgid "Aspen Wood" +msgstr "" + +#: init.lua +msgid "Junglewood" +msgstr "" + +#: init.lua +msgid "Pine Wood" +msgstr "" + +#: init.lua +msgid "Oak Wood" +msgstr "" + +#: init.lua +msgid "Birch Wood" +msgstr "" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "" + +#: init.lua +msgid "Spruce Wood" +msgstr "" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "" + +#: init.lua +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +msgid "Mithril Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +msgid "Wooden Trim" +msgstr "" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "" + +#: lua/controller.lua +msgid "Current State: " +msgstr "" + +#: lua/controller.lua +msgid "Stopped" +msgstr "" + +#: lua/controller.lua +msgid "Running" +msgstr "" + +#: lua/controller.lua +msgid "Jammed" +msgstr "" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "" diff --git a/mods/drawers/locale/tr.po b/mods/drawers/locale/tr.po new file mode 100644 index 0000000..1cb6485 --- /dev/null +++ b/mods/drawers/locale/tr.po @@ -0,0 +1,138 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2018-12-09 11:08+0000\n" +"Last-Translator: monolifed \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 3.4-dev\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "AhÅŸap" + +#: init.lua +msgid "Acacia Wood" +msgstr "Akasya AhÅŸap" + +#: init.lua +msgid "Aspen Wood" +msgstr "Kavak AhÅŸap" + +#: init.lua +msgid "Junglewood" +msgstr "Cangıl AhÅŸap" + +#: init.lua +msgid "Pine Wood" +msgstr "Çam AhÅŸap" + +#: init.lua +msgid "Oak Wood" +msgstr "MeÅŸe AhÅŸap" + +#: init.lua +msgid "Birch Wood" +msgstr "HuÅŸ AhÅŸap" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "Koyu MeÅŸe AhÅŸap" + +#: init.lua +msgid "Spruce Wood" +msgstr "Ladin AhÅŸap" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "Çelik Çekmece Yükseltme (x2)" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "Altın Çekmece Yükseltme (x3)" + +#: init.lua +#, fuzzy +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "Obsidyen Çekmece Yükseltme (x5)" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "Elmas Çekmece Yükseltme (x8)" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "Demir Çekmece Yükseltme (x2)" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "Zümrüt Çekmece Yükseltme (x13)" + +#: init.lua +#, fuzzy +msgid "Mithril Drawer Upgrade (x13)" +msgstr "Zümrüt Çekmece Yükseltme (x13)" + +#: init.lua +msgid "Wooden Trim" +msgstr "AhÅŸap Döşeme" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "Çekmece Yükseltme Åžablonu" + +#: lua/controller.lua +msgid "Current State: " +msgstr "Åžu Anki Durum: " + +#: lua/controller.lua +msgid "Stopped" +msgstr "Durdu" + +#: lua/controller.lua +msgid "Running" +msgstr "Çalışıyor" + +#: lua/controller.lua +msgid "Jammed" +msgstr "Sıkıştı" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "Çekmece Denetleyicisi" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "BoÅŸ" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "@1 Çekmece" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "@1 Çekmece (1x2)" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "@1 Çekmece (2x2)" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "@1 (%@2 dolu)" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "@1 @2 (%@3 dolu)" diff --git a/mods/drawers/locale/zh_CMN-HANT.po b/mods/drawers/locale/zh_CMN-HANT.po new file mode 100644 index 0000000..d3f4b6e --- /dev/null +++ b/mods/drawers/locale/zh_CMN-HANT.po @@ -0,0 +1,138 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: 2019-07-18 17:04+0000\n" +"Last-Translator: Elizabeth Sherrock \n" +"Language-Team: Chinese (Simplified) \n" +"Language: zh_CMN-HANT\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 3.8-dev\n" + +#: init.lua lua/api.lua +#, fuzzy +msgid "Wooden" +msgstr "木制" + +#: init.lua +msgid "Acacia Wood" +msgstr "金åˆæ¬¢æœ¨" + +#: init.lua +msgid "Aspen Wood" +msgstr "" + +#: init.lua +msgid "Junglewood" +msgstr "丛林木" + +#: init.lua +msgid "Pine Wood" +msgstr "" + +#: init.lua +msgid "Oak Wood" +msgstr "橡木" + +#: init.lua +msgid "Birch Wood" +msgstr "白桦木" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "深色橡木" + +#: init.lua +msgid "Spruce Wood" +msgstr "云æ‰æœ¨" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "" + +#: init.lua +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +msgid "Mithril Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +msgid "Wooden Trim" +msgstr "" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "" + +#: lua/controller.lua +msgid "Current State: " +msgstr "当å‰çŠ¶æ€ï¼š " + +#: lua/controller.lua +msgid "Stopped" +msgstr "å·²åœæ­¢" + +#: lua/controller.lua +msgid "Running" +msgstr "正在è¿è¡Œ" + +#: lua/controller.lua +msgid "Jammed" +msgstr "" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "" + +#: lua/api.lua lua/visual.lua +#, fuzzy +msgid "Empty" +msgstr "空的" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "" diff --git a/mods/drawers/locale/zh_Hant.po b/mods/drawers/locale/zh_Hant.po new file mode 100644 index 0000000..5057c96 --- /dev/null +++ b/mods/drawers/locale/zh_Hant.po @@ -0,0 +1,133 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-01-11 16:49+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: zh_Hant\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: init.lua lua/api.lua +msgid "Wooden" +msgstr "" + +#: init.lua +msgid "Acacia Wood" +msgstr "" + +#: init.lua +msgid "Aspen Wood" +msgstr "" + +#: init.lua +msgid "Junglewood" +msgstr "" + +#: init.lua +msgid "Pine Wood" +msgstr "" + +#: init.lua +msgid "Oak Wood" +msgstr "" + +#: init.lua +msgid "Birch Wood" +msgstr "" + +#: init.lua +msgid "Dark Oak Wood" +msgstr "" + +#: init.lua +msgid "Spruce Wood" +msgstr "" + +#: init.lua +msgid "Steel Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Gold Drawer Upgrade (x3)" +msgstr "" + +#: init.lua +msgid "Obsidian Drawer Upgrade (x4)" +msgstr "" + +#: init.lua +msgid "Diamond Drawer Upgrade (x8)" +msgstr "" + +#: init.lua +msgid "Iron Drawer Upgrade (x2)" +msgstr "" + +#: init.lua +msgid "Emerald Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +msgid "Mithril Drawer Upgrade (x13)" +msgstr "" + +#: init.lua +msgid "Wooden Trim" +msgstr "" + +#: init.lua +msgid "Drawer Upgrade Template" +msgstr "" + +#: lua/controller.lua +msgid "Current State: " +msgstr "" + +#: lua/controller.lua +msgid "Stopped" +msgstr "" + +#: lua/controller.lua +msgid "Running" +msgstr "" + +#: lua/controller.lua +msgid "Jammed" +msgstr "" + +#: lua/controller.lua +msgid "Drawer Controller" +msgstr "" + +#: lua/api.lua lua/visual.lua +msgid "Empty" +msgstr "" + +#: lua/api.lua +msgid "@1 Drawer" +msgstr "" + +#: lua/api.lua +msgid "@1 Drawers (1x2)" +msgstr "" + +#: lua/api.lua +msgid "@1 Drawers (2x2)" +msgstr "" + +#: lua/helpers.lua +msgid "@1 (@2% full)" +msgstr "" + +#: lua/helpers.lua +msgid "@1 @2 (@3% full)" +msgstr "" diff --git a/mods/drawers/lua/api.lua b/mods/drawers/lua/api.lua new file mode 100755 index 0000000..4a17a6f --- /dev/null +++ b/mods/drawers/lua/api.lua @@ -0,0 +1,346 @@ +--[[ +Minetest Mod Storage Drawers - A Mod adding storage drawers + +Copyright (C) 2017-2019 Linus Jahn +Copyright (C) 2016 Mango Tango + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]] + +-- Load support for intllib. +local MP = core.get_modpath(core.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +drawers.node_box_simple = { + {-0.5, -0.5, -0.4375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, -0.4375, 0.5, -0.4375}, + {0.4375, -0.5, -0.5, 0.5, 0.5, -0.4375}, + {-0.4375, 0.4375, -0.5, 0.4375, 0.5, -0.4375}, + {-0.4375, -0.5, -0.5, 0.4375, -0.4375, -0.4375}, +} + +drawers.drawer_formspec = "size[9,7]" .. + "list[context;upgrades;2,0.5;5,1;]" .. + "list[current_player;main;0,3;9,4;]" .. + drawers.gui_bg .. + drawers.gui_bg_img .. + drawers.gui_slots .. + drawers.get_upgrade_slots_bg(2, 0.5) + +-- construct drawer +function drawers.drawer_on_construct(pos) + local node = core.get_node(pos) + local ndef = core.registered_nodes[node.name] + local drawerType = ndef.groups.drawer + + local base_stack_max = core.nodedef_default.stack_max or 99 + local stack_max_factor = ndef.drawer_stack_max_factor or 24 -- 3x8 + stack_max_factor = math.floor(stack_max_factor / drawerType) -- drawerType => number of drawers in node + + -- meta + local meta = core.get_meta(pos) + + local i = 1 + while i <= drawerType do + local vid = i + -- 1x1 drawers don't have numbers in the meta fields + if drawerType == 1 then vid = "" end + meta:set_string("name"..vid, "") + meta:set_int("count"..vid, 0) + meta:set_int("max_count"..vid, base_stack_max * stack_max_factor) + meta:set_int("base_stack_max"..vid, base_stack_max) + meta:set_string("entity_infotext"..vid, drawers.gen_info_text(S("Empty"), 0, + stack_max_factor, base_stack_max)) + meta:set_int("stack_max_factor"..vid, stack_max_factor) + + i = i + 1 + end + + -- spawn all visuals + drawers.spawn_visuals(pos) + + -- create drawer upgrade inventory + meta:get_inventory():set_size("upgrades", 5) + + -- set the formspec + meta:set_string("formspec", drawers.drawer_formspec) +end + +-- destruct drawer +function drawers.drawer_on_destruct(pos) + drawers.remove_visuals(pos) + + -- clean up visual cache + if drawers.drawer_visuals[core.serialize(pos)] then + drawers.drawer_visuals[core.serialize(pos)] = nil + end +end + +-- drop all items +function drawers.drawer_on_dig(pos, node, player) + local drawerType = 1 + if core.registered_nodes[node.name] then + drawerType = core.registered_nodes[node.name].groups.drawer + end + if core.is_protected(pos,player:get_player_name()) then + core.record_protection_violation(pos,player:get_player_name()) + return 0 + end + local meta = core.get_meta(pos) + + local k = 1 + while k <= drawerType do + -- don't add a number in meta fields for 1x1 drawers + local vid = tostring(k) + if drawerType == 1 then vid = "" end + local count = meta:get_int("count"..vid) + local name = meta:get_string("name"..vid) + + -- drop the items + local stack_max = ItemStack(name):get_stack_max() + + local j = math.floor(count / stack_max) + 1 + local i = 1 + while i <= j do + local rndpos = drawers.randomize_pos(pos) + if not (i == j) then + core.add_item(rndpos, name .. " " .. stack_max) + else + core.add_item(rndpos, name .. " " .. count % stack_max) + end + i = i + 1 + end + k = k + 1 + end + + -- drop all drawer upgrades + local upgrades = meta:get_inventory():get_list("upgrades") + if upgrades then + for _,itemStack in pairs(upgrades) do + if itemStack:get_count() > 0 then + local rndpos = drawers.randomize_pos(pos) + core.add_item(rndpos, itemStack:get_name()) + end + end + end + + -- remove node + core.node_dig(pos, node, player) +end + +function drawers.drawer_allow_metadata_inventory_put(pos, listname, index, stack, player) + if core.is_protected(pos,player:get_player_name()) then + core.record_protection_violation(pos,player:get_player_name()) + return 0 + end + if listname ~= "upgrades" then + return 0 + end + if stack:get_count() > 1 then + return 0 + end + if core.get_item_group(stack:get_name(), "drawer_upgrade") < 1 then + return 0 + end + return 1 +end + +function drawers.add_drawer_upgrade(pos, listname, index, stack, player) + -- only do anything if adding to upgrades + if listname ~= "upgrades" then return end + + drawers.update_drawer_upgrades(pos) +end + +function drawers.remove_drawer_upgrade(pos, listname, index, stack, player) + -- only do anything if adding to upgrades + if listname ~= "upgrades" then return end + + drawers.update_drawer_upgrades(pos) +end + +function drawers.drawer_insert_object(pos, node, stack, direction) + local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)] + if not drawer_visuals then return stack end + + -- first try to insert in the correct slot (if there are already items) + local leftover = stack + for _, visual in pairs(drawer_visuals) do + if visual.itemName == stack:get_name() then + leftover = visual:try_insert_stack(leftover, true) + end + end + + -- if there's still something left, also use other slots + if leftover:get_count() > 0 then + for _, visual in pairs(drawer_visuals) do + leftover = visual:try_insert_stack(leftover, true) + end + end + return leftover +end + +function drawers.drawer_can_insert_object(pos, node, stack, direction) + local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)] + if not drawer_visuals then return false end + + + for _, visual in pairs(drawer_visuals) do + if visual.itemName == "" or (visual.itemName == stack:get_name() and visual.count ~= visual.maxCount) then + return true + end + end + return false +end + +function drawers.register_drawer(name, def) + def.description = def.description or S("Wooden") + def.drawtype = "nodebox" + def.node_box = {type = "fixed", fixed = drawers.node_box_simple} + def.collision_box = {type = "regular"} + def.selection_box = {type = "fixed", fixed = drawers.node_box_simple} + def.paramtype = "light" + def.paramtype2 = "facedir" + def.legacy_facedir_simple = true + def.groups = def.groups or {} + def.drawer_stack_max_factor = def.drawer_stack_max_factor or 24 + + -- events + def.on_construct = drawers.drawer_on_construct + def.on_destruct = drawers.drawer_on_destruct + def.on_dig = drawers.drawer_on_dig + def.allow_metadata_inventory_put = drawers.drawer_allow_metadata_inventory_put + def.allow_metadata_inventory_take = drawers.drawer_allow_metadata_inventory_put + def.on_metadata_inventory_put = drawers.add_drawer_upgrade + def.on_metadata_inventory_take = drawers.remove_drawer_upgrade + + if minetest.get_modpath("screwdriver") and screwdriver then + def.on_rotate = def.on_rotate or screwdriver.disallow + end + + if minetest.get_modpath("pipeworks") and pipeworks then + def.groups.tubedevice = 1 + def.groups.tubedevice_receiver = 1 + def.tube = def.tube or {} + def.tube.insert_object = def.tube.insert_object or + drawers.drawer_insert_object + def.tube.can_insert = def.tube.can_insert or + drawers.drawer_can_insert_object + + def.tube.connect_sides = {left = 1, right = 1, back = 1, top = 1, + bottom = 1} + def.after_place_node = pipeworks.after_place + def.after_dig_node = pipeworks.after_dig + end + + if drawers.enable_1x1 then + -- normal drawer 1x1 = 1 + local def1 = table.copy(def) + def1.description = S("@1 Drawer", def.description) + def1.tiles = def.tiles or def.tiles1 + def1.tiles1 = nil + def1.tiles2 = nil + def1.tiles4 = nil + def1.groups.drawer = 1 + core.register_node(name .. "1", def1) + core.register_alias(name, name .. "1") -- 1x1 drawer is the default one + end + + if drawers.enable_1x2 then + -- 1x2 = 2 + local def2 = table.copy(def) + def2.description = S("@1 Drawers (1x2)", def.description) + def2.tiles = def.tiles2 + def2.tiles1 = nil + def2.tiles2 = nil + def2.tiles4 = nil + def2.groups.drawer = 2 + core.register_node(name .. "2", def2) + end + + if drawers.enable_2x2 then + -- 2x2 = 4 + local def4 = table.copy(def) + def4.description = S("@1 Drawers (2x2)", def.description) + def4.tiles = def.tiles4 + def4.tiles1 = nil + def4.tiles2 = nil + def4.tiles4 = nil + def4.groups.drawer = 4 + core.register_node(name .. "4", def4) + end + + if (not def.no_craft) and def.material then + if drawers.enable_1x1 then + core.register_craft({ + output = name .. "1", + recipe = { + {def.material, def.material, def.material}, + { "", drawers.CHEST_ITEMSTRING, "" }, + {def.material, def.material, def.material} + } + }) + end + if drawers.enable_1x2 then + core.register_craft({ + output = name .. "2 2", + recipe = { + {def.material, drawers.CHEST_ITEMSTRING, def.material}, + {def.material, def.material, def.material}, + {def.material, drawers.CHEST_ITEMSTRING, def.material} + } + }) + end + if drawers.enable_2x2 then + core.register_craft({ + output = name .. "4 4", + recipe = { + {drawers.CHEST_ITEMSTRING, def.material, drawers.CHEST_ITEMSTRING}, + { def.material, def.material, def.material }, + {drawers.CHEST_ITEMSTRING, def.material, drawers.CHEST_ITEMSTRING} + } + }) + end + end +end + +function drawers.register_drawer_upgrade(name, def) + def.groups = def.groups or {} + def.groups.drawer_upgrade = def.groups.drawer_upgrade or 100 + def.inventory_image = def.inventory_image or "drawers_upgrade_template.png" + def.stack_max = 1 + + local recipe_item = def.recipe_item or "air" + def.recipe_item = nil + + core.register_craftitem(name, def) + + if not def.no_craft then + core.register_craft({ + output = name, + recipe = { + {recipe_item, "group:stick", recipe_item}, + {"group:stick", "drawers:upgrade_template", "group:stick"}, + {recipe_item, "group:stick", recipe_item} + } + }) + end +end diff --git a/mods/drawers/lua/controller.lua b/mods/drawers/lua/controller.lua new file mode 100644 index 0000000..2983859 --- /dev/null +++ b/mods/drawers/lua/controller.lua @@ -0,0 +1,555 @@ +--[[ +Minetest Mod Storage Drawers - A Mod adding storage drawers + +Copyright (C) 2017-2019 Linus Jahn +Copyright (C) 2018 isaiah658 + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]]-- + +--[[ The gist of how the drawers mod stores data is that there are entities +and the drawer node itself. The entities are needed to allow having multiple +drawers in one node. The entities and node each store metadata about the item +counts and such. It is necessary to change both at once otherwise in some cases +the entity values are used and in other cases the node metadata is used. + +The gist of how the controller works is this. The drawer controller scans the +adjacent tiles and puts the item names and other info such as coordinates and +the visualid of the entity in a table. That table is saved in the controllers +metadata. The table is used to help prevent needing to scan all the drawers to +deposit an item in certain situations. The table is only updated on an as needed +basis, not by a specific time/interval. Controllers that have no items will not +continue scanning drawers. ]]-- + +-- Load support for intllib. +local MP = core.get_modpath(core.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +local default_loaded = core.get_modpath("default") and default +local mcl_loaded = core.get_modpath("mcl_core") and mcl_core +local pipeworks_loaded = core.get_modpath("pipeworks") and pipeworks + +local controller_interval = tonumber(core.settings:get("drawers_controller_interval")) or 1.0 + +local function controller_formspec(pos, meta_current_state) + local formspec = + "size[8,8.5]".. + drawers.gui_bg.. + drawers.gui_bg_img.. + drawers.gui_slots.. + "label[0,0;" .. S("Current State: ") .. meta_current_state .. "]" .. + "list[current_name;src;3.5,1.75;1,1;]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "listring[current_player;main]".. + "listring[current_name;src]".. + "listring[current_player;main]" + return formspec +end + +local function controller_index_slot(pos, visualid) + return { + drawer_pos_x = pos.x, + drawer_pos_y = pos.y, + drawer_pos_z = pos.z, + visualid = visualid + } +end + +local function compare_pos(pos1, pos2) + return pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z +end + +local function contains_pos(list, p) + for _,v in ipairs(list) do + if compare_pos(v, p) then + return true + end + end + return false +end + +-- iterator for iterating from 1 -> to +local function range(to) + local i = 0 + return function() + if i == to then + return nil + end + i = i + 1 + return i, i + end +end + +local function pos_in_range(pos1, pos2) + local diff = { + pos1.x - pos2.x, + pos1.y - pos2.y, + pos1.z - pos2.z + } + for _,v in ipairs(diff) do + if v < 0 then + v = v * -1 + end + if v > drawers.CONTROLLER_RANGE then + return false + end + end + return true +end + +local function add_drawer_to_inventory(controllerInventory, pos) + -- the number of slots is saved as drawer group + local slots = core.get_item_group(core.get_node(pos).name, "drawer") + if not slots then + return + end + + local meta = core.get_meta(pos) + if not meta then + return + end + + local i = 1 + while i <= slots do + -- nothing is appended in case the drawer has only one slot + local slot_id = "" + if slots ~= 1 then + slot_id = tostring(i) + end + + local item_id = meta:get_string("name" .. slot_id) + local drawer_meta_entity_infotext = meta:get_string("entity_infotext" .. slot_id) + + if item_id == "" and not controllerInventory["empty"] then + controllerInventory["empty"] = controller_index_slot(pos, slot_id) + elseif item_id ~= "" then + -- If we already indexed this item previously, check which drawer + -- has the most space and have that one be the one indexed + if controllerInventory[item_id] then + local indexed_drawer_meta = core.get_meta({ + x = controllerInventory[item_id]["drawer_pos_x"], + y = controllerInventory[item_id]["drawer_pos_y"], + z = controllerInventory[item_id]["drawer_pos_z"]} + ) + local indexed_drawer_meta_count = indexed_drawer_meta:get_int( + "count" .. controllerInventory[item_id]["visualid"]) + local indexed_drawer_meta_max_count = indexed_drawer_meta:get_int( + "max_count" .. controllerInventory[item_id]["visualid"]) + + local drawer_meta_count = meta:get_int("count" .. slot_id) + local drawer_meta_max_count = meta:get_int("max_count" .. slot_id) + + -- If the already indexed drawer has less space, we override the table index for that item with the new drawer + if (indexed_drawer_meta_max_count - indexed_drawer_meta_count) + < (drawer_meta_max_count - drawer_meta_count) then + controllerInventory[item_id] = controller_index_slot(pos, slot_id) + end + else + controllerInventory[item_id] = controller_index_slot(pos, slot_id) + end + end + + i = i + 1 + end +end + +local function find_connected_drawers(controller_pos, pos, foundPositions) + foundPositions = foundPositions or {} + pos = pos or controller_pos + + local newPositions = core.find_nodes_in_area( + {x = pos.x - 1, y = pos.y - 1, z = pos.z - 1}, + {x = pos.x + 1, y = pos.y + 1, z = pos.z + 1}, + {"group:drawer", "group:drawer_connector"} + ) + + for _,p in ipairs(newPositions) do + -- check that this node hasn't been scanned yet + if not compare_pos(pos, p) and not contains_pos(foundPositions, p) + and pos_in_range(controller_pos, pos) then + -- add new position + table.insert(foundPositions, p) + -- search for other drawers from the new pos + find_connected_drawers(controller_pos, p, foundPositions) + end + end + + return foundPositions +end + +local function index_drawers(pos) + --[[ + The pos parameter is the controllers position + + We store the item name as a string key and the value is a table with position x, + position y, position z, and visualid. Those are all strings as well with the + values assigned to them that way we don't need to worry about the ordering of + the table. The count and max count are not stored as those values have a high + potential of being outdated quickly. It's better to grab the values from the + drawer when needed so you know you are working with accurate numbers. + ]] + + local controllerInventory = {} + for _,drawerPos in ipairs(find_connected_drawers(pos)) do + add_drawer_to_inventory(controllerInventory, drawerPos) + end + + return controllerInventory +end + +local function controller_node_timer(pos, elapsed) + -- Inizialize metadata + local meta = core.get_meta(pos) + local meta_current_state = meta:get_string("current_state") + local meta_times_ran_while_jammed = meta:get_float("times_ran_while_jammed") + local meta_jammed_item_name = meta:get_string("jammed_item_name") + local inv = meta:get_inventory() + local src = inv:get_stack("src", 1) + local src_name = src:get_name() + + --[[ + There are four scenarios for the item slot in the controller. + 1: No item is in the controller. + 2: Item is not stackable. + 3. Item is allowed and there is either an existing drawer for that item with room or an empty drawer. + 4: Item is allowed, but there is no room. + + There are three different possibilities for "current_state". + 1: "running" which means means it's operating normally. + 2: "stopped" meaning the controller makes no attempt to put in the item possibly due to being unallowed for various reasons. + 3: "jammed" meaning the item is allowed in to drawers, but there was no space to deposit it last time it ran. + ]] + + --[[ + If current state is jammed, the item that jammed it is the same item in the + src inv slot, and the amount of times ran while jammed is 8 or higher, we + set the current state to stopped. Will possibly want to make an option in the + formspec to ignore this an continue running if the user plans on using the + system in a way that may cause frequent jams making it a hassle to manually + clear it each time + ]] + if meta_current_state == "jammed" and meta_jammed_item_name == src_name and meta_times_ran_while_jammed >= 2 then + meta:set_string("current_state", "stopped") + meta:set_string("formspec", controller_formspec(pos, S("Stopped"))) + return true + end + + -- If current state is stopped, and the item that jammed it is the same + -- item in the src inv slot, we don't do anything + if meta_current_state == "stopped" and meta_jammed_item_name == src_name then + return true + end + + -- If current state is stopped, and the item that jammed it is not the + -- same item in the src inv slot, we set the current state to running and + -- clear the jam counter. + if meta_current_state == "stopped" and meta_jammed_item_name ~= src_name then + meta:set_string("current_state", "running") + meta:set_string("formspec", controller_formspec(pos, S("Running"))) + meta:set_float("times_ran_while_jammed", 0) + end + + -- If no item is in the controller, nothing is searched and current_state + -- is set to running and no jams. + if inv:is_empty("src") then + meta:set_string("current_state", "running") + meta:set_string("formspec", controller_formspec(pos, S("Running"))) + meta:set_float("times_ran_while_jammed", 0) + return true + end + + -- If a non stackable item is in the controller, such as a written book, + -- set the current_state to stopped because they are not allowed in drawers + if src:get_stack_max() == 1 then + meta:set_string("current_state", "stopped") + meta:set_string("formspec", controller_formspec(pos, S("Stopped"))) + meta:set_string("jammed_item_name", src_name) + meta:set_float("times_ran_while_jammed", 1) + return true + end + + -- If the index has not been created, the item isn't in the index, the + -- item in the drawer is no longer the same item in the index, or the item + -- is in the index but it's full, run the index_drawers function. + local drawers_table_index = core.deserialize(meta:get_string("drawers_table_index")) + + -- If the index has not been created + if not drawers_table_index then + drawers_table_index = index_drawers(pos) + meta:set_string("drawers_table_index", core.serialize(drawers_table_index)) + + -- If the item isn't in the index + elseif not drawers_table_index[src_name] then + drawers_table_index = index_drawers(pos) + meta:set_string("drawers_table_index", core.serialize(drawers_table_index)) + + -- If the item is in the index but either the name that was indexed is not + -- the same as what is currently in the drawer or the drawer is full + elseif drawers_table_index[src_name] then + local visualid = drawers_table_index[src_name]["visualid"] + local indexed_drawer_meta = core.get_meta({x = drawers_table_index[src_name]["drawer_pos_x"], y = drawers_table_index[src_name]["drawer_pos_y"], z = drawers_table_index[src_name]["drawer_pos_z"]}) + local indexed_drawer_meta_name = indexed_drawer_meta:get_string("name" .. visualid) + local indexed_drawer_meta_count = indexed_drawer_meta:get_int("count" .. visualid) + local indexed_drawer_meta_max_count = indexed_drawer_meta:get_int("max_count" .. visualid) + if indexed_drawer_meta_name ~= src_name or indexed_drawer_meta_count >= indexed_drawer_meta_max_count then + drawers_table_index = index_drawers(pos) + meta:set_string("drawers_table_index", core.serialize(drawers_table_index)) + end + end + + -- This might not be needed, but my concern is if the above indexing takes + -- enough time, there could be a "race condition" where the item in the src + -- inventory is no longer the same item when we checked before or the + -- quantity of the items changed so I'm having it grab the item stack again + -- just in case. + -- If a race condition does occur, items could be lost or duplicated + src = inv:get_stack("src", 1) + src_name = src:get_name() + local src_count = src:get_count() + local src_stack_max = src:get_stack_max() + + -- At this point, the item either was in the index or everything was reindexed so we check again + -- If there is a drawer with the item and it isn't full, we will put the items we can in to it + if drawers_table_index[src_name] then + local indexed_drawer_pos = {x = drawers_table_index[src_name]["drawer_pos_x"], y = drawers_table_index[src_name]["drawer_pos_y"], z = drawers_table_index[src_name]["drawer_pos_z"]} + local visualid = drawers_table_index[src_name]["visualid"] + local indexed_drawer_meta = core.get_meta(indexed_drawer_pos) + local indexed_drawer_meta_name = indexed_drawer_meta:get_string("name" .. visualid) + local indexed_drawer_meta_count = indexed_drawer_meta:get_int("count" .. visualid) + local indexed_drawer_meta_max_count = indexed_drawer_meta:get_int("max_count" .. visualid) + -- If the the item in the drawer is the same as the one we are trying to store, the drawer is not full, and the drawer entity is loaded, we will put the items in the drawer + if indexed_drawer_meta_name == src_name and indexed_drawer_meta_count < indexed_drawer_meta_max_count and drawers.drawer_visuals[core.serialize(indexed_drawer_pos)] then + local leftover = drawers.drawer_insert_object(indexed_drawer_pos, nil, src, nil) + inv:set_stack("src", 1, leftover) + -- Set the controller metadata + meta:set_string("current_state", "running") + meta:set_string("formspec", controller_formspec(pos, S("Running"))) + meta:set_float("times_ran_while_jammed", 0) + else + meta:set_string("current_state", "jammed") + meta:set_string("formspec", controller_formspec(pos, S("Jammed"))) + meta:set_string("jammed_item_name", src_name) + meta:set_float("times_ran_while_jammed", meta_times_ran_while_jammed + 1) + end + elseif drawers_table_index["empty"] then + local indexed_drawer_pos = {x = drawers_table_index["empty"]["drawer_pos_x"], y = drawers_table_index["empty"]["drawer_pos_y"], z = drawers_table_index["empty"]["drawer_pos_z"]} + local visualid = drawers_table_index["empty"]["visualid"] + local indexed_drawer_meta = core.get_meta(indexed_drawer_pos) + local indexed_drawer_meta_name = indexed_drawer_meta:get_string("name" .. visualid) + -- If the drawer is still empty and the drawer entity is loaded, we will put the items in the drawer + if indexed_drawer_meta_name == "" and drawers.drawer_visuals[core.serialize(indexed_drawer_pos)] then + local leftover = drawers.drawer_insert_object(indexed_drawer_pos, nil, src, nil) + inv:set_stack("src", 1, leftover) + -- Add the item to the drawers table index and set the empty one to nil + drawers_table_index["empty"] = nil + drawers_table_index[src_name] = {drawer_pos_x = indexed_drawer_pos.x, drawer_pos_y = indexed_drawer_pos.y, drawer_pos_z = indexed_drawer_pos.z, visualid = visualid} + -- Set the controller metadata + meta:set_string("current_state", "running") + meta:set_string("formspec", controller_formspec(pos, S("Running"))) + meta:set_float("times_ran_while_jammed", 0) + meta:set_string("drawers_table_index", core.serialize(drawers_table_index)) + else + meta:set_string("current_state", "jammed") + meta:set_string("formspec", controller_formspec(pos, S("Jammed"))) + meta:set_string("jammed_item_name", src_name) + meta:set_float("times_ran_while_jammed", meta_times_ran_while_jammed + 1) + end + else + meta:set_string("current_state", "jammed") + meta:set_string("formspec", controller_formspec(pos, S("Jammed"))) + meta:set_string("jammed_item_name", src_name) + meta:set_float("times_ran_while_jammed", meta_times_ran_while_jammed + 1) + end + + return true +end + +local function controller_can_dig(pos, player) + local meta = core.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("src") +end + +local function controller_on_construct(pos) + local meta = core.get_meta(pos) + meta:set_string("current_state", "running") + meta:set_float("times_ran_while_jammed", 0) + meta:set_string("jammed_item_name", "") + meta:set_string("drawers_table_index", "") + meta:set_string("formspec", controller_formspec(pos, S("Running"))) + + meta:get_inventory():set_size("src", 1) + + core.get_node_timer(pos):start(controller_interval) +end + +local function controller_on_blast(pos) + local drops = {} + default.get_inventory_drops(pos, "src", drops) + drops[#drops+1] = "drawers:controller" + core.remove_node(pos) + return drops +end + +local function controller_allow_metadata_inventory_put(pos, listname, index, stack, player) + if core.is_protected(pos, player:get_player_name()) then + return 0 + end + if listname == "src" then + return stack:get_count() + end +end + +local function controller_allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = core.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return controller_allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function controller_allow_metadata_inventory_take(pos, listname, index, stack, player) + if core.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() +end + +-- Registers the drawer controller +local function register_controller() + -- Set the controller definition using a table to allow for pipeworks and + -- potentially other mod support + local def = {} + + def.description = S("Drawer Controller") + def.drawtype = "nodebox" + def.node_box = { type = "fixed", fixed = drawers.node_box_simple } + def.collision_box = { type = "regular" } + def.selection_box = { type = "regular" } + def.paramtype = "light" + def.paramtype2 = "facedir" + def.legacy_facedir_simple = true + + -- add pipe connectors, if pipeworks is enabled + if pipeworks_loaded then + def.tiles = { + "drawers_controller_top.png^pipeworks_tube_connection_metallic.png", + "drawers_controller_top.png^pipeworks_tube_connection_metallic.png", + "drawers_controller_side.png^pipeworks_tube_connection_metallic.png", + "drawers_controller_side.png^pipeworks_tube_connection_metallic.png", + "drawers_controller_top.png^pipeworks_tube_connection_metallic.png", + "drawers_controller_front.png" + } + else + def.tiles = { + "drawers_controller_top.png", + "drawers_controller_top.png", + "drawers_controller_side.png", + "drawers_controller_side.png", + "drawers_controller_top.png", + "drawers_controller_front.png" + } + end + + -- MCL2 requires a few different groups and parameters that MTG does not + if mcl_loaded then + def.groups = { + pickaxey = 1, stone = 1, building_block = 1, material_stone = 1 + } + def._mcl_blast_resistance = 30 + def._mcl_hardness = 1.5 + else + def.groups = { + cracky = 3, level = 2 + } + end + + def.can_dig = controller_can_dig + def.on_construct = controller_on_construct + def.on_blast = controller_on_blast + def.on_timer = controller_node_timer + + def.allow_metadata_inventory_put = controller_allow_metadata_inventory_put + def.allow_metadata_inventory_move = controller_allow_metadata_inventory_move + def.allow_metadata_inventory_take = controller_allow_metadata_inventory_take + + if pipeworks_loaded then + def.groups.tubedevice = 1 + def.groups.tubedevice_receiver = 1 + + def.tube = {} + def.tube.insert_object = function(pos, node, stack, tubedir) + -- add stack to inventory + local remaining_stack = core.get_meta(pos):get_inventory():add_item("src", stack) + -- kick off controller work + controller_node_timer(pos) + + return remaining_stack + end + + def.tube.can_insert = function(pos, node, stack, tubedir) + return core.get_meta(pos):get_inventory():room_for_item("src", stack) + end + + def.tube.connect_sides = { + left = 1, right = 1, back = 1, top = 1, bottom = 1 + } + + def.after_place_node = pipeworks.after_place + def.after_dig_node = pipeworks.after_dig + end + + core.register_node("drawers:controller", def) +end + +-- register drawer controller +register_controller() + +if default_loaded then + core.register_craft({ + output = 'drawers:controller', + recipe = { + {'default:steel_ingot', 'default:diamond', 'default:steel_ingot'}, + {'default:tin_ingot', 'group:drawer', 'default:copper_ingot'}, + {'default:steel_ingot', 'default:diamond', 'default:steel_ingot'}, + } + }) +elseif mcl_loaded then + core.register_craft({ + output = 'drawers:controller', + recipe = { + {'mcl_core:iron_ingot', 'mcl_core:diamond', 'mcl_core:iron_ingot'}, + {'mcl_core:gold_ingot', 'group:drawer', 'mcl_core:gold_ingot'}, + {'mcl_core:iron_ingot', 'mcl_core:diamond', 'mcl_core:iron_ingot'}, + } + }) +else + -- Because the rest of the drawers mod doesn't have a hard depend on + -- default, I changed the recipe to have an alternative + core.register_craft({ + output = 'drawers:controller', + recipe = { + {'group:stone', 'group:stone', 'group:stone'}, + {'group:stone', 'group:drawer', 'group:stone'}, + {'group:stone', 'group:stone', 'group:stone'}, + } + }) +end diff --git a/mods/drawers/lua/helpers.lua b/mods/drawers/lua/helpers.lua new file mode 100755 index 0000000..0aaa15b --- /dev/null +++ b/mods/drawers/lua/helpers.lua @@ -0,0 +1,258 @@ +--[[ +Minetest Mod Storage Drawers - A Mod adding storage drawers + +Copyright (C) 2017-2019 Linus Jahn +Copyright (C) 2016 Mango Tango + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]] + +-- Load support for intllib. +local MP = core.get_modpath(core.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +-- GUI +function drawers.get_upgrade_slots_bg(x,y) + local out = "" + for i = 0, 4, 1 do + out = out .."image["..x+i..","..y..";1,1;drawers_upgrade_slot_bg.png]" + end + return out +end + +function drawers.gen_info_text(basename, count, factor, stack_max) + local maxCount = stack_max * factor + local percent = count / maxCount * 100 + -- round the number (float -> int) + percent = math.floor(percent + 0.5) + + if count == 0 then + return S("@1 (@2% full)", basename, tostring(percent)) + else + return S("@1 @2 (@3% full)", tostring(count), basename, tostring(percent)) + end +end + +function drawers.get_inv_image(name) + local texture = "blank.png" + local def = core.registered_items[name] + if not def then return end + + if def.inventory_image and #def.inventory_image > 0 then + texture = def.inventory_image + else + if not def.tiles then return texture end + local tiles = table.copy(def.tiles) + + for k,v in pairs(tiles) do + if type(v) == "table" then + tiles[k] = v.name + end + end + + -- tiles: up, down, right, left, back, front + -- inventorycube: up, front, right + if #tiles <= 2 then + texture = core.inventorycube(tiles[1], tiles[1], tiles[1]) + elseif #tiles <= 5 then + texture = core.inventorycube(tiles[1], tiles[3], tiles[3]) + else -- full tileset + texture = core.inventorycube(tiles[1], tiles[6], tiles[3]) + end + end + + return texture +end + +function drawers.spawn_visuals(pos) + local node = core.get_node(pos) + local ndef = core.registered_nodes[node.name] + local drawerType = ndef.groups.drawer + + -- data for the new visual + drawers.last_drawer_pos = pos + drawers.last_drawer_type = drawerType + + if drawerType == 1 then -- 1x1 drawer + drawers.last_visual_id = "" + drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name")) + + local bdir = core.facedir_to_dir(node.param2) + local fdir = vector.new(-bdir.x, 0, -bdir.z) + local pos2 = vector.add(pos, vector.multiply(fdir, 0.45)) + + local obj = core.add_entity(pos2, "drawers:visual") + + if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end + if bdir.z < 0 then obj:set_yaw(math.pi) end + if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end + + drawers.last_texture = nil + elseif drawerType == 2 then + local bdir = core.facedir_to_dir(node.param2) + + local fdir1 + local fdir2 + if node.param2 == 2 or node.param2 == 0 then + fdir1 = vector.new(-bdir.x, 0.5, -bdir.z) + fdir2 = vector.new(-bdir.x, -0.5, -bdir.z) + else + fdir1 = vector.new(-bdir.x, 0.5, -bdir.z) + fdir2 = vector.new(-bdir.x, -0.5, -bdir.z) + end + + local objs = {} + + drawers.last_visual_id = 1 + drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name1")) + local pos1 = vector.add(pos, vector.multiply(fdir1, 0.45)) + objs[1] = core.add_entity(pos1, "drawers:visual") + + drawers.last_visual_id = 2 + drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name2")) + local pos2 = vector.add(pos, vector.multiply(fdir2, 0.45)) + objs[2] = core.add_entity(pos2, "drawers:visual") + + for i,obj in pairs(objs) do + if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end + if bdir.z < 0 then obj:set_yaw(math.pi) end + if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end + end + else -- 2x2 drawer + local bdir = core.facedir_to_dir(node.param2) + + local fdir1 + local fdir2 + local fdir3 + local fdir4 + if node.param2 == 2 then + fdir1 = vector.new(-bdir.x + 0.5, 0.5, -bdir.z) + fdir2 = vector.new(-bdir.x - 0.5, 0.5, -bdir.z) + fdir3 = vector.new(-bdir.x + 0.5, -0.5, -bdir.z) + fdir4 = vector.new(-bdir.x - 0.5, -0.5, -bdir.z) + elseif node.param2 == 0 then + fdir1 = vector.new(-bdir.x - 0.5, 0.5, -bdir.z) + fdir2 = vector.new(-bdir.x + 0.5, 0.5, -bdir.z) + fdir3 = vector.new(-bdir.x - 0.5, -0.5, -bdir.z) + fdir4 = vector.new(-bdir.x + 0.5, -0.5, -bdir.z) + elseif node.param2 == 1 then + fdir1 = vector.new(-bdir.x, 0.5, -bdir.z + 0.5) + fdir2 = vector.new(-bdir.x, 0.5, -bdir.z - 0.5) + fdir3 = vector.new(-bdir.x, -0.5, -bdir.z + 0.5) + fdir4 = vector.new(-bdir.x, -0.5, -bdir.z - 0.5) + else + fdir1 = vector.new(-bdir.x, 0.5, -bdir.z - 0.5) + fdir2 = vector.new(-bdir.x, 0.5, -bdir.z + 0.5) + fdir3 = vector.new(-bdir.x, -0.5, -bdir.z - 0.5) + fdir4 = vector.new(-bdir.x, -0.5, -bdir.z + 0.5) + end + + local objs = {} + + drawers.last_visual_id = 1 + drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name1")) + local pos1 = vector.add(pos, vector.multiply(fdir1, 0.45)) + objs[1] = core.add_entity(pos1, "drawers:visual") + + drawers.last_visual_id = 2 + drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name2")) + local pos2 = vector.add(pos, vector.multiply(fdir2, 0.45)) + objs[2] = core.add_entity(pos2, "drawers:visual") + + drawers.last_visual_id = 3 + drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name3")) + local pos3 = vector.add(pos, vector.multiply(fdir3, 0.45)) + objs[3] = core.add_entity(pos3, "drawers:visual") + + drawers.last_visual_id = 4 + drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name4")) + local pos4 = vector.add(pos, vector.multiply(fdir4, 0.45)) + objs[4] = core.add_entity(pos4, "drawers:visual") + + + for i,obj in pairs(objs) do + if bdir.x < 0 then obj:set_yaw(0.5 * math.pi) end + if bdir.z < 0 then obj:set_yaw(math.pi) end + if bdir.x > 0 then obj:set_yaw(1.5 * math.pi) end + end + end +end + +function drawers.remove_visuals(pos) + local objs = core.get_objects_inside_radius(pos, 0.58) + if not objs then return end + + for _, obj in pairs(objs) do + if obj and obj:get_luaentity() and + obj:get_luaentity().name == "drawers:visual" then + obj:remove() + end + end +end + +function drawers.update_drawer_upgrades(pos) + local node = core.get_node(pos) + local ndef = core.registered_nodes[node.name] + local drawerType = ndef.groups.drawer + + -- default number of slots/stacks + local stackMaxFactor = ndef.drawer_stack_max_factor + + -- storage percent with all upgrades + local storagePercent = 100 + + -- get info of all upgrades + local inventory = core.get_meta(pos):get_inventory():get_list("upgrades") + for _,itemStack in pairs(inventory) do + local iname = itemStack:get_name() + local idef = core.registered_items[iname] + local addPercent = idef.groups.drawer_upgrade or 0 + + storagePercent = storagePercent + addPercent + end + + -- i.e.: 150% / 100 => 1.50 + stackMaxFactor = math.floor(stackMaxFactor * (storagePercent / 100)) + -- calculate stack_max factor for a single drawer + stackMaxFactor = stackMaxFactor / drawerType + + -- set the new stack max factor in all visuals + local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)] + if not drawer_visuals then return end + + for _,visual in pairs(drawer_visuals) do + visual:setStackMaxFactor(stackMaxFactor) + end +end + +function drawers.randomize_pos(pos) + local rndpos = table.copy(pos) + local x = math.random(-50, 50) * 0.01 + local z = math.random(-50, 50) * 0.01 + rndpos.x = rndpos.x + x + rndpos.y = rndpos.y + 0.25 + rndpos.z = rndpos.z + z + return rndpos +end + +function drawers.node_tiles_front_other(front, other) + return {other, other, other, other, other, front} +end diff --git a/mods/drawers/lua/visual.lua b/mods/drawers/lua/visual.lua new file mode 100755 index 0000000..2fb2c18 --- /dev/null +++ b/mods/drawers/lua/visual.lua @@ -0,0 +1,455 @@ +--[[ +Minetest Mod Storage Drawers - A Mod adding storage drawers + +Copyright (C) 2017-2019 Linus Jahn + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +]] + +-- Load support for intllib. +local MP = core.get_modpath(core.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") + +core.register_entity("drawers:visual", { + initial_properties = { + hp_max = 1, + physical = false, + collide_with_objects = false, + collisionbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0}, -- for param2 0, 2 + visual = "upright_sprite", -- "wielditem" for items without inv img? + visual_size = {x = 0.6, y = 0.6}, + textures = {"blank.png"}, + spritediv = {x = 1, y = 1}, + initial_sprite_basepos = {x = 0, y = 0}, + is_visible = true, + }, + + get_staticdata = function(self) + return core.serialize({ + drawer_posx = self.drawer_pos.x, + drawer_posy = self.drawer_pos.y, + drawer_posz = self.drawer_pos.z, + texture = self.texture, + drawerType = self.drawerType, + visualId = self.visualId + }) + end, + + on_activate = function(self, staticdata, dtime_s) + -- Restore data + local data = core.deserialize(staticdata) + if data then + self.drawer_pos = { + x = data.drawer_posx, + y = data.drawer_posy, + z = data.drawer_posz, + } + self.texture = data.texture + self.drawerType = data.drawerType or 1 + self.visualId = data.visualId or "" + + -- backwards compatibility + if self.texture == "drawers_empty.png" then + self.texture = "blank.png" + end + else + self.drawer_pos = drawers.last_drawer_pos + self.texture = drawers.last_texture or "blank.png" + self.visualId = drawers.last_visual_id + self.drawerType = drawers.last_drawer_type + end + + local node = minetest.get_node(self.object:get_pos()) + if not node.name:match("^drawers:") then + self.object:remove() + return + end + + -- add self to public drawer visuals + -- this is needed because there is no other way to get this class + -- only the underlying LuaEntitySAO + -- PLEASE contact me, if this is wrong + local vId = self.visualId + if vId == "" then vId = 1 end + local posstr = core.serialize(self.drawer_pos) + if not drawers.drawer_visuals[posstr] then + drawers.drawer_visuals[posstr] = {[vId] = self} + else + drawers.drawer_visuals[posstr][vId] = self + end + + -- get meta + self.meta = core.get_meta(self.drawer_pos) + + -- collisionbox + node = core.get_node(self.drawer_pos) + local colbox + if self.drawerType ~= 2 then + if node.param2 == 1 or node.param2 == 3 then + colbox = {0, -0.4374, -0.4374, 0, 0.4374, 0.4374} + else + colbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0} -- for param2 = 0 or 2 + end + -- only half the size if it's a small drawer + if self.drawerType > 1 then + for i,j in pairs(colbox) do + colbox[i] = j * 0.5 + end + end + else + if node.param2 == 1 or node.param2 == 3 then + colbox = {0, -0.2187, -0.4374, 0, 0.2187, 0.4374} + else + colbox = {-0.4374, -0.2187, 0, 0.4374, 0.2187, 0} -- for param2 = 0 or 2 + end + end + + -- visual size + local visual_size = {x = 0.6, y = 0.6} + if self.drawerType >= 2 then + visual_size = {x = 0.3, y = 0.3} + end + + + -- drawer values + local vid = self.visualId + self.count = self.meta:get_int("count"..vid) + self.itemName = self.meta:get_string("name"..vid) + self.maxCount = self.meta:get_int("max_count"..vid) + self.itemStackMax = self.meta:get_int("base_stack_max"..vid) + self.stackMaxFactor = self.meta:get_int("stack_max_factor"..vid) + + + -- infotext + local infotext = self.meta:get_string("entity_infotext"..vid) .. "\n\n\n\n\n" + + self.object:set_properties({ + collisionbox = colbox, + infotext = infotext, + textures = {self.texture}, + visual_size = visual_size + }) + + -- make entity undestroyable + self.object:set_armor_groups({immortal = 1}) + end, + + on_rightclick = function(self, clicker) + if core.is_protected(self.drawer_pos, clicker:get_player_name()) then + core.record_protection_violation(self.drawer_pos, clicker:get_player_name()) + return + end + + -- used to check if we need to play a sound in the end + local inventoryChanged = false + + -- When the player uses the drawer with their bare hand all + -- stacks from the inventory will be added to the drawer. + if self.itemName ~= "" and + clicker:get_wielded_item():get_name() == "" and + not clicker:get_player_control().sneak then + -- try to insert all items from inventory + local i = 0 + local inv = clicker:get_inventory() + + while i <= inv:get_size("main") do + -- set current stack to leftover of insertion + local leftover = self.try_insert_stack( + self, + inv:get_stack("main", i), + true + ) + + -- check if something was added + if leftover:get_count() < inv:get_stack("main", i):get_count() then + inventoryChanged = true + end + + -- set new stack + inv:set_stack("main", i, leftover) + i = i + 1 + end + else + -- try to insert wielded item only + local leftover = self.try_insert_stack( + self, + clicker:get_wielded_item(), + not clicker:get_player_control().sneak + ) + + -- check if something was added + if clicker:get_wielded_item():get_count() > leftover:get_count() then + inventoryChanged = true + end + -- set the leftover as new wielded item for the player + clicker:set_wielded_item(leftover) + end + + if inventoryChanged then + self:play_interact_sound() + end + end, + + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) + local node = minetest.get_node(self.object:get_pos()) + if not node.name:match("^drawers:") then + self.object:remove() + return + end + local add_stack = not puncher:get_player_control().sneak + if core.is_protected(self.drawer_pos, puncher:get_player_name()) then + core.record_protection_violation(self.drawer_pos, puncher:get_player_name()) + return + end + local inv = puncher:get_inventory() + if inv == nil then + return + end + local spaceChecker = ItemStack(self.itemName) + if add_stack then + spaceChecker:set_count(spaceChecker:get_stack_max()) + end + if not inv:room_for_item("main", spaceChecker) then + return + end + + local stack = self:take_items(add_stack) + if stack ~= nil then + -- add removed stack to player's inventory + inv:add_item("main", stack) + + -- play the interact sound + self:play_interact_sound() + end + end, + + take_items = function(self, take_stack) + local meta = core.get_meta(self.drawer_pos) + + if self.count <= 0 then + return + end + + local removeCount = 1 + if take_stack then + removeCount = ItemStack(self.itemName):get_stack_max() + end + if removeCount > self.count then + removeCount = self.count + end + + local stack = ItemStack(self.itemName) + stack:set_count(removeCount) + + -- update the drawer count + self.count = self.count - removeCount + + self:updateInfotext() + self:updateTexture() + self:saveMetaData() + + -- return the stack that was removed from the drawer + return stack + end, + + try_insert_stack = function(self, itemstack, insert_stack) + local stackCount = itemstack:get_count() + local stackName = itemstack:get_name() + + -- if nothing to be added, return + if stackCount <= 0 then return itemstack end + -- if no itemstring, return + if stackName == "" then return itemstack end + + -- only add one, if player holding sneak key + if not insert_stack then + stackCount = 1 + end + + -- if current itemstring is not empty + if self.itemName ~= "" then + -- check if same item + if stackName ~= self.itemName then return itemstack end + else -- is empty + self.itemName = stackName + self.count = 0 + + -- get new stack max + self.itemStackMax = ItemStack(self.itemName):get_stack_max() + self.maxCount = self.itemStackMax * self.stackMaxFactor + end + + -- Don't add items stackable only to 1 + if self.itemStackMax == 1 then + self.itemName = "" + return itemstack + end + + -- set new counts: + -- if new count is more than max_count + if (self.count + stackCount) > self.maxCount then + itemstack:set_count(self.count + stackCount - self.maxCount) + self.count = self.maxCount + else -- new count fits + self.count = self.count + stackCount + -- this is for only removing one + itemstack:set_count(itemstack:get_count() - stackCount) + end + + -- update infotext, texture + self:updateInfotext() + self:updateTexture() + + self:saveMetaData() + + if itemstack:get_count() == 0 then itemstack = ItemStack("") end + return itemstack + end, + + updateInfotext = function(self) + local itemDescription = "" + if core.registered_items[self.itemName] then + itemDescription = core.registered_items[self.itemName].description + end + + if self.count <= 0 then + self.itemName = "" + self.meta:set_string("name"..self.visualId, self.itemName) + self.texture = "blank.png" + itemDescription = S("Empty") + end + + local infotext = drawers.gen_info_text(itemDescription, + self.count, self.stackMaxFactor, self.itemStackMax) + self.meta:set_string("entity_infotext"..self.visualId, infotext) + + self.object:set_properties({ + infotext = infotext .. "\n\n\n\n\n" + }) + end, + + updateTexture = function(self) + -- texture + self.texture = drawers.get_inv_image(self.itemName) + + self.object:set_properties({ + textures = {self.texture} + }) + end, + + dropStack = function(self, itemStack) + -- print warning if dropping higher stack counts than allowed + if itemStack:get_count() > itemStack:get_stack_max() then + core.log("warning", "[drawers] Dropping item stack with higher count than allowed") + end + -- find a position containing air + local dropPos = core.find_node_near(self.drawer_pos, 1, {"air"}, false) + -- if no pos found then drop on the top of the drawer + if not dropPos then + dropPos = self.pos + dropPos.y = dropPos.y + 1 + end + -- drop the item stack + core.item_drop(itemStack, nil, dropPos) + end, + + dropItemOverload = function(self) + -- drop stacks until there are no more items than allowed + while self.count > self.maxCount do + -- remove the overflow + local removeCount = self.count - self.maxCount + -- if this is too much for a single stack, only take the + -- stack limit + if removeCount > self.itemStackMax then + removeCount = self.itemStackMax + end + -- remove this count from the drawer + self.count = self.count - removeCount + -- create a new item stack having the size of the remove + -- count + local stack = ItemStack(self.itemName) + stack:set_count(removeCount) + print(stack:to_string()) + -- drop the stack + self:dropStack(stack) + end + end, + + setStackMaxFactor = function(self, stackMaxFactor) + self.stackMaxFactor = stackMaxFactor + self.maxCount = self.stackMaxFactor * self.itemStackMax + + -- will drop possible overflowing items + self:dropItemOverload() + self:updateInfotext() + self:saveMetaData() + end, + + play_interact_sound = function(self) + core.sound_play("drawers_interact", { + pos = self.object:get_pos(), + max_hear_distance = 6, + gain = 2.0 + }) + end, + + saveMetaData = function(self, meta) + self.meta:set_int("count"..self.visualId, self.count) + self.meta:set_string("name"..self.visualId, self.itemName) + self.meta:set_int("max_count"..self.visualId, self.maxCount) + self.meta:set_int("base_stack_max"..self.visualId, self.itemStackMax) + self.meta:set_int("stack_max_factor"..self.visualId, self.stackMaxFactor) + end +}) + +core.register_lbm({ + name = "drawers:restore_visual", + nodenames = {"group:drawer"}, + run_at_every_load = true, + action = function(pos, node) + local meta = core.get_meta(pos) + -- create drawer upgrade inventory + meta:get_inventory():set_size("upgrades", 5) + -- set the formspec + meta:set_string("formspec", drawers.drawer_formspec) + + -- count the drawer visuals + local drawerType = core.registered_nodes[node.name].groups.drawer + local foundVisuals = 0 + local objs = core.get_objects_inside_radius(pos, 0.59) + if objs then + for _, obj in pairs(objs) do + if obj and obj:get_luaentity() and + obj:get_luaentity().name == "drawers:visual" then + foundVisuals = foundVisuals + 1 + end + end + end + -- if all drawer visuals were found, return + if foundVisuals == drawerType then + return + end + + -- not enough visuals found, remove existing and create new ones + drawers.remove_visuals(pos) + drawers.spawn_visuals(pos) + end +}) diff --git a/mods/drawers/mod.conf b/mods/drawers/mod.conf new file mode 100644 index 0000000..b9e2282 --- /dev/null +++ b/mods/drawers/mod.conf @@ -0,0 +1,3 @@ +name = drawers +optional_depends = default, mcl_core, screwdriver, pipeworks, intllib, moreores +description = A Mod adding simple storages for items and blocks, showing the item's inventory image in the front. diff --git a/mods/drawers/settingtypes.txt b/mods/drawers/settingtypes.txt new file mode 100644 index 0000000..a42e370 --- /dev/null +++ b/mods/drawers/settingtypes.txt @@ -0,0 +1 @@ +drawers_controller_interval (Drawer Controller update interval in seconds) float 1.0 0.1 10.0 diff --git a/mods/drawers/sounds/drawers_interact.1.ogg b/mods/drawers/sounds/drawers_interact.1.ogg new file mode 100644 index 0000000..4e50559 Binary files /dev/null and b/mods/drawers/sounds/drawers_interact.1.ogg differ diff --git a/mods/drawers/sounds/drawers_interact.2.ogg b/mods/drawers/sounds/drawers_interact.2.ogg new file mode 100644 index 0000000..572c595 Binary files /dev/null and b/mods/drawers/sounds/drawers_interact.2.ogg differ diff --git a/mods/drawers/textures/drawers_acacia_wood.png b/mods/drawers/textures/drawers_acacia_wood.png new file mode 100644 index 0000000..71f8a2c Binary files /dev/null and b/mods/drawers/textures/drawers_acacia_wood.png differ diff --git a/mods/drawers/textures/drawers_acacia_wood_front_1.png b/mods/drawers/textures/drawers_acacia_wood_front_1.png new file mode 100644 index 0000000..fbeb7a3 Binary files /dev/null and b/mods/drawers/textures/drawers_acacia_wood_front_1.png differ diff --git a/mods/drawers/textures/drawers_acacia_wood_front_2.png b/mods/drawers/textures/drawers_acacia_wood_front_2.png new file mode 100644 index 0000000..1268b26 Binary files /dev/null and b/mods/drawers/textures/drawers_acacia_wood_front_2.png differ diff --git a/mods/drawers/textures/drawers_acacia_wood_front_4.png b/mods/drawers/textures/drawers_acacia_wood_front_4.png new file mode 100644 index 0000000..3e2c064 Binary files /dev/null and b/mods/drawers/textures/drawers_acacia_wood_front_4.png differ diff --git a/mods/drawers/textures/drawers_acacia_wood_mcl.png b/mods/drawers/textures/drawers_acacia_wood_mcl.png new file mode 100644 index 0000000..71f8a2c Binary files /dev/null and b/mods/drawers/textures/drawers_acacia_wood_mcl.png differ diff --git a/mods/drawers/textures/drawers_acacia_wood_mcl_front_1.png b/mods/drawers/textures/drawers_acacia_wood_mcl_front_1.png new file mode 100644 index 0000000..fbeb7a3 Binary files /dev/null and b/mods/drawers/textures/drawers_acacia_wood_mcl_front_1.png differ diff --git a/mods/drawers/textures/drawers_acacia_wood_mcl_front_2.png b/mods/drawers/textures/drawers_acacia_wood_mcl_front_2.png new file mode 100644 index 0000000..1268b26 Binary files /dev/null and b/mods/drawers/textures/drawers_acacia_wood_mcl_front_2.png differ diff --git a/mods/drawers/textures/drawers_acacia_wood_mcl_front_4.png b/mods/drawers/textures/drawers_acacia_wood_mcl_front_4.png new file mode 100644 index 0000000..3e2c064 Binary files /dev/null and b/mods/drawers/textures/drawers_acacia_wood_mcl_front_4.png differ diff --git a/mods/drawers/textures/drawers_aspen_wood.png b/mods/drawers/textures/drawers_aspen_wood.png new file mode 100644 index 0000000..a3ca314 Binary files /dev/null and b/mods/drawers/textures/drawers_aspen_wood.png differ diff --git a/mods/drawers/textures/drawers_aspen_wood_front_1.png b/mods/drawers/textures/drawers_aspen_wood_front_1.png new file mode 100644 index 0000000..68d1608 Binary files /dev/null and b/mods/drawers/textures/drawers_aspen_wood_front_1.png differ diff --git a/mods/drawers/textures/drawers_aspen_wood_front_2.png b/mods/drawers/textures/drawers_aspen_wood_front_2.png new file mode 100644 index 0000000..164858e Binary files /dev/null and b/mods/drawers/textures/drawers_aspen_wood_front_2.png differ diff --git a/mods/drawers/textures/drawers_aspen_wood_front_4.png b/mods/drawers/textures/drawers_aspen_wood_front_4.png new file mode 100644 index 0000000..cd6ac96 Binary files /dev/null and b/mods/drawers/textures/drawers_aspen_wood_front_4.png differ diff --git a/mods/drawers/textures/drawers_birch_wood.png b/mods/drawers/textures/drawers_birch_wood.png new file mode 100644 index 0000000..7756f07 Binary files /dev/null and b/mods/drawers/textures/drawers_birch_wood.png differ diff --git a/mods/drawers/textures/drawers_birch_wood_front_1.png b/mods/drawers/textures/drawers_birch_wood_front_1.png new file mode 100644 index 0000000..d571633 Binary files /dev/null and b/mods/drawers/textures/drawers_birch_wood_front_1.png differ diff --git a/mods/drawers/textures/drawers_birch_wood_front_2.png b/mods/drawers/textures/drawers_birch_wood_front_2.png new file mode 100644 index 0000000..9a874e1 Binary files /dev/null and b/mods/drawers/textures/drawers_birch_wood_front_2.png differ diff --git a/mods/drawers/textures/drawers_birch_wood_front_4.png b/mods/drawers/textures/drawers_birch_wood_front_4.png new file mode 100644 index 0000000..83cf185 Binary files /dev/null and b/mods/drawers/textures/drawers_birch_wood_front_4.png differ diff --git a/mods/drawers/textures/drawers_controller_front.png b/mods/drawers/textures/drawers_controller_front.png new file mode 100644 index 0000000..3724090 Binary files /dev/null and b/mods/drawers/textures/drawers_controller_front.png differ diff --git a/mods/drawers/textures/drawers_controller_side.png b/mods/drawers/textures/drawers_controller_side.png new file mode 100644 index 0000000..8645f6e Binary files /dev/null and b/mods/drawers/textures/drawers_controller_side.png differ diff --git a/mods/drawers/textures/drawers_controller_top.png b/mods/drawers/textures/drawers_controller_top.png new file mode 100644 index 0000000..774bc6a Binary files /dev/null and b/mods/drawers/textures/drawers_controller_top.png differ diff --git a/mods/drawers/textures/drawers_dark_oak_wood.png b/mods/drawers/textures/drawers_dark_oak_wood.png new file mode 100644 index 0000000..f4e45ad Binary files /dev/null and b/mods/drawers/textures/drawers_dark_oak_wood.png differ diff --git a/mods/drawers/textures/drawers_dark_oak_wood_front_1.png b/mods/drawers/textures/drawers_dark_oak_wood_front_1.png new file mode 100644 index 0000000..349985c Binary files /dev/null and b/mods/drawers/textures/drawers_dark_oak_wood_front_1.png differ diff --git a/mods/drawers/textures/drawers_dark_oak_wood_front_2.png b/mods/drawers/textures/drawers_dark_oak_wood_front_2.png new file mode 100644 index 0000000..45f6d78 Binary files /dev/null and b/mods/drawers/textures/drawers_dark_oak_wood_front_2.png differ diff --git a/mods/drawers/textures/drawers_dark_oak_wood_front_4.png b/mods/drawers/textures/drawers_dark_oak_wood_front_4.png new file mode 100644 index 0000000..6848091 Binary files /dev/null and b/mods/drawers/textures/drawers_dark_oak_wood_front_4.png differ diff --git a/mods/drawers/textures/drawers_junglewood.png b/mods/drawers/textures/drawers_junglewood.png new file mode 100644 index 0000000..f4e45ad Binary files /dev/null and b/mods/drawers/textures/drawers_junglewood.png differ diff --git a/mods/drawers/textures/drawers_junglewood_front_1.png b/mods/drawers/textures/drawers_junglewood_front_1.png new file mode 100644 index 0000000..349985c Binary files /dev/null and b/mods/drawers/textures/drawers_junglewood_front_1.png differ diff --git a/mods/drawers/textures/drawers_junglewood_front_2.png b/mods/drawers/textures/drawers_junglewood_front_2.png new file mode 100644 index 0000000..45f6d78 Binary files /dev/null and b/mods/drawers/textures/drawers_junglewood_front_2.png differ diff --git a/mods/drawers/textures/drawers_junglewood_front_4.png b/mods/drawers/textures/drawers_junglewood_front_4.png new file mode 100644 index 0000000..6848091 Binary files /dev/null and b/mods/drawers/textures/drawers_junglewood_front_4.png differ diff --git a/mods/drawers/textures/drawers_junglewood_mcl.png b/mods/drawers/textures/drawers_junglewood_mcl.png new file mode 100644 index 0000000..84f08e3 Binary files /dev/null and b/mods/drawers/textures/drawers_junglewood_mcl.png differ diff --git a/mods/drawers/textures/drawers_junglewood_mcl_front_1.png b/mods/drawers/textures/drawers_junglewood_mcl_front_1.png new file mode 100644 index 0000000..dcbcd50 Binary files /dev/null and b/mods/drawers/textures/drawers_junglewood_mcl_front_1.png differ diff --git a/mods/drawers/textures/drawers_junglewood_mcl_front_2.png b/mods/drawers/textures/drawers_junglewood_mcl_front_2.png new file mode 100644 index 0000000..df0e683 Binary files /dev/null and b/mods/drawers/textures/drawers_junglewood_mcl_front_2.png differ diff --git a/mods/drawers/textures/drawers_junglewood_mcl_front_4.png b/mods/drawers/textures/drawers_junglewood_mcl_front_4.png new file mode 100644 index 0000000..06f71bb Binary files /dev/null and b/mods/drawers/textures/drawers_junglewood_mcl_front_4.png differ diff --git a/mods/drawers/textures/drawers_oak_wood.png b/mods/drawers/textures/drawers_oak_wood.png new file mode 100644 index 0000000..350fe01 Binary files /dev/null and b/mods/drawers/textures/drawers_oak_wood.png differ diff --git a/mods/drawers/textures/drawers_oak_wood_front_1.png b/mods/drawers/textures/drawers_oak_wood_front_1.png new file mode 100644 index 0000000..d4f2277 Binary files /dev/null and b/mods/drawers/textures/drawers_oak_wood_front_1.png differ diff --git a/mods/drawers/textures/drawers_oak_wood_front_2.png b/mods/drawers/textures/drawers_oak_wood_front_2.png new file mode 100644 index 0000000..2835d1a Binary files /dev/null and b/mods/drawers/textures/drawers_oak_wood_front_2.png differ diff --git a/mods/drawers/textures/drawers_oak_wood_front_4.png b/mods/drawers/textures/drawers_oak_wood_front_4.png new file mode 100644 index 0000000..b6f63ab Binary files /dev/null and b/mods/drawers/textures/drawers_oak_wood_front_4.png differ diff --git a/mods/drawers/textures/drawers_pine_wood.png b/mods/drawers/textures/drawers_pine_wood.png new file mode 100644 index 0000000..9f2a6de Binary files /dev/null and b/mods/drawers/textures/drawers_pine_wood.png differ diff --git a/mods/drawers/textures/drawers_pine_wood_front_1.png b/mods/drawers/textures/drawers_pine_wood_front_1.png new file mode 100644 index 0000000..51a0edf Binary files /dev/null and b/mods/drawers/textures/drawers_pine_wood_front_1.png differ diff --git a/mods/drawers/textures/drawers_pine_wood_front_2.png b/mods/drawers/textures/drawers_pine_wood_front_2.png new file mode 100644 index 0000000..a6cee5c Binary files /dev/null and b/mods/drawers/textures/drawers_pine_wood_front_2.png differ diff --git a/mods/drawers/textures/drawers_pine_wood_front_4.png b/mods/drawers/textures/drawers_pine_wood_front_4.png new file mode 100644 index 0000000..f15313e Binary files /dev/null and b/mods/drawers/textures/drawers_pine_wood_front_4.png differ diff --git a/mods/drawers/textures/drawers_spruce_wood.png b/mods/drawers/textures/drawers_spruce_wood.png new file mode 100644 index 0000000..7abf2c4 Binary files /dev/null and b/mods/drawers/textures/drawers_spruce_wood.png differ diff --git a/mods/drawers/textures/drawers_spruce_wood_front_1.png b/mods/drawers/textures/drawers_spruce_wood_front_1.png new file mode 100644 index 0000000..87f0f57 Binary files /dev/null and b/mods/drawers/textures/drawers_spruce_wood_front_1.png differ diff --git a/mods/drawers/textures/drawers_spruce_wood_front_2.png b/mods/drawers/textures/drawers_spruce_wood_front_2.png new file mode 100644 index 0000000..19ecb45 Binary files /dev/null and b/mods/drawers/textures/drawers_spruce_wood_front_2.png differ diff --git a/mods/drawers/textures/drawers_spruce_wood_front_4.png b/mods/drawers/textures/drawers_spruce_wood_front_4.png new file mode 100644 index 0000000..ea77052 Binary files /dev/null and b/mods/drawers/textures/drawers_spruce_wood_front_4.png differ diff --git a/mods/drawers/textures/drawers_trim.png b/mods/drawers/textures/drawers_trim.png new file mode 100644 index 0000000..ab398c4 Binary files /dev/null and b/mods/drawers/textures/drawers_trim.png differ diff --git a/mods/drawers/textures/drawers_upgrade_diamond.png b/mods/drawers/textures/drawers_upgrade_diamond.png new file mode 100644 index 0000000..13ecd60 Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_diamond.png differ diff --git a/mods/drawers/textures/drawers_upgrade_emerald.png b/mods/drawers/textures/drawers_upgrade_emerald.png new file mode 100644 index 0000000..35fb6ff Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_emerald.png differ diff --git a/mods/drawers/textures/drawers_upgrade_gold.png b/mods/drawers/textures/drawers_upgrade_gold.png new file mode 100644 index 0000000..be74af0 Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_gold.png differ diff --git a/mods/drawers/textures/drawers_upgrade_iron.png b/mods/drawers/textures/drawers_upgrade_iron.png new file mode 100644 index 0000000..25c74df Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_iron.png differ diff --git a/mods/drawers/textures/drawers_upgrade_mithril.png b/mods/drawers/textures/drawers_upgrade_mithril.png new file mode 100644 index 0000000..dcdd13e Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_mithril.png differ diff --git a/mods/drawers/textures/drawers_upgrade_obsidian.png b/mods/drawers/textures/drawers_upgrade_obsidian.png new file mode 100644 index 0000000..8c24128 Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_obsidian.png differ diff --git a/mods/drawers/textures/drawers_upgrade_slot_bg.png b/mods/drawers/textures/drawers_upgrade_slot_bg.png new file mode 100644 index 0000000..97bad37 Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_slot_bg.png differ diff --git a/mods/drawers/textures/drawers_upgrade_steel.png b/mods/drawers/textures/drawers_upgrade_steel.png new file mode 100644 index 0000000..25c74df Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_steel.png differ diff --git a/mods/drawers/textures/drawers_upgrade_template.png b/mods/drawers/textures/drawers_upgrade_template.png new file mode 100644 index 0000000..d6cf9b3 Binary files /dev/null and b/mods/drawers/textures/drawers_upgrade_template.png differ diff --git a/mods/drawers/textures/drawers_wood.png b/mods/drawers/textures/drawers_wood.png new file mode 100644 index 0000000..350fe01 Binary files /dev/null and b/mods/drawers/textures/drawers_wood.png differ diff --git a/mods/drawers/textures/drawers_wood_front_1.png b/mods/drawers/textures/drawers_wood_front_1.png new file mode 100644 index 0000000..d4f2277 Binary files /dev/null and b/mods/drawers/textures/drawers_wood_front_1.png differ diff --git a/mods/drawers/textures/drawers_wood_front_2.png b/mods/drawers/textures/drawers_wood_front_2.png new file mode 100644 index 0000000..2835d1a Binary files /dev/null and b/mods/drawers/textures/drawers_wood_front_2.png differ diff --git a/mods/drawers/textures/drawers_wood_front_4.png b/mods/drawers/textures/drawers_wood_front_4.png new file mode 100644 index 0000000..b6f63ab Binary files /dev/null and b/mods/drawers/textures/drawers_wood_front_4.png differ diff --git a/mods/drawers/tools/updatepo.sh b/mods/drawers/tools/updatepo.sh new file mode 100755 index 0000000..74332e0 --- /dev/null +++ b/mods/drawers/tools/updatepo.sh @@ -0,0 +1,22 @@ +#! /bin/bash + +# To create a new translation: +# msginit --locale=ll_CC -o locale/ll_CC.po -i locale/template.pot + +cd "$(dirname "${BASH_SOURCE[0]}")/.."; + +# Extract translatable strings. +xgettext --from-code=UTF-8 \ + --keyword=S \ + --keyword=NS:1,2 \ + --keyword=N_ \ + --add-comments='Translators:' \ + --add-location=file \ + -o locale/template.pot \ + $(find . -name '*.lua') + +# Update translations. +find locale -name '*.po' | while read -r file; do + echo $file + msgmerge --update $file locale/template.pot; +done diff --git a/mods/drinks/depends.txt b/mods/drinks/depends.txt new file mode 100644 index 0000000..f28d1a6 --- /dev/null +++ b/mods/drinks/depends.txt @@ -0,0 +1,13 @@ +bucket +default +vessels +stairs +hunger? +thirsty? +plantlife? +farming_plus? +crops? +farming? +minetest_doc_modpack? +fruits? +ethereal? diff --git a/mods/drinks/description.txt b/mods/drinks/description.txt new file mode 100644 index 0000000..75420af --- /dev/null +++ b/mods/drinks/description.txt @@ -0,0 +1 @@ +This mod adds a juice press and two juice storage containers. Most fruits and several veggies can be juiced. The resulting drinks can be 'ate' to gain health, or if you are using the thirsty mod, to regain hydration. diff --git a/mods/drinks/drink_machines.lua b/mods/drinks/drink_machines.lua new file mode 100644 index 0000000..d19fbe8 --- /dev/null +++ b/mods/drinks/drink_machines.lua @@ -0,0 +1,636 @@ +--Craft Recipes + +minetest.register_craft({ + output = 'drinks:juice_press', + recipe = { + {'default:stick', 'default:steel_ingot', 'default:stick'}, + {'default:stick', 'bucket:bucket_empty', 'default:stick'}, + {'stairs:slab_wood', 'stairs:slab_wood', 'vessels:drinking_glass'}, + } +}) + +minetest.register_craft({ + output = 'drinks:liquid_barrel', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + {'stairs:slab_wood', '', 'stairs:slab_wood'}, + } +}) + +minetest.register_craft({ + output = 'drinks:liquid_silo', + recipe = { + {'drinks:liquid_barrel'}, + {'drinks:liquid_barrel'}, + {'drinks:liquid_barrel'} + } +}) + +local press_idle_formspec = + 'size[8,7]'.. + 'label[1.5,0;Organic juice is just a squish away.]' .. + 'label[4.3,.75;Put fruit here ->]'.. + 'label[3.5,1.75;Put container here ->]'.. + 'label[0.2,1.8;4 fruits to a glass,]'.. + 'label[0.2,2.1;8 fruits to a bottle,]'.. + 'label[0.2,2.4;16 fruits to a bucket.]'.. + 'button[1,1;2,1;press;Start Juicing]'.. + 'list[current_name;src;6.5,.5;1,1;]'.. + 'list[current_name;dst;6.5,1.5;1,1;]'.. + 'list[current_player;main;0,3;8,4;]' + +local press_running_formspec = + 'size[8,7]'.. + 'label[1.5,0;Organic juice coming right up.]' .. + 'label[4.3,.75;Put fruit here ->]'.. + 'label[3.5,1.75;Put container here ->]'.. + 'label[0.2,1.8;4 fruits to a glass,]'.. + 'label[0.2,2.1;8 fruits to a bottle,]'.. + 'label[0.2,2.4;16 fruits to a bucket.]'.. + 'button[1,1;2,1;press;Start Juicing]'.. + 'list[current_name;src;6.5,.5;1,1;]'.. + 'list[current_name;dst;6.5,1.5;1,1;]'.. + 'list[current_player;main;0,3;8,4;]' + +local press_error_formspec = + 'size[8,7]'.. + 'label[1.5,0;You need to add more fruit.]' .. + 'label[4.3,.75;Put fruit here ->]'.. + 'label[3.5,1.75;Put container here ->]'.. + 'label[0.2,1.8;4 fruits to a glass,]'.. + 'label[0.2,2.1;8 fruits to a bottle,]'.. + 'label[0.2,2.4;16 fruits to a bucket.]'.. + 'button[1,1;2,1;press;Start Juicing]'.. + 'list[current_name;src;6.5,.5;1,1;]'.. + 'list[current_name;dst;6.5,1.5;1,1;]'.. + 'list[current_player;main;0,3;8,4;]' + +minetest.register_node('drinks:juice_press', { + description = 'Juice Press', + _doc_items_longdesc = "A machine for creating drinks out of various fruits and vegetables.", + _doc_items_usagehelp = "Right-click the press to access inventory and begin juicing.", + drawtype = 'mesh', + mesh = 'drinks_press.obj', + tiles = {name='drinks_press.png'}, + groups = {choppy=2, dig_immediate=2,}, + paramtype = 'light', + paramtype2 = 'facedir', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, .5, .5}, + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('main', 8*4) + inv:set_size('src', 1) + inv:set_size('dst', 1) + meta:set_string('infotext', 'Empty Juice Press') + meta:set_string('formspec', press_idle_formspec) + end, + on_receive_fields = function(pos, formname, fields, sender) + if fields ['press'] then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local timer = minetest.get_node_timer(pos) + local instack = inv:get_stack("src", 1) + local fruitstack = instack:get_name() + local mod, fruit = fruitstack:match("([^:]+):([^:]+)") + if drinks.juiceable[fruit] then + if string.find(fruit, '_') then + local fruit, junk = fruit:match('([^_]+)_([^_]+)') + meta:set_string('fruit', fruit) + else + meta:set_string('fruit', fruit) + end + local outstack = inv:get_stack("dst", 1) + local vessel = outstack:get_name() + if vessel == 'vessels:drinking_glass' then + if instack:get_count() >= 4 then + meta:set_string('container', 'jcu_') + meta:set_string('fruitnumber', 4) + meta:set_string('infotext', 'Juicing...') + meta:set_string('formspec', press_running_formspec) + timer:start(4) + else + meta:set_string('infotext', 'You need more fruit.') + meta:set_string('formspec', press_error_formspec) + end + elseif vessel == 'vessels:glass_bottle' then + if instack:get_count() >= 8 then + meta:set_string('container', 'jbo_') + meta:set_string('fruitnumber', 8) + meta:set_string('infotext', 'Juicing...') + meta:set_string('formspec', press_running_formspec) + timer:start(8) + else + meta:set_string('infotext', 'You need more fruit.') + meta:set_string('formspec', press_error_formspec) + end + elseif vessel == 'vessels:steel_bottle' then + if instack:get_count() >= 8 then + meta:set_string('container', 'jsb_') + meta:set_string('fruitnumber', 8) + meta:set_string('infotext', 'Juicing...') + meta:set_string('formspec', press_running_formspec) + timer:start(8) + else + meta:set_string('infotext', 'You need more fruit.') + meta:set_string('formspec', press_error_formspec) + end + elseif vessel == 'bucket:bucket_empty' then + if instack:get_count() >= 16 then + meta:set_string('container', 'jbu_') + meta:set_string('fruitnumber', 16) + meta:set_string('infotext', 'Juicing...') + meta:set_string('formspec', press_running_formspec) + timer:start(16) + else + meta:set_string('infotext', 'You need more fruit.') + meta:set_string('formspec', press_error_formspec) + end + elseif vessel == 'default:papyrus' then + if instack:get_count() >= 2 then + local under_node = {x=pos.x, y=pos.y-1, z=pos.z} + local under_node_name = minetest.get_node_or_nil(under_node) + local under_node_2 = {x=pos.x, y=pos.y-2, z=pos.z} + local under_node_name_2 = minetest.get_node_or_nil(under_node_2) + if under_node_name.name == 'drinks:liquid_barrel' then + local meta_u = minetest.get_meta(under_node) + local stored_fruit = meta_u:get_string('fruit') + if fruit == stored_fruit or stored_fruit == 'empty' then + meta:set_string('container', 'tube') + meta:set_string('fruitnumber', 2) + meta:set_string('infotext', 'Juicing...') + meta_u:set_string('fruit', fruit) + timer:start(4) + else + meta:set_string('infotext', "You can't mix juices.") + end + elseif under_node_name_2.name == 'drinks:liquid_silo' then + local meta_u = minetest.get_meta(under_node_2) + local stored_fruit = meta_u:get_string('fruit') + if fruit == stored_fruit or stored_fruit == 'empty' then + meta:set_string('container', 'tube') + meta:set_string('fruitnumber', 2) + meta:set_string('infotext', 'Juicing...') + meta_u:set_string('fruit', fruit) + timer:start(4) + else + meta:set_string('infotext', "You can't mix juices.") + end + else + meta:set_string('infotext', 'You need more fruit.') + meta:set_string('formspec', press_error_formspec) + end + end + end + end + end + end, + on_timer = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local container = meta:get_string('container') + local instack = inv:get_stack("src", 1) + local outstack = inv:get_stack("dst", 1) + local fruit = meta:get_string('fruit') + local fruitnumber = tonumber(meta:get_string('fruitnumber')) + if container == 'tube' then + local timer = minetest.get_node_timer(pos) + local under_node = {x=pos.x, y=pos.y-1, z=pos.z} + local under_node_name = minetest.get_node_or_nil(under_node) + local under_node_2 = {x=pos.x, y=pos.y-2, z=pos.z} + local under_node_name_2 = minetest.get_node_or_nil(under_node_2) + if under_node_name.name == 'drinks:liquid_barrel' then + local meta_u = minetest.get_meta(under_node) + local fullness = tonumber(meta_u:get_string('fullness')) + instack:take_item(tonumber(fruitnumber)) + inv:set_stack('src', 1, instack) + if fullness + 2 > 128 then + timer:stop() + meta:set_string('infotext', 'Barrel is full of juice.') + return + else + local fullness = fullness + 2 + meta_u:set_string('fullness', fullness) + meta_u:set_string('infotext', (math.floor((fullness/128)*100))..' % full of '..fruit..' juice.') + meta_u:set_string('formspec', drinks.liquid_storage_formspec(fruit, fullness, 128)) + if instack:get_count() >= 2 then + timer:start(4) + else + meta:set_string('infotext', 'You need more fruit.') + end + end + elseif under_node_name_2.name == 'drinks:liquid_silo' then + local meta_u = minetest.get_meta(under_node_2) + local fullness = tonumber(meta_u:get_string('fullness')) + instack:take_item(tonumber(fruitnumber)) + inv:set_stack('src', 1, instack) + if fullness + 2 > 256 then + timer:stop() + meta:set_string('infotext', 'Silo is full of juice.') + return + else + local fullness = fullness + 2 + meta_u:set_string('fullness', fullness) + meta_u:set_string('infotext', (math.floor((fullness/256)*100))..' % full of '..fruit..' juice.') + meta_u:set_string('formspec', drinks.liquid_storage_formspec(fruit, fullness, 256)) + if instack:get_count() >= 2 then + timer:start(4) + else + meta:set_string('infotext', 'You need more fruit.') + end + end + end + else + meta:set_string('infotext', 'Collect your juice.') + meta:set_string('formspec', press_idle_formspec) + instack:take_item(tonumber(fruitnumber)) + inv:set_stack('src', 1, instack) + inv:set_stack('dst', 1 ,'drinks:'..container..fruit) + end + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local timer = minetest.get_node_timer(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + timer:stop() + meta:set_string('infotext', 'Ready for more juicing.') + meta:set_string('formspec', press_idle_formspec) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + meta:set_string('infotext', 'Ready for juicing.') + end, + can_dig = function(pos) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + if inv:is_empty("src") and + inv:is_empty("dst") then + return true + else + return false + end + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == 'dst' then + if stack:get_name() == ('bucket:bucket_empty') then + return 1 + elseif stack:get_name() == ('vessels:drinking_glass') then + return 1 + elseif stack:get_name() == ('vessels:glass_bottle') then + return 1 + elseif stack:get_name() == ('vessels:steel_bottle') then + return 1 + elseif stack:get_name() == ('default:papyrus') then + return 1 + else + return 0 + end + else + return 99 + end + end, +}) + +function drinks.drinks_liquid_sub(liq_vol, ves_typ, ves_vol, pos, able_to_fill, leftover_count, outputstack) + local meta = minetest.get_meta(pos) + local fullness = tonumber(meta:get_string('fullness')) + local fruit = meta:get_string('fruit') + local fruit_name = meta:get_string('fruit_name') + local inv = meta:get_inventory() + local fullness = fullness - (liq_vol*able_to_fill) + meta:set_string('fullness', fullness) + meta:set_string('infotext', (math.floor((fullness/ves_vol)*100))..' % full of '..fruit_name..' juice.') + if ves_vol == 128 then + meta:set_string('formspec', drinks.liquid_storage_formspec(fruit_name, fullness, 128)) + elseif ves_vol == 256 then + meta:set_string('formspec', drinks.liquid_storage_formspec(fruit_name, fullness, 256)) + end + if ves_typ == 'jcu' or ves_typ == 'jbo' or ves_typ == 'jsb' or ves_typ == 'jbu' then + inv:set_stack('dst', 1, 'drinks:'..ves_typ..'_'..fruit..' '..able_to_fill) + inv:set_stack('src', 1, outputstack..' '..leftover_count) + elseif ves_typ == 'thirsty:bronze_canteen' then + inv:set_stack('dst', 1, {name="thirsty:bronze_canteen", count=1, wear=60, metadata=""}) + elseif ves_typ == 'thirsty:steel_canteen' then + inv:set_stack('dst', 1, {name="thirsty:steel_canteen", count=1, wear=40, metadata=""}) + end +end + +function drinks.drinks_liquid_avail_sub(liq_vol, ves_typ, ves_vol, outputstack, pos, count) + local meta = minetest.get_meta(pos) + local fullness = tonumber(meta:get_string('fullness')) + if fullness - (liq_vol*count) < 0 then + local able_to_fill = math.floor(fullness/liq_vol) + local leftover_count = count - able_to_fill + drinks.drinks_liquid_sub(liq_vol, ves_typ, ves_vol, pos, able_to_fill, leftover_count, outputstack) + elseif fullness - (liq_vol*count) >= 0 then + drinks.drinks_liquid_sub(liq_vol, ves_typ, ves_vol, pos, count, 0, outputstack) + end +end + +function drinks.drinks_liquid_add(liq_vol, ves_typ, ves_vol, pos, inputcount, leftover_count, inputstack) + local meta = minetest.get_meta(pos) + local fullness = tonumber(meta:get_string('fullness')) + local fruit = meta:get_string('fruit') + local fruit_name = meta:get_string('fruit_name') + local inv = meta:get_inventory() + local fullness = fullness + (liq_vol*inputcount) + meta:set_string('fullness', fullness) + inv:set_stack('src', 1, ves_typ..' '..inputcount) + inv:set_stack('dst', 1, inputstack..' '..leftover_count) + meta:set_string('infotext', (math.floor((fullness/ves_vol)*100))..' % full of '..fruit_name..' juice.') + if ves_vol == 256 then + meta:set_string('formspec', drinks.liquid_storage_formspec(fruit_name, fullness, 256)) + elseif ves_vol == 128 then + meta:set_string('formspec', drinks.liquid_storage_formspec(fruit_name, fullness, 128)) + end +end + +function drinks.drinks_liquid_avail_add(liq_vol, ves_typ, ves_vol, pos, inputstack, inputcount) + local meta = minetest.get_meta(pos) + local fullness = tonumber(meta:get_string('fullness')) + if fullness + (liq_vol*inputcount) > ves_vol then + local avail_ves_vol = ves_vol - fullness + local can_empty = math.floor(avail_ves_vol/liq_vol) + local leftover_count = inputcount - can_empty + drinks.drinks_liquid_add(liq_vol, ves_typ, ves_vol, pos, can_empty, leftover_count, inputstack) + elseif fullness + (liq_vol*inputcount) <= ves_vol then + drinks.drinks_liquid_add(liq_vol, ves_typ, ves_vol, pos, inputcount, 0, inputstack) + end +end + +function drinks.drinks_barrel(pos, inputstack, inputcount) + local meta = minetest.get_meta(pos) + local vessel = string.sub(inputstack, 8, 10) + drinks.drinks_liquid_avail_add(drinks.shortname[vessel].size, drinks.shortname[vessel].name, 128, pos, inputstack, inputcount) +end + +function drinks.drinks_silo(pos, inputstack, inputcount) + local meta = minetest.get_meta(pos) + local vessel = string.sub(inputstack, 8, 10) + drinks.drinks_liquid_avail_add(drinks.shortname[vessel].size, drinks.shortname[vessel].name, 256, pos, inputstack, inputcount) +end + +minetest.register_node('drinks:liquid_barrel', { + description = 'Barrel of Liquid', + _doc_items_longdesc = "A node that provides a simple way to store juice.", + _doc_items_usagehelp = "Add or remove liquids from the barrel using buckets, bottles, or cups.", + drawtype = 'mesh', + mesh = 'drinks_liquid_barrel.obj', + tiles = {name='drinks_barrel.png'}, + groups = {choppy=2, dig_immediate=2,}, + paramtype = 'light', + paramtype2 = 'facedir', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, .5, .5}, + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('main', 8*4) + inv:set_size('src', 1) + inv:set_size('dst', 1) + meta:set_string('fullness', 0) + meta:set_string('fruit', 'empty') + meta:set_string('infotext', 'Empty Drink Barrel') + meta:set_string('formspec', 'size[8,8]'.. + 'label[0,0;Fill with the drink of your choice,]'.. + 'label[0,.4;you can only add more of the same type of drink.]'.. + 'label[4.5,1.2;Add liquid ->]'.. + 'label[.75,1.75;The barrel is empty]'.. + 'label[4.5,2.25;Take liquid ->]'.. + 'label[2,3.2;(This empties the barrel completely)]'.. + 'button[0,3;2,1;purge;Purge]'.. + 'list[current_name;src;6.5,1;1,1;]'.. + 'list[current_name;dst;6.5,2;1,1;]'.. + 'list[current_player;main;0,4;8,5;]') + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local instack = inv:get_stack('src', 1) + local outstack = inv:get_stack('dst', 1) + local outputstack = outstack:get_name() + local inputstack = instack:get_name() + local outputcount = outstack:get_count() + local inputcount = instack:get_count() + local fruit = string.sub(inputstack, 12, -1) + local fruit_in = meta:get_string('fruit') + if fruit_in == 'empty' then + meta:set_string('fruit', fruit) + local fruit_name = minetest.registered_nodes[instack:get_name()] + meta:set_string('fruit_name', string.lower(fruit_name.juice_type)) + local vessel = string.sub(inputstack, 8, 10) + drinks.drinks_barrel(pos, inputstack, inputcount) + end + if fruit == fruit_in then + local vessel = string.sub(inputstack, 8, 10) + drinks.drinks_barrel(pos, inputstack, inputcount) + end + if drinks.longname[outputstack] then + drinks.drinks_liquid_avail_sub(drinks.longname[outputstack].size, drinks.longname[outputstack].name, 128, outputstack, pos, outputcount) + end + end, + on_receive_fields = function(pos, formname, fields, sender) + if fields['purge'] then + local player_name = sender:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(sender, 'protection_bypass') then + return + end + local meta = minetest.get_meta(pos) + local fullness = 0 + local fruit_name = 'no' + meta:set_string('fullness', 0) + meta:set_string('fruit', 'empty') + meta:set_string('infotext', 'Empty Drink Barrel') + meta:set_string('formspec', drinks.liquid_storage_formspec(fruit_name, fullness, 128)) + end + end, + can_dig = function(pos) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + if inv:is_empty("src") and + inv:is_empty("dst") and + tonumber(meta:get_string('fullness')) == 0 then + return true + else + return false + end + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if minetest.is_protected(pos, player:get_player_name()) and not minetest.check_player_privs(player, 'protection_bypass') then + return 0 + end + if listname == 'src' then --adding liquid + local inputstack = stack:get_name() + local inputcount = stack:get_count() + local valid = string.sub(inputstack, 1, 8) + if valid == 'drinks:j' then + return inputcount + else + return 0 + end + elseif listname == 'dst' then --removing liquid + --make sure there is a liquid to remove + local juice = meta:get_string('fruit') + if juice ~= 'empty' then + local inputstack = stack:get_name() + local inputcount = stack:get_count() + local valid = string.sub(inputstack, 1, 7) + if valid == 'vessels' or valid == 'bucket:' then + return inputcount + else + return 0 + end + else + return 0 + end + end + end, +}) + +minetest.register_node('drinks:liquid_silo', { + description = 'Silo of Liquid', + _doc_items_longdesc = "A node that provides a simple way to store juice.", + _doc_items_usagehelp = "Add or remove liquids from the silo using buckets, bottles, or cups.", + drawtype = 'mesh', + mesh = 'drinks_silo.obj', + tiles = {name='drinks_silo.png'}, + groups = {choppy=2, dig_immediate=2,}, + paramtype = 'light', + paramtype2 = 'facedir', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, 1.5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, 1.5, .5}, + }, + after_place_node = function(pos, placer, itemstack) + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local top_node = minetest.get_node_or_nil(above) + if top_node.name ~= 'air' then + minetest.remove_node(pos) + return itemstack + end + end, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size('main', 8*4) + inv:set_size('src', 1) + inv:set_size('dst', 1) + meta:set_string('fullness', 0) + meta:set_string('fruit', 'empty') + meta:set_string('infotext', 'Empty Drink Silo') + meta:set_string('formspec', 'size[8,8]'.. + 'label[0,0;Fill with the drink of your choice,]'.. + 'label[0,.4;you can only add more of the same type of drink.]'.. + 'label[4.5,1.2;Add liquid ->]'.. + 'label[.75,1.75;The Silo is empty]'.. + 'label[4.5,2.25;Take liquid ->]'.. + 'label[2,3.2;(This empties the silo completely)]'.. + 'button[0,3;2,1;purge;Purge]'.. + 'list[current_name;src;6.5,1;1,1;]'.. + 'list[current_name;dst;6.5,2;1,1;]'.. + 'list[current_player;main;0,4;8,5;]') + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local instack = inv:get_stack("src", 1) + local outstack = inv:get_stack('dst', 1) + local outputstack = outstack:get_name() + local inputstack = instack:get_name() + local outputcount = outstack:get_count() + local inputcount = instack:get_count() + local fruit = string.sub(inputstack, 12, -1) + local fruit_in = meta:get_string('fruit') + if fruit_in == 'empty' then + meta:set_string('fruit', fruit) + local fruit_name = minetest.registered_nodes[instack:get_name()] + meta:set_string('fruit_name', string.lower(fruit_name.juice_type)) + local vessel = string.sub(inputstack, 8, 10) + drinks.drinks_silo(pos, inputstack, inputcount) + end + if fruit == fruit_in then + local vessel = string.sub(inputstack, 8, 10) + drinks.drinks_silo(pos, inputstack, inputcount) + end + if drinks.longname[outputstack] then + drinks.drinks_liquid_avail_sub(drinks.longname[outputstack].size, drinks.longname[outputstack].name, 256, outputstack, pos, outputcount) + end + end, + on_receive_fields = function(pos, formname, fields, sender) + local player_name = sender:get_player_name() + if fields['purge'] then + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(sender, 'protection_bypass') then + return + end + local meta = minetest.get_meta(pos) + local fullness = 0 + local fruit_name = 'no' + meta:set_string('fullness', 0) + meta:set_string('fruit', 'empty') + meta:set_string('infotext', 'Empty Drink Silo') + meta:set_string('formspec', drinks.liquid_storage_formspec(fruit_name, fullness, 256)) + end + end, + can_dig = function(pos) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + if inv:is_empty("src") and + inv:is_empty("dst") and + tonumber(meta:get_string('fullness')) == 0 then + return true + else + return false + end + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if minetest.is_protected(pos, player:get_player_name()) and not minetest.check_player_privs(player, 'protection_bypass') then + return 0 + end + if listname == 'src' then --adding liquid + local inputstack = stack:get_name() + local inputcount = stack:get_count() + local valid = string.sub(inputstack, 1, 8) + if valid == 'drinks:j' then + return inputcount + else + return 0 + end + elseif listname == 'dst' then --removing liquid + --make sure there is liquid to take_item + local juice = meta:get_string('fruit') + if juice ~= 'empty' then + local inputstack = stack:get_name() + local inputcount = stack:get_count() + local valid = string.sub(inputstack, 1, 7) + if valid == 'vessels' or valid == 'bucket:' then + return inputcount + else + return 0 + end + else + return 0 + end + end + end, +}) diff --git a/mods/drinks/drinks.lua b/mods/drinks/drinks.lua new file mode 100644 index 0000000..7de692f --- /dev/null +++ b/mods/drinks/drinks.lua @@ -0,0 +1,65 @@ +--Parse Table +for i in ipairs (drinks.drink_table) do + local desc = drinks.drink_table[i][1] + local craft = drinks.drink_table[i][2] + local color = drinks.drink_table[i][3] + local health = drinks.drink_table[i][4] + health = health or 1 + -- The color of the drink is all done in code, so we don't need to have multiple images. + +--Actual Node registration +minetest.register_node('drinks:jbu_'..desc..'', { + description = 'Bucket of '..craft..' Juice', + drawtype = "plantlike", + tiles = {'bucket.png^(drinks_bucket_contents.png^[colorize:'..color..':200)'}, + inventory_image = 'bucket.png^(drinks_bucket_contents.png^[colorize:'..color..':200)', + wield_image = 'bucket.png^(drinks_bucket_contents.png^[colorize:'..color..':200)', + paramtype = "light", + juice_type = craft, + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25} + }, + groups = {vessel=1,dig_immediate=3,attached_node=1, drink = 1}, + sounds = default.node_sound_defaults(), +}) + +drinks.register_item('drinks:jcu_'..desc, 'vessels:drinking_glass', { + description = 'Cup of '..craft..' Juice', + groups = {drink=1}, + juice_type = craft, + inventory_image = 'drinks_glass_contents.png^[colorize:'..color..':200^drinks_drinking_glass.png', + on_use = function(itemstack, user, pointed_thing) + thirsty.drink(user, 4, 20) + local eat_func = minetest.item_eat(health, 'vessels:drinking_glass') + return eat_func(itemstack, user, pointed_thing) + end, +}) + +drinks.register_item('drinks:jbo_'..desc, 'vessels:glass_bottle',{ + description = 'Bottle of '..craft..' Juice', + groups = {drink = 1}, + juice_type = craft, + inventory_image = 'drinks_bottle_contents.png^[colorize:'..color..':200^drinks_glass_bottle.png', + on_use = function(itemstack, user, pointed_thing) + thirsty.drink(user, 8, 20) + local eat_func = minetest.item_eat((health*2), 'vessels:glass_bottle') + return eat_func(itemstack, user, pointed_thing) + end, +}) + +drinks.register_item('drinks:jsb_'..desc, 'vessels:steel_bottle',{ + description = 'Heavy Steel Bottle ('..craft..' Juice)', + groups = {drink = 1}, + juice_type = craft, + inventory_image = 'vessels_steel_bottle.png', + on_use = function(itemstack, user, pointed_thing) + thirsty.drink(user, 8, 20) + local eat_func = minetest.item_eat((health*2), 'vessels:steel_bottle') + return eat_func(itemstack, user, pointed_thing) + end, +}) + +end diff --git a/mods/drinks/drinks2.lua b/mods/drinks/drinks2.lua new file mode 100644 index 0000000..a59444d --- /dev/null +++ b/mods/drinks/drinks2.lua @@ -0,0 +1,61 @@ +-- This code is for if Thirst isn't enabled. +--Parse Table +for i in ipairs (drinks.drink_table) do + local desc = drinks.drink_table[i][1] + local craft = drinks.drink_table[i][2] + local color = drinks.drink_table[i][3] + local health = drinks.drink_table[i][4] + health = health or 1 + +--Actual Node registration +minetest.register_node('drinks:jbu_'..desc..'', { + description = 'Bucket of '..craft..' Juice', + drawtype = "plantlike", + tiles = {'bucket.png^(drinks_bucket_contents.png^[colorize:'..color..':200)'}, + inventory_image = 'bucket.png^(drinks_bucket_contents.png^[colorize:'..color..':200)', + wield_image = 'bucket.png^(drinks_bucket_contents.png^[colorize:'..color..':200)', + paramtype = "light", + juice_type = craft, + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.4, 0.25} + }, + groups = {vessel=1,dig_immediate=3,attached_node=1, drink = 1}, + sounds = default.node_sound_defaults(), +}) + +drinks.register_item( 'drinks:jcu_'..desc, 'vessels:drinking_glass', { + description = 'Cup of '..craft..' Juice', + juice_type = craft, + inventory_image = 'drinks_glass_contents.png^[colorize:'..color..':200^drinks_drinking_glass.png', + on_use = function(itemstack, user, pointed_thing) + local eat_func = minetest.item_eat(health, 'vessels:drinking_glass') + return eat_func(itemstack, user, pointed_thing) + end, +}) + +drinks.register_item( 'drinks:jbo_'..desc, 'vessels:glass_bottle', { + description = 'Bottle of '..craft..' Juice', + groups = {drink=1}, + juice_type = craft, + inventory_image = 'drinks_bottle_contents.png^[colorize:'..color..':200^drinks_glass_bottle.png', + on_use = function(itemstack, user, pointed_thing) + local eat_func = minetest.item_eat((health*2), 'vessels:glass_bottle') + return eat_func(itemstack, user, pointed_thing) + end, +}) + +drinks.register_item( 'drinks:jsb_'..desc, 'vessels:steel_bottle', { + description = 'Heavy Steel Bottle ('..craft..' Juice)', + groups = {drink=1}, + juice_type = craft, + inventory_image = 'vessels_steel_bottle.png', + on_use = function(itemstack, user, pointed_thing) + local eat_func = minetest.item_eat((health*2), 'vessels:steel_bottle') + return eat_func(itemstack, user, pointed_thing) + end, +}) + +end diff --git a/mods/drinks/formspecs.lua b/mods/drinks/formspecs.lua new file mode 100644 index 0000000..43bf390 --- /dev/null +++ b/mods/drinks/formspecs.lua @@ -0,0 +1,16 @@ +function drinks.liquid_storage_formspec(fruit_name, fullness, max) + local formspec = + 'size[8,8]'.. + 'label[0,0;Fill with the drink of your choice,]'.. + 'label[0,.4;you can only add more of the same type of drink.]'.. + 'label[4.5,1.2;Add liquid ->]'.. + 'label[.5,1.2;Storing '..fruit_name..' juice.]'.. + 'label[.5,1.65;Holding '..(fullness/2)..' of '..(max/2)..' cups.]'.. + 'label[4.5,2.25;Take liquid ->]'.. + 'label[2,3.2;(This empties the container completely)]'.. + 'button[0,3;2,1;purge;Purge]'.. + 'list[current_name;src;6.5,1;1,1;]'.. + 'list[current_name;dst;6.5,2;1,1;]'.. + 'list[current_player;main;0,4;8,5;]' + return formspec +end diff --git a/mods/drinks/init.lua b/mods/drinks/init.lua new file mode 100644 index 0000000..df106bc --- /dev/null +++ b/mods/drinks/init.lua @@ -0,0 +1,217 @@ +-- mod support (moreblocks/technic_worldgen) +local slab_str = "stairs:slab_wood" + +function applyModSupport() + local moreblocks_found = false + local technic_worldgen = false + + local modnames = minetest.get_modnames() + + for i, name in ipairs(modnames) do + -- minetest.log("[Mod] " .. name) + if name == "moreblocks" then + moreblocks_found = true + end + + if name == "technic_worldgen" then + technic_worldgen = true + end + end + + if moreblocks_found == true and technic_worldgen == true then + minetest.log("applying patch to mod " .. minetest.get_current_modname()) + minetest.log("converting '" .. slab_str .. "' to 'moreblocks:slab_wood'") + slab_str = "moreblocks:slab_wood" + end +end +--applyModSupport() + +--Craft Recipes + +-- added mod-support +minetest.register_craft({ + output = 'drinks:juice_press', + recipe = { + {'default:stick', 'default:steel_ingot', 'default:stick'}, + {'default:stick', 'bucket:bucket_empty', 'default:stick'}, + {slab_str, slab_str, 'vessels:drinking_glass'}, + } +}) + +-- added mod-support +minetest.register_craft({ + output = 'drinks:liquid_barrel', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + {slab_str, '', slab_str}, + } +}) + +drinks = { +drink_table = {}, +juiceable = {}, +shortname = { + ['jcu'] = {size = 2, name = 'vessels:drinking_glass'}, + ['jbo'] = {size = 4, name = 'vessels:glass_bottle'}, + ['jsb'] = {size = 4, name = 'vessels:steel_bottle'}, + ['jbu'] = {size = 16, name = 'bucket:bucket_empty'} +}, +longname = { + ['vessels:drinking_glass'] = {size = 2, name = 'jcu'}, + ['vessels:glass_bottle'] = {size = 4, name = 'jbo'}, + ['vessels:steel_bottle'] = {size = 4, name = 'jsb'}, + ['bucket:bucket_empty'] = {size = 16, name = 'jbu'}, + ['thirsty:steel_canteen'] = {size = 20, name = 'thirsty:steel_canteen'}, + ['thirsty:bronze_canteen'] = {size = 30, name = 'thirsty:bronze_canteen'}, +}, +} + + +-- Honestly not needed for default, but used as an example to add support to other mods. +-- Basically to use this all you need to do is add the name of the fruit to make juiceable (see line 14 for example) +-- Add the new fruit to a table like I've done in line 16. +-- The table should follow this scheme: internal name, Displayed name, colorize code. +-- Check out the drinks.lua file for more info how how the colorize code is used. + +if minetest.get_modpath('default') then + drinks.juiceable['apple'] = true -- Name of fruit to make juiceable. + drinks.juiceable['cactus'] = true + drinks.juiceable['blueberries'] = true + table.insert(drinks.drink_table, {'apple', 'Apple', '#ecff56'}) + table.insert(drinks.drink_table, {'cactus', 'Cactus', '#96F97B'}) + table.insert(drinks.drink_table, {'blueberries', 'Blueberry', '#521dcb'}) +end + +if minetest.get_modpath('bushes_classic') then + drinks.juiceable['blackberry'] = true + drinks.juiceable['blueberry'] = true + drinks.juiceable['gooseberry'] = true + drinks.juiceable['raspberry'] = true + drinks.juiceable['strawberry'] = true + table.insert(drinks.drink_table, {'blackberry', 'Blackberry', '#581845'}) + table.insert(drinks.drink_table, {'blueberry', 'Blueberry', '#521dcb'}) + table.insert(drinks.drink_table, {'gooseberry', 'Gooseberry', '#9cf57c'}) + table.insert(drinks.drink_table, {'raspberry', 'Raspberry', '#C70039'}) + table.insert(drinks.drink_table, {'strawberry', 'Strawberry', '#ff3636'}) +end + +if minetest.get_modpath('farming_plus') then + drinks.juiceable['banana'] = true + drinks.juiceable['melon'] = true + drinks.juiceable['lemon_item'] = true + drinks.juiceable['orange_item'] = true + drinks.juiceable['peach_item'] = true + drinks.juiceable['rhubarb_item'] = true + drinks.juiceable['tomato_item'] = true + drinks.juiceable['strawberry_item'] = true + drinks.juiceable['raspberry_item'] = true + table.insert(drinks.drink_table, {'banana', 'Banana', '#eced9f'}) + table.insert(drinks.drink_table, {'lemon', 'Lemon', '#feffaa'}) + table.insert(drinks.drink_table, {'melon', 'Melon', '#ef4646'}) + table.insert(drinks.drink_table, {'orange', 'Orange', '#ffc417'}) + table.insert(drinks.drink_table, {'peach', 'Peach', '#f2bc1e'}) + table.insert(drinks.drink_table, {'rhubarb', 'Rhubarb', '#fb8461'}) + table.insert(drinks.drink_table, {'tomato', 'Tomato', '#d03a0e'}) + table.insert(drinks.drink_table, {'strawberry', 'Strawberry', '#ff3636'}) + table.insert(drinks.drink_table, {'raspberry', 'Raspberry', '#C70039'}) +end + +if minetest.get_modpath('crops') then + drinks.juiceable['melon'] = true + drinks.juiceable['melon_slice'] = true + drinks.juiceable['tomato'] = true + drinks.juiceable['pumpkin'] = true + table.insert(drinks.drink_table, {'melon', 'Melon', '#ef4646'}) + table.insert(drinks.drink_table, {'tomato', 'Tomato', '#d03a0e'}) + table.insert(drinks.drink_table, {'pumpkin', 'Pumpkin', '#ffc04c'}) +end + +if minetest.get_modpath('farming') then + drinks.juiceable['melon_8'] = true + drinks.juiceable['melon_slice'] = true + drinks.juiceable['tomato'] = true + drinks.juiceable['carrot'] = true + drinks.juiceable['cucumber'] = true + drinks.juiceable['grapes'] = true + drinks.juiceable['pumpkin'] = true + drinks.juiceable['raspberries'] = true + drinks.juiceable['rhubarb'] = true + drinks.juiceable['pineapple'] = true + drinks.juiceable['pineapple_ring'] = true + table.insert(drinks.drink_table, {'melon', 'Melon', '#ef4646'}) + table.insert(drinks.drink_table, {'tomato', 'Tomato', '#990000'}) + table.insert(drinks.drink_table, {'carrot', 'Carrot', '#ed9121'}) + table.insert(drinks.drink_table, {'cucumber', 'Cucumber', '#73af59'}) + table.insert(drinks.drink_table, {'grapes', 'Grape', '#b20056'}) + table.insert(drinks.drink_table, {'pumpkin', 'Pumpkin', '#ffc04c'}) + table.insert(drinks.drink_table, {'raspberries', 'Raspberry', '#C70039'}) + table.insert(drinks.drink_table, {'rhubarb', 'Rhubarb', '#fb8461'}) + table.insert(drinks.drink_table, {'pineapple', 'Pineapple', '#dcd611'}) +end + +if minetest.get_modpath('fruit') then + drinks.juiceable['pear'] = true + drinks.juiceable['plum'] = true + drinks.juiceable['peach'] = true + drinks.juiceable['orange'] = true + table.insert(drinks.drink_table, {'pear', 'Pear', '#ecff56'}) + table.insert(drinks.drink_table, {'plum', 'Plum', '#8e4585'}) + table.insert(drinks.drink_table, {'peach', 'Peach', '#f2bc1e'}) + table.insert(drinks.drink_table, {'orange', 'Orange', '#ffc417'}) +end + +if minetest.get_modpath('ethereal') then + drinks.juiceable['banana'] = true + drinks.juiceable['coconut'] = true + drinks.juiceable['orange'] = true + drinks.juiceable['strawberry'] = true + table.insert(drinks.drink_table, {'banana', 'Banana', '#eced9f'}) + table.insert(drinks.drink_table, {'coconut', 'Coconut', '#ffffff'}) + table.insert(drinks.drink_table, {'orange', 'Orange', '#ffc417'}) + table.insert(drinks.drink_table, {'strawberry', 'Strawberry', '#ff3636'}) +end + +if minetest.get_modpath('desert_life') then + drinks.juiceable['prickly_pear'] = true + drinks.juiceable['barrel_cacti_1'] = true + table.insert(drinks.drink_table, {'prickly', 'Cactus', '#96F97B'}) + table.insert(drinks.drink_table, {'barrel', 'Cactus', '#96F97B'}) +end + +-- replace craftitem to node definition +-- use existing node as template (e.g. 'vessel:glass_bottle') +drinks.register_item = function( name, template, def ) + local template_def = minetest.registered_nodes[template] + if template_def then + local drinks_def = table.copy(template_def) + + -- replace/add values + for k,v in pairs(def) do + if k == "groups" then + -- special handling for groups: merge instead replace + for g,n in pairs(v) do + drinks_def[k][g] = n + end + else + drinks_def[k]=v + end + end + + if def.inventory_image then + drinks_def.wield_image = drinks_def.inventory_image + drinks_def.tiles = { drinks_def.inventory_image } + end + + minetest.register_node( name, drinks_def ) + end +end + + +if minetest.get_modpath('thirsty') then + dofile(minetest.get_modpath('drinks')..'/drinks.lua') +else + dofile(minetest.get_modpath('drinks')..'/drinks2.lua') +end +dofile(minetest.get_modpath('drinks')..'/drink_machines.lua') +dofile(minetest.get_modpath('drinks')..'/formspecs.lua') diff --git a/mods/drinks/license.txt b/mods/drinks/license.txt new file mode 100644 index 0000000..49b202c --- /dev/null +++ b/mods/drinks/license.txt @@ -0,0 +1,16 @@ +Textures are licensed under CC by SA 3.0 Nathan Salapat + +The drinking glass textures are modified from the vessels mod where it is licensed as; +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Vanessa Ezekowitz +Copyright (C) 2016 Thomas-S + +The bucket textures are modified from the bucket mod where it is licensed as; +(CC BY-SA 3.0) celeron55 + +Code is licensed MIT, +Copyright 2019 Nathan Salapat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/drinks/mod.conf b/mods/drinks/mod.conf new file mode 100644 index 0000000..d0c47df --- /dev/null +++ b/mods/drinks/mod.conf @@ -0,0 +1,7 @@ +name = drinks +depends= bucket,default,vessels,stairs +description = Adds a juice press and two juice storage containers. Most fruits and several veggies can be juiced. The resulting drinks can be 'ate' to gain health, or if you are using the thirsty mod, to regain hydration. +author = Nathan, Napiophelios +optional_depends = hunger,thirsty,plantlife,farming_plus,crops,farming,minetest_doc_modpack,fruits,ethereal +release = 1004 +title = Drinks diff --git a/mods/drinks/models/drinks_liquid_barrel.obj b/mods/drinks/models/drinks_liquid_barrel.obj new file mode 100644 index 0000000..4a67ef4 --- /dev/null +++ b/mods/drinks/models/drinks_liquid_barrel.obj @@ -0,0 +1,385 @@ +# Blender v2.78 (sub 0) OBJ File: 'drinks.blend' +# www.blender.org +o Barrel_Cylinder.001 +v -0.406507 -0.168381 0.450000 +v -0.406507 -0.168381 -0.400000 +v -0.168381 -0.406507 0.450000 +v -0.168381 -0.406507 -0.400000 +v 0.168381 -0.406507 0.450000 +v 0.168381 -0.406507 -0.400000 +v 0.406507 -0.168381 0.450000 +v 0.406507 -0.168381 -0.400000 +v 0.406507 0.168381 0.450000 +v 0.406507 0.168381 -0.400000 +v 0.168381 0.406507 0.450000 +v 0.168381 0.406507 -0.400000 +v -0.168381 0.406507 0.450000 +v -0.168381 0.406507 -0.400000 +v -0.406507 0.168381 0.450000 +v -0.406507 0.168381 -0.400000 +v -0.447158 -0.185219 0.350000 +v -0.447158 -0.185219 -0.300000 +v -0.185219 -0.447158 -0.300000 +v -0.185219 -0.447158 0.350000 +v 0.185219 -0.447158 -0.300000 +v 0.185219 -0.447158 0.350000 +v 0.447158 -0.185219 -0.300000 +v 0.447158 -0.185219 0.350000 +v 0.447158 0.185219 -0.300000 +v 0.447158 0.185219 0.350000 +v 0.185219 0.447158 -0.300000 +v 0.185219 0.447158 0.350000 +v -0.185219 0.447158 -0.300000 +v -0.185219 0.447158 0.350000 +v -0.447158 0.185219 -0.300000 +v -0.447158 0.185219 0.350000 +v 0.500000 -0.400000 0.350000 +v 0.500000 -0.500000 0.350000 +v -0.500000 -0.400000 0.350000 +v -0.500000 -0.500000 0.350000 +v -0.000000 -0.300000 0.350000 +v 0.000000 -0.500000 0.350000 +v 0.500000 -0.400000 0.250000 +v 0.500000 -0.500000 0.250000 +v -0.500000 -0.400000 0.250000 +v -0.500000 -0.500000 0.250000 +v 0.000000 -0.300000 0.250000 +v 0.000000 -0.500000 0.250000 +v 0.500000 -0.400000 -0.200000 +v 0.500000 -0.500000 -0.200000 +v -0.500000 -0.400000 -0.200000 +v -0.500000 -0.500000 -0.200000 +v 0.000000 -0.300000 -0.200000 +v 0.000000 -0.500000 -0.200000 +v 0.500000 -0.400000 -0.300000 +v 0.500000 -0.500000 -0.300000 +v -0.500000 -0.400000 -0.300000 +v -0.500000 -0.500000 -0.300000 +v 0.000000 -0.300000 -0.300000 +v 0.000000 -0.500000 -0.300000 +v -0.073585 0.436096 0.000000 +v -0.091981 0.482086 0.000000 +v -0.052032 0.436096 -0.052032 +v -0.065041 0.482086 -0.065041 +v -0.000000 0.436096 -0.073585 +v -0.000000 0.482086 -0.091981 +v 0.052032 0.436096 -0.052032 +v 0.065041 0.482086 -0.065041 +v 0.073585 0.436096 0.000000 +v 0.091981 0.482086 0.000000 +v 0.052032 0.436096 0.052032 +v 0.065041 0.482086 0.065041 +v -0.000000 0.436096 0.073585 +v -0.000000 0.482086 0.091981 +v -0.052032 0.436096 0.052032 +v -0.065041 0.482086 0.065041 +v 0.028284 -0.396726 -0.471686 +v 0.028284 -0.373432 -0.384753 +v -0.050000 -0.345485 -0.392241 +v -0.050000 -0.368778 -0.479174 +v -0.035355 -0.379635 -0.383090 +v -0.035355 -0.402929 -0.470024 +v 0.000000 -0.393781 -0.379300 +v 0.000000 -0.417075 -0.466233 +v 0.035355 -0.379635 -0.383090 +v 0.035355 -0.402929 -0.470024 +v 0.050000 -0.345485 -0.392241 +v 0.050000 -0.368778 -0.479174 +v 0.000000 -0.408042 -0.468654 +v 0.000000 -0.384749 -0.381720 +v -0.028284 -0.396726 -0.471686 +v -0.028284 -0.373432 -0.384753 +v -0.040000 -0.369405 -0.479006 +v -0.040000 -0.346112 -0.392073 +v 0.040000 -0.346112 -0.392073 +v 0.040000 -0.369405 -0.479006 +vt 1.0000 0.9193 +vt 0.9874 1.0000 +vt 0.7357 1.0000 +vt 0.7232 0.9193 +vt 0.8500 0.9193 +vt 0.8374 1.0000 +vt 0.5857 1.0000 +vt 0.5731 0.9193 +vt 0.8849 0.9193 +vt 0.8724 1.0000 +vt 0.6207 1.0000 +vt 0.6081 0.9193 +vt 0.6234 0.9193 +vt 0.6360 1.0000 +vt 0.8876 1.0000 +vt 0.9002 0.9193 +vt 0.8078 0.9193 +vt 0.7952 1.0000 +vt 0.5436 1.0000 +vt 0.5310 0.9193 +vt 0.5401 0.9193 +vt 0.5526 1.0000 +vt 0.8043 1.0000 +vt 0.8169 0.9193 +vt 0.0000 0.3716 +vt 0.0646 0.1942 +vt 0.2357 0.1145 +vt 0.4130 0.1791 +vt 0.4928 0.3502 +vt 0.4282 0.5276 +vt 0.2571 0.6073 +vt 0.0797 0.5427 +vt 0.9614 0.9193 +vt 0.9488 1.0000 +vt 0.6971 1.0000 +vt 0.6845 0.9193 +vt 0.6518 0.9193 +vt 0.6643 1.0000 +vt 0.9160 1.0000 +vt 0.9286 0.9193 +vt 0.0000 0.1969 +vt 0.1032 0.0388 +vt 0.2879 0.0000 +vt 0.4460 0.1032 +vt 0.4848 0.2879 +vt 0.3816 0.4460 +vt 0.1969 0.4848 +vt 0.0388 0.3816 +vt 0.6643 0.3529 +vt 0.6518 0.4335 +vt 0.9286 0.4335 +vt 0.9160 0.3529 +vt 0.9488 0.3529 +vt 0.9614 0.4335 +vt 0.6845 0.4335 +vt 0.6971 0.3529 +vt 0.5526 0.3529 +vt 0.5401 0.4335 +vt 0.8169 0.4335 +vt 0.8043 0.3529 +vt 0.7952 0.3529 +vt 0.8078 0.4335 +vt 0.5310 0.4335 +vt 0.5436 0.3529 +vt 0.6360 0.3529 +vt 0.6234 0.4335 +vt 0.9002 0.4335 +vt 0.8876 0.3529 +vt 0.8724 0.3529 +vt 0.8849 0.4335 +vt 0.6081 0.4335 +vt 0.6207 0.3529 +vt 0.8374 0.3529 +vt 0.8500 0.4335 +vt 0.5731 0.4335 +vt 0.5857 0.3529 +vt 0.9874 0.3529 +vt 1.0000 0.4335 +vt 0.7232 0.4335 +vt 0.7357 0.3529 +vt 0.2562 0.8343 +vt 0.4617 0.8366 +vt 0.4691 0.8792 +vt 0.2563 0.9163 +vt 0.0501 0.8371 +vt 0.0428 0.8798 +vt 0.2556 0.7954 +vt 0.2555 0.7134 +vt 0.4690 0.7499 +vt 0.4617 0.7926 +vt 0.0501 0.7930 +vt 0.0426 0.7505 +vt 0.2283 0.8520 +vt 0.4369 0.8520 +vt 0.4369 0.8937 +vt 0.2283 0.8937 +vt 0.0197 0.8520 +vt 0.0197 0.8937 +vt 0.5058 0.8366 +vt 0.5058 0.7926 +vt 0.0060 0.8371 +vt 0.0060 0.7930 +vt 0.2502 0.9083 +vt 0.4557 0.9106 +vt 0.4632 0.9532 +vt 0.2503 0.9902 +vt 0.0441 0.9111 +vt 0.0368 0.9538 +vt 0.2496 0.8693 +vt 0.2495 0.7873 +vt 0.4630 0.8238 +vt 0.4557 0.8665 +vt 0.0441 0.8670 +vt 0.0367 0.8244 +vt 0.2224 0.9347 +vt 0.4310 0.9347 +vt 0.4310 0.9764 +vt 0.2224 0.9764 +vt 0.0138 0.9347 +vt 0.0138 0.9764 +vt 0.4998 0.9106 +vt 0.4998 0.8665 +vt 0.0000 0.9111 +vt 0.0000 0.8670 +vt 0.6949 0.1977 +vt 0.6590 0.1885 +vt 0.6791 0.1399 +vt 0.7110 0.1588 +vt 0.7110 0.1210 +vt 0.6590 0.0913 +vt 0.6949 0.0821 +vt 0.6682 0.0554 +vt 0.6104 0.0711 +vt 0.6293 0.0393 +vt 0.5915 0.0393 +vt 0.5618 0.0913 +vt 0.5526 0.0554 +vt 0.5259 0.0821 +vt 0.5417 0.1399 +vt 0.5098 0.1210 +vt 0.5098 0.1588 +vt 0.5618 0.1885 +vt 0.5259 0.1977 +vt 0.6104 0.2086 +vt 0.5526 0.2244 +vt 0.5915 0.2405 +vt 0.6293 0.2405 +vt 0.6682 0.2244 +vt 0.8644 0.0660 +vt 0.8658 0.0729 +vt 0.8425 0.0797 +vt 0.8369 0.0733 +vt 0.9516 0.0062 +vt 0.9428 0.0724 +vt 0.9155 0.0655 +vt 0.9235 0.0025 +vt 0.8900 0.0645 +vt 0.8927 0.0000 +vt 1.0000 0.1215 +vt 0.9945 0.1279 +vt 0.9374 0.0787 +vt 0.8611 0.0000 +vt 0.8901 0.0702 +vt 0.8287 0.0027 +vt 0.7853 0.1303 +vt 0.7796 0.1239 +vt 0.8684 0.1399 +vt 0.8488 0.1414 +vt 0.8881 0.1398 +vt 0.9081 0.1412 +vt 0.9142 0.0724 +vt 0.9302 0.1436 +vn -0.6551 -0.6551 -0.3766 +vn 0.0000 -0.9264 -0.3766 +vn 0.6551 -0.6551 -0.3766 +vn 0.9264 0.0000 -0.3766 +vn 0.6551 0.6551 -0.3766 +vn -0.0000 0.9264 -0.3766 +vn 0.0000 0.0000 -1.0000 +vn -0.6551 0.6551 -0.3766 +vn -0.9264 0.0000 -0.3766 +vn -0.0000 -0.0000 1.0000 +vn -0.9264 0.0000 0.3766 +vn -1.0000 0.0000 -0.0000 +vn -0.6551 0.6551 0.3766 +vn -0.7071 0.7071 -0.0000 +vn -0.0000 0.9264 0.3766 +vn -0.0000 1.0000 -0.0000 +vn 0.6551 0.6551 0.3766 +vn 0.7071 0.7071 0.0000 +vn 0.9264 0.0000 0.3766 +vn 1.0000 0.0000 0.0000 +vn 0.6551 -0.6551 0.3766 +vn 0.7071 -0.7071 0.0000 +vn 0.0000 -0.9264 0.3766 +vn 0.0000 -1.0000 0.0000 +vn -0.6551 -0.6551 0.3766 +vn -0.7071 -0.7071 -0.0000 +vn -0.1961 0.9806 -0.0000 +vn 0.1961 0.9806 -0.0000 +vn -0.8666 -0.3466 -0.3590 +vn -0.3590 -0.3466 -0.8666 +vn 0.3590 -0.3466 -0.8666 +vn 0.8666 -0.3466 -0.3590 +vn 0.8666 -0.3466 0.3590 +vn 0.3590 -0.3466 0.8666 +vn -0.3590 -0.3466 0.8666 +vn -0.8666 -0.3466 0.3590 +vn 0.0000 -0.2588 -0.9659 +vn -0.9239 -0.3696 0.0990 +vn -0.3827 -0.8924 0.2391 +vn 0.0648 0.9639 -0.2583 +vn 0.3827 -0.8924 0.2391 +vn 0.9239 -0.3696 0.0990 +vn -0.0648 0.9639 -0.2583 +vn -0.9239 0.3696 -0.0990 +vn -0.3827 0.8924 -0.2391 +vn 0.3827 0.8924 -0.2391 +vn 0.9239 0.3696 -0.0990 +g Barrel_Cylinder.001_None +s off +f 18/1/1 2/2/1 4/3/1 19/4/1 +f 19/5/2 4/6/2 6/7/2 21/8/2 +f 21/9/3 6/10/3 8/11/3 23/12/3 +f 23/13/4 8/14/4 10/15/4 25/16/4 +f 25/17/5 10/18/5 12/19/5 27/20/5 +f 27/21/6 12/22/6 14/23/6 29/24/6 +f 4/25/7 2/26/7 16/27/7 14/28/7 12/29/7 10/30/7 8/31/7 6/32/7 +f 29/33/8 14/34/8 16/35/8 31/36/8 +f 31/37/9 16/38/9 2/39/9 18/40/9 +f 1/41/10 3/42/10 5/43/10 7/44/10 9/45/10 11/46/10 13/47/10 15/48/10 +f 15/49/11 32/50/11 17/51/11 1/52/11 +f 32/50/12 31/37/12 18/40/12 17/51/12 +f 13/53/13 30/54/13 32/55/13 15/56/13 +f 30/54/14 29/33/14 31/36/14 32/55/14 +f 11/57/15 28/58/15 30/59/15 13/60/15 +f 28/58/16 27/21/16 29/24/16 30/59/16 +f 9/61/17 26/62/17 28/63/17 11/64/17 +f 26/62/18 25/17/18 27/20/18 28/63/18 +f 7/65/19 24/66/19 26/67/19 9/68/19 +f 24/66/20 23/13/20 25/16/20 26/67/20 +f 5/69/21 22/70/21 24/71/21 7/72/21 +f 22/70/22 21/9/22 23/12/22 24/71/22 +f 3/73/23 20/74/23 22/75/23 5/76/23 +f 20/74/24 19/5/24 21/8/24 22/75/24 +f 1/77/25 17/78/25 20/79/25 3/80/25 +f 17/78/26 18/1/26 19/4/26 20/79/26 +f 37/81/10 35/82/10 36/83/10 38/84/10 +f 33/85/10 37/81/10 38/84/10 34/86/10 +f 43/87/7 44/88/7 42/89/7 41/90/7 +f 39/91/7 40/92/7 44/88/7 43/87/7 +f 35/82/27 37/81/27 43/87/27 41/90/27 +f 38/93/24 36/94/24 42/95/24 44/96/24 +f 37/81/28 33/85/28 39/91/28 43/87/28 +f 34/97/24 38/93/24 44/96/24 40/98/24 +f 36/99/12 35/82/12 41/90/12 42/100/12 +f 33/85/20 34/101/20 40/102/20 39/91/20 +f 49/103/10 47/104/10 48/105/10 50/106/10 +f 45/107/10 49/103/10 50/106/10 46/108/10 +f 55/109/7 56/110/7 54/111/7 53/112/7 +f 51/113/7 52/114/7 56/110/7 55/109/7 +f 47/104/27 49/103/27 55/109/27 53/112/27 +f 50/115/24 48/116/24 54/117/24 56/118/24 +f 49/103/28 45/107/28 51/113/28 55/109/28 +f 46/119/24 50/115/24 56/118/24 52/120/24 +f 48/121/12 47/104/12 53/112/12 54/122/12 +f 45/107/20 46/123/20 52/124/20 51/113/20 +f 57/125/29 58/126/29 60/127/29 59/128/29 +f 59/129/30 60/127/30 62/130/30 61/131/30 +f 61/132/31 62/130/31 64/133/31 63/134/31 +f 63/135/32 64/133/32 66/136/32 65/137/32 +f 65/138/33 66/136/33 68/139/33 67/140/33 +f 67/141/34 68/139/34 70/142/34 69/143/34 +f 60/127/16 58/126/16 72/144/16 70/142/16 68/139/16 66/136/16 64/133/16 62/130/16 +f 69/145/35 70/142/35 72/144/35 71/146/35 +f 71/147/36 72/144/36 58/126/36 57/148/36 +f 82/149/37 73/150/37 92/151/37 84/152/37 +f 75/153/38 76/154/38 78/155/38 77/156/38 +f 77/156/39 78/155/39 80/157/39 79/158/39 +f 75/159/40 90/160/40 89/161/40 76/154/40 +f 79/158/41 80/157/41 82/149/41 81/162/41 +f 80/157/37 85/163/37 73/150/37 82/149/37 +f 81/162/42 82/149/42 84/152/42 83/164/42 +f 84/152/43 92/151/43 91/165/43 83/166/43 +f 74/167/44 91/168/44 92/151/44 73/150/44 +f 86/169/45 74/167/45 73/150/45 85/163/45 +f 88/170/46 86/169/46 85/163/46 87/171/46 +f 78/155/37 87/171/37 85/163/37 80/157/37 +f 90/172/47 88/170/47 87/171/47 89/161/47 +f 76/154/37 89/161/37 87/171/37 78/155/37 diff --git a/mods/drinks/models/drinks_press.obj b/mods/drinks/models/drinks_press.obj new file mode 100644 index 0000000..4265ffc --- /dev/null +++ b/mods/drinks/models/drinks_press.obj @@ -0,0 +1,427 @@ +# Blender v2.78 (sub 0) OBJ File: 'drinks.blend' +# www.blender.org +o Press_Cube.001 +v 0.490000 -0.450000 0.030000 +v 0.490000 0.400000 0.030000 +v 0.490000 -0.450000 0.130000 +v 0.490000 0.400000 0.130000 +v 0.350000 -0.450000 0.030000 +v 0.350000 0.400000 0.030000 +v 0.350000 -0.450000 0.130000 +v 0.350000 0.400000 0.130000 +v -0.490000 -0.450000 0.130000 +v -0.490000 0.400000 0.130000 +v -0.490000 -0.450000 0.030000 +v -0.490000 0.400000 0.030000 +v -0.350000 -0.450000 0.130000 +v -0.350000 0.400000 0.130000 +v -0.350000 -0.450000 0.030000 +v -0.350000 0.400000 0.030000 +v 0.500000 0.370000 -0.000000 +v -0.500000 0.370000 -0.000000 +v 0.500000 0.370000 0.160000 +v -0.500000 0.370000 0.160000 +v 0.500000 0.230000 -0.000000 +v -0.500000 0.230000 -0.000000 +v 0.500000 0.230000 0.160000 +v -0.500000 0.230000 0.160000 +v -0.286937 0.050000 0.080000 +v -0.202895 0.050000 -0.122895 +v -0.330000 -0.450000 0.080000 +v -0.330000 0.050000 0.080000 +v -0.233345 -0.450000 -0.153345 +v -0.233345 0.050000 -0.153345 +v 0.000000 -0.450000 -0.250000 +v 0.000000 0.050000 -0.250000 +v 0.233345 -0.450000 -0.153345 +v 0.233345 0.050000 -0.153345 +v 0.330000 -0.450000 0.080000 +v 0.330000 0.050000 0.080000 +v 0.233345 -0.450000 0.313345 +v 0.233345 0.050000 0.313345 +v -0.000000 -0.450000 0.410000 +v -0.000000 0.050000 0.410000 +v -0.233345 -0.450000 0.313345 +v -0.233345 0.050000 0.313345 +v 0.000000 0.050000 -0.206937 +v 0.202895 0.050000 -0.122895 +v 0.286937 0.050000 0.080000 +v 0.202895 0.050000 0.282895 +v -0.000000 0.050000 0.366937 +v -0.202895 0.050000 0.282895 +v -0.286937 -0.033841 0.080000 +v -0.202895 -0.033841 0.282895 +v -0.000000 -0.033841 0.366937 +v 0.202895 -0.033841 0.282895 +v 0.286937 -0.033841 0.080000 +v 0.202895 -0.033841 -0.122895 +v 0.000000 -0.033841 -0.206937 +v -0.202895 -0.033841 -0.122895 +v 0.300000 -0.500000 0.400000 +v 0.400000 -0.500000 -0.400000 +v -0.300000 -0.500000 0.400000 +v -0.400000 -0.500000 -0.400000 +v -0.000000 -0.500000 0.500000 +v 0.500000 -0.500000 0.080000 +v 0.000000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.080000 +v -0.000000 -0.500000 0.080000 +v 0.300000 -0.450000 0.400000 +v 0.400000 -0.450000 -0.400000 +v -0.300000 -0.450000 0.400000 +v -0.400000 -0.450000 -0.400000 +v -0.000000 -0.450000 0.500000 +v 0.500000 -0.450000 0.080000 +v 0.000000 -0.450000 -0.500000 +v -0.500000 -0.450000 0.080000 +v -0.000000 -0.450000 0.080000 +v -0.280783 0.000000 0.080000 +v -0.198544 0.000000 -0.118544 +v 0.000000 0.000000 -0.200783 +v 0.198544 0.000000 -0.118544 +v 0.280783 0.000000 0.080000 +v 0.198544 0.000000 0.278544 +v -0.000000 0.000000 0.360783 +v -0.198544 0.000000 0.278544 +v -0.241395 0.372715 -0.123119 +v 0.259946 0.372715 0.258765 +v -0.025000 -0.005792 0.080000 +v -0.025000 0.449165 0.080000 +v -0.017678 -0.005792 0.062322 +v -0.017678 0.449165 0.062322 +v -0.000000 -0.005792 0.055000 +v -0.000000 0.449165 0.055000 +v 0.017678 -0.005792 0.062322 +v 0.017678 0.449165 0.062322 +v 0.025000 -0.005792 0.080000 +v 0.025000 0.449165 0.080000 +v 0.017678 -0.005792 0.097678 +v 0.017678 0.449165 0.097678 +v -0.000000 -0.005792 0.105000 +v -0.000000 0.449165 0.105000 +v -0.017678 -0.005792 0.097678 +v -0.017678 0.449165 0.097678 +v 0.273063 0.394363 0.241544 +v -0.228277 0.394363 -0.140340 +v 0.273063 0.424977 0.241544 +v -0.228277 0.424978 -0.140340 +v 0.259946 0.446625 0.258765 +v -0.241395 0.446625 -0.123119 +v 0.241395 0.446625 0.283119 +v -0.259946 0.446625 -0.098765 +v 0.228277 0.424977 0.300340 +v -0.273063 0.424977 -0.081544 +v 0.228277 0.394363 0.300340 +v -0.273063 0.394363 -0.081544 +v 0.241395 0.372715 0.283119 +v -0.259946 0.372715 -0.098765 +vt 1.0000 0.8133 +vt 0.5747 0.8133 +vt 0.5747 0.7632 +vt 1.0000 0.7632 +vt 0.5747 0.6932 +vt 1.0000 0.6932 +vt 0.5747 0.6431 +vt 1.0000 0.6431 +vt 1.0000 0.8833 +vt 0.5747 0.8833 +vt 0.3063 0.3026 +vt 0.4945 0.0006 +vt 0.7460 0.2422 +vt 0.6556 0.5216 +vt 0.5246 0.8833 +vt 0.5246 0.8133 +vt 0.5246 0.8414 +vt 0.9500 0.8414 +vt 0.9500 0.8914 +vt 0.5246 0.8914 +vt 0.9500 0.9615 +vt 0.5246 0.9615 +vt 0.5246 0.7213 +vt 0.9500 0.7213 +vt 0.9500 0.7713 +vt 0.5246 0.7713 +vt 0.0533 0.1441 +vt 0.2265 0.0006 +vt 1.0000 0.8914 +vt 1.0000 0.9615 +vt 0.9472 0.7427 +vt 0.5705 0.7427 +vt 0.5705 0.6824 +vt 0.9472 0.6824 +vt 0.5705 0.6296 +vt 0.9472 0.6296 +vt 0.9472 0.8557 +vt 0.5705 0.8557 +vt 0.5705 0.7954 +vt 0.9472 0.7954 +vt 1.0000 0.8557 +vt 1.0000 0.7954 +vt 0.5177 0.8557 +vt 0.5177 0.7954 +vt 0.7652 0.5368 +vt 0.9836 0.5368 +vt 0.9836 0.6201 +vt 0.7652 0.6201 +vt 0.7488 0.4972 +vt 1.0000 0.4972 +vt 0.9836 0.5368 +vt 0.7652 0.5368 +vt 1.0000 0.0000 +vt 1.0000 0.4972 +vt 0.7488 0.4972 +vt 0.7488 0.0000 +vt 0.9836 0.6201 +vt 0.7652 0.6201 +vt 0.9836 0.5368 +vt 0.7652 0.5368 +vt 1.0000 0.0000 +vt 1.0000 0.4972 +vt 0.7488 0.4972 +vt 0.7488 0.0000 +vt 0.7652 0.5368 +vt 0.9836 0.5368 +vt 0.9836 0.6201 +vt 0.7652 0.6201 +vt 0.7488 0.4972 +vt 1.0000 0.4972 +vt 0.9836 0.5368 +vt 0.7652 0.5368 +vt 1.0000 0.0000 +vt 0.7488 0.0000 +vt 0.7652 0.5368 +vt 0.9836 0.5368 +vt 0.9836 0.6201 +vt 0.7652 0.6201 +vt 0.9836 0.5368 +vt 0.7652 0.5368 +vt 1.0000 0.0000 +vt 1.0000 0.4972 +vt 0.7488 0.4972 +vt 0.7488 0.0000 +vt 0.9836 0.6201 +vt 0.7652 0.6201 +vt 0.7488 0.4972 +vt 1.0000 0.4972 +vt 1.0000 0.0000 +vt 0.7488 0.0000 +vt 0.1181 0.6046 +vt 0.4448 0.7254 +vt 0.7488 0.4972 +vt 1.0000 0.4972 +vt 0.9836 0.5368 +vt 0.7652 0.5368 +vt 1.0000 0.0000 +vt 0.7488 0.0000 +vt 0.9836 0.6201 +vt 0.7652 0.6201 +vt 1.0000 0.0000 +vt 1.0000 0.4972 +vt 0.7488 0.4972 +vt 0.7488 0.0000 +vt 0.9836 0.6201 +vt 0.7652 0.6201 +vt 1.0000 0.0000 +vt 0.7488 0.0000 +vt 0.0006 0.3630 +vt 0.9836 0.6201 +vt 0.7652 0.6201 +vt 0.3057 0.3020 +vt 0.6550 0.5209 +vt 0.4442 0.7248 +vt 0.1174 0.6040 +vt 0.0527 0.1434 +vt 0.0000 0.3624 +vt 0.4939 0.0000 +vt 0.7453 0.2416 +vt 0.2259 0.0000 +vt 0.4840 0.9815 +vt 0.6645 0.9816 +vt 0.6645 1.0000 +vt 0.4840 0.9999 +vt 0.1389 1.0000 +vt 0.0000 1.0000 +vt 0.0000 0.9816 +vt 0.1389 0.9816 +vt 0.5106 1.0000 +vt 0.3717 1.0000 +vt 0.3717 0.9816 +vt 0.5106 0.9816 +vt 0.0000 0.9814 +vt 0.1805 0.9814 +vt 0.1805 0.9998 +vt 0.0000 0.9998 +vt 0.3323 0.9815 +vt 0.3322 0.9999 +vt 0.2553 1.0000 +vt 0.2553 0.9816 +vt 0.2489 0.4939 +vt 0.1374 0.3825 +vt 0.1374 0.2249 +vt 0.2489 0.1134 +vt 0.4065 0.1134 +vt 0.5180 0.2249 +vt 0.5180 0.3825 +vt 0.4065 0.4939 +vt 0.9532 0.8586 +vt 0.9418 0.8699 +vt 0.9258 0.8699 +vt 0.9145 0.8586 +vt 0.9145 0.8425 +vt 0.9258 0.8312 +vt 0.9418 0.8312 +vt 0.9532 0.8425 +vt 0.0160 0.8312 +vt 0.4121 0.8312 +vt 0.4121 0.8479 +vt 0.0160 0.8479 +vt 0.5843 0.8425 +vt 0.5843 0.8586 +vt 0.4121 0.8645 +vt 0.0160 0.8645 +vt 0.5843 0.9548 +vt 0.9145 0.9548 +vt 0.9145 0.9709 +vt 0.5843 0.9709 +vt 0.4121 0.8812 +vt 0.0160 0.8812 +vt 0.5843 0.9388 +vt 0.9145 0.9388 +vt 0.4121 0.8978 +vt 0.0160 0.8978 +vt 0.5569 0.8699 +vt 0.5456 0.8586 +vt 0.5456 0.8425 +vt 0.5569 0.8312 +vt 0.5730 0.8312 +vt 0.5730 0.8699 +vt 0.5843 0.9227 +vt 0.9145 0.9227 +vt 0.0160 0.7646 +vt 0.4121 0.7646 +vt 0.4121 0.7812 +vt 0.0160 0.7812 +vt 0.5843 0.8746 +vt 0.9145 0.8746 +vt 0.9145 0.8907 +vt 0.5843 0.8907 +vt 0.5843 0.9067 +vt 0.9145 0.9067 +vt 0.4121 0.7979 +vt 0.0160 0.7979 +vt 0.4523 0.7646 +vt 0.4523 0.7812 +vt 0.4405 0.7930 +vt 0.4239 0.7930 +vt 0.4239 0.7528 +vt 0.4405 0.7528 +vt 0.4121 0.8145 +vt 0.0160 0.8145 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 -0.0000 +vn 0.0000 1.0000 0.0000 +vn -0.9239 0.0000 0.3827 +vn -0.9239 0.0000 -0.3827 +vn -0.3827 0.0000 0.9239 +vn -0.3827 0.0000 -0.9239 +vn 0.3827 0.0000 -0.9239 +vn 0.9239 0.0000 -0.3827 +vn 0.3827 0.0000 0.9239 +vn 0.9239 0.0000 0.3827 +vn -0.9790 0.0000 -0.2040 +vn 0.8480 0.0000 0.5300 +vn -0.8480 0.0000 0.5300 +vn 0.9790 0.0000 -0.2040 +vn 0.2425 0.0000 -0.9701 +vn -0.3162 0.0000 0.9487 +vn -0.2425 0.0000 -0.9701 +vn 0.3162 0.0000 0.9487 +vn -0.7955 -0.0000 -0.6060 +vn -0.6060 -0.0000 0.7955 +vn -0.4285 0.7071 0.5625 +vn 0.7955 -0.0000 0.6060 +vn 0.4285 0.7071 -0.5625 +vn 0.6060 -0.0000 -0.7955 +vn 0.4285 -0.7071 -0.5625 +vn -0.4285 -0.7071 0.5625 +g Press_Cube.001_None +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 65/11/5 64/12/5 60/13/5 63/14/5 +f 8/15/6 4/16/6 2/2/6 6/10/6 +f 9/17/3 10/18/3 12/19/3 11/20/3 +f 11/20/4 12/19/4 16/21/4 15/22/4 +f 15/23/1 16/24/1 14/25/1 13/26/1 +f 13/26/2 14/25/2 10/18/2 9/17/2 +f 61/27/5 59/28/5 64/12/5 65/11/5 +f 16/21/6 12/19/6 10/29/6 14/30/6 +f 17/31/6 18/32/6 20/33/6 19/34/6 +f 19/34/2 20/33/2 24/35/2 23/36/2 +f 23/37/5 24/38/5 22/39/5 21/40/5 +f 21/40/4 22/39/4 18/32/4 17/31/4 +f 19/41/1 23/37/1 21/40/1 17/42/1 +f 24/38/3 20/43/3 18/44/3 22/39/3 +f 45/45/7 44/46/7 54/47/7 53/48/7 +f 34/49/6 32/50/6 43/51/6 44/52/6 +f 27/53/8 28/54/8 30/55/8 29/56/8 +f 44/52/9 43/51/9 55/57/9 54/58/9 +f 30/55/6 28/54/6 25/59/6 26/60/6 +f 29/61/10 30/62/10 32/63/10 31/64/10 +f 46/65/8 45/66/8 53/67/8 52/68/8 +f 40/69/6 38/70/6 46/71/6 47/72/6 +f 31/73/11 32/50/11 34/49/11 33/74/11 +f 48/75/11 47/76/11 51/77/11 50/78/11 +f 32/63/6 30/62/6 26/79/6 43/80/6 +f 33/81/12 34/82/12 36/83/12 35/84/12 +f 43/80/13 26/79/13 56/85/13 55/86/13 +f 38/87/6 36/88/6 45/66/6 46/65/6 +f 35/89/14 36/88/14 38/87/14 37/90/14 +f 62/91/5 65/11/5 63/14/5 58/92/5 +f 28/93/6 42/94/6 48/95/6 25/96/6 +f 37/97/13 38/70/13 40/69/13 39/98/13 +f 36/83/6 34/82/6 44/46/6 45/45/6 +f 47/72/10 46/71/10 52/99/10 51/100/10 +f 39/101/9 40/102/9 42/103/9 41/104/9 +f 26/60/14 25/59/14 49/105/14 56/106/14 +f 42/103/6 40/102/6 47/76/6 48/75/6 +f 41/107/7 42/94/7 28/93/7 27/108/7 +f 57/109/5 61/27/5 65/11/5 62/91/5 +f 25/96/12 48/95/12 50/110/12 49/111/12 +f 74/112/6 72/113/6 69/114/6 73/115/6 +f 70/116/6 74/112/6 73/115/6 68/117/6 +f 71/118/6 67/119/6 72/113/6 74/112/6 +f 66/120/6 71/118/6 74/112/6 70/116/6 +f 60/121/15 64/122/15 73/123/15 69/124/15 +f 57/125/16 62/126/16 71/127/16 66/128/16 +f 64/129/17 59/130/17 68/131/17 73/132/17 +f 62/133/18 58/134/18 67/135/18 71/136/18 +f 58/134/19 63/137/19 72/138/19 67/135/19 +f 59/130/20 61/139/20 70/140/20 68/131/20 +f 63/137/21 60/121/21 69/124/21 72/138/21 +f 61/139/22 57/125/22 66/128/22 70/140/22 +f 75/141/6 82/142/6 81/143/6 80/144/6 79/145/6 78/146/6 77/147/6 76/148/6 +f 102/149/23 83/150/23 114/151/23 112/152/23 110/153/23 108/154/23 106/155/23 104/156/23 +f 85/157/8 86/158/8 88/159/8 87/160/8 +f 109/161/24 110/153/24 112/152/24 111/162/24 +f 87/160/10 88/159/10 90/163/10 89/164/10 +f 107/165/25 108/166/25 110/167/25 109/168/25 +f 89/164/11 90/163/11 92/169/11 91/170/11 +f 105/171/6 106/172/6 108/166/6 107/165/6 +f 91/170/12 92/169/12 94/173/12 93/174/12 +f 84/175/26 101/176/26 103/177/26 105/178/26 107/179/26 109/161/26 111/162/26 113/180/26 +f 103/181/27 104/182/27 106/172/27 105/171/27 +f 93/183/14 94/184/14 96/185/14 95/186/14 +f 113/187/5 114/188/5 83/189/5 84/190/5 +f 101/191/28 102/192/28 104/182/28 103/181/28 +f 95/186/13 96/185/13 98/193/13 97/194/13 +f 88/195/6 86/196/6 100/197/6 98/198/6 96/185/6 94/184/6 92/199/6 90/200/6 +f 84/190/29 83/189/29 102/192/29 101/191/29 +f 97/194/9 98/193/9 100/201/9 99/202/9 +f 111/162/30 112/152/30 114/188/30 113/187/30 +f 99/202/7 100/201/7 86/158/7 85/157/7 diff --git a/mods/drinks/models/drinks_silo.obj b/mods/drinks/models/drinks_silo.obj new file mode 100644 index 0000000..d31e98b --- /dev/null +++ b/mods/drinks/models/drinks_silo.obj @@ -0,0 +1,449 @@ +# Blender v2.78 (sub 2) OBJ File: 'drinks.blend' +# www.blender.org +o Sphere_Sphere.001 +v 0.355973 -0.470000 -0.283179 +v 0.355973 0.000000 -0.283179 +v 0.285262 -0.470000 -0.353890 +v 0.285262 0.000000 -0.353890 +v 0.426684 -0.470000 -0.353890 +v 0.426684 0.000000 -0.353890 +v 0.355973 -0.470000 -0.424601 +v 0.355973 0.000000 -0.424601 +v 0.256978 -0.480000 -0.353890 +v 0.355973 -0.480000 -0.254895 +v 0.355973 -0.480000 -0.452885 +v 0.454968 -0.480000 -0.353890 +v 0.256978 -0.500000 -0.353890 +v 0.355973 -0.500000 -0.254895 +v 0.355973 -0.500000 -0.452885 +v 0.454968 -0.500000 -0.353890 +v 0.355973 0.030000 -0.283179 +v 0.285262 0.030000 -0.353890 +v 0.296242 0.036360 -0.364870 +v 0.366953 0.036360 -0.294159 +v -0.285262 -0.470000 -0.353890 +v -0.285262 0.000000 -0.353890 +v -0.355973 -0.470000 -0.283179 +v -0.355973 0.000000 -0.283179 +v -0.355973 -0.470000 -0.424601 +v -0.355973 0.000000 -0.424601 +v -0.426684 -0.470000 -0.353890 +v -0.426684 0.000000 -0.353890 +v -0.355973 -0.480000 -0.254895 +v -0.256978 -0.480000 -0.353890 +v -0.454968 -0.480000 -0.353890 +v -0.355973 -0.480000 -0.452885 +v -0.355973 -0.500000 -0.254895 +v -0.256978 -0.500000 -0.353890 +v -0.454968 -0.500000 -0.353890 +v -0.355973 -0.500000 -0.452885 +v -0.285262 0.030000 -0.353890 +v -0.355973 0.030000 -0.283179 +v -0.366953 0.036360 -0.294159 +v -0.296242 0.036360 -0.364870 +v 0.285262 -0.470000 0.358056 +v 0.285262 0.000000 0.358056 +v 0.355973 -0.470000 0.287346 +v 0.355973 0.000000 0.287346 +v 0.355973 -0.470000 0.428767 +v 0.355973 0.000000 0.428767 +v 0.426684 -0.470000 0.358056 +v 0.426684 0.000000 0.358056 +v 0.355973 -0.480000 0.259061 +v 0.256978 -0.480000 0.358056 +v 0.454968 -0.480000 0.358056 +v 0.355973 -0.480000 0.457051 +v 0.355973 -0.500000 0.259061 +v 0.256978 -0.500000 0.358056 +v 0.454968 -0.500000 0.358056 +v 0.355973 -0.500000 0.457051 +v 0.285262 0.030000 0.358056 +v 0.355973 0.030000 0.287346 +v 0.366953 0.036360 0.298326 +v 0.296242 0.036360 0.369036 +v -0.355973 -0.470000 0.287346 +v -0.355973 0.000000 0.287346 +v -0.285263 -0.470000 0.358056 +v -0.285263 0.000000 0.358056 +v -0.426684 -0.470000 0.358056 +v -0.426684 0.000000 0.358056 +v -0.355973 -0.470000 0.428767 +v -0.355973 0.000000 0.428767 +v -0.256978 -0.480000 0.358056 +v -0.355973 -0.480000 0.259061 +v -0.355973 -0.480000 0.457051 +v -0.454968 -0.480000 0.358056 +v -0.256978 -0.500000 0.358056 +v -0.355973 -0.500000 0.259061 +v -0.355973 -0.500000 0.457051 +v -0.454968 -0.500000 0.358056 +v -0.355973 0.030000 0.287346 +v -0.285263 0.030000 0.358056 +v -0.296242 0.036360 0.369036 +v -0.366953 0.036360 0.298326 +v 0.298674 1.404509 -0.123715 +v 0.483264 -0.154509 -0.200174 +v 0.000000 -0.350000 0.000000 +v 0.298674 1.404509 0.123715 +v 0.483264 1.154508 0.200174 +v 0.483264 -0.154509 0.200174 +v 0.298674 -0.304509 0.123715 +v 0.123715 1.404509 0.298674 +v 0.200175 1.154508 0.483264 +v 0.200175 -0.154509 0.483264 +v 0.123715 -0.304509 0.298674 +v -0.123715 1.404509 0.298674 +v -0.200174 1.154508 0.483264 +v -0.200174 -0.154509 0.483264 +v -0.123715 -0.304509 0.298674 +v -0.298674 1.404509 0.123715 +v -0.483264 1.154508 0.200175 +v -0.483264 -0.154509 0.200175 +v -0.298673 -0.304509 0.123715 +v -0.000000 1.500000 0.000000 +v -0.298674 1.404509 -0.123715 +v -0.483264 1.154508 -0.200174 +v -0.483264 -0.154509 -0.200174 +v -0.298673 -0.304509 -0.123715 +v -0.123715 1.404509 -0.298674 +v -0.200174 1.154508 -0.483264 +v -0.200174 -0.154509 -0.483264 +v -0.123715 -0.304509 -0.298673 +v 0.123715 1.404509 -0.298674 +v 0.200175 1.154508 -0.483264 +v 0.200175 -0.154509 -0.483264 +v 0.123715 -0.304509 -0.298673 +v 0.483264 1.154508 -0.200174 +v 0.298673 -0.304509 -0.123715 +vt 1.000000 0.008414 +vt 0.978921 0.399028 +vt 0.894297 0.383031 +vt 0.916891 0.003929 +vt 0.822710 0.352283 +vt 0.834561 0.000001 +vt 0.760707 0.354848 +vt 0.739397 0.000000 +vt 0.689594 0.414136 +vt 0.642691 0.007416 +vt 0.756477 0.490620 +vt 0.709526 0.588101 +vt 0.670960 0.596854 +vt 0.740550 0.468871 +vt 0.849070 0.402909 +vt 0.749567 0.419582 +vt 0.853240 0.441198 +vt 0.727002 0.453325 +vt 0.854930 0.419425 +vt 0.924304 0.516307 +vt 0.847709 0.465468 +vt 0.944476 0.505392 +vt 0.932660 0.620289 +vt 0.957582 0.639217 +vt 0.963235 0.492572 +vt 0.982975 0.636506 +vt 0.651986 0.586137 +vt 0.974085 0.425479 +vt 0.885915 0.409359 +vt 0.712088 0.441124 +vt 1.000000 0.008414 +vt 0.978921 0.399028 +vt 0.894297 0.383031 +vt 0.916891 0.003929 +vt 0.822710 0.352283 +vt 0.834561 0.000001 +vt 0.760707 0.354848 +vt 0.739397 0.000000 +vt 0.689594 0.414136 +vt 0.642691 0.007416 +vt 0.756477 0.490620 +vt 0.709526 0.588101 +vt 0.670960 0.596854 +vt 0.740550 0.468871 +vt 0.849070 0.402909 +vt 0.749567 0.419582 +vt 0.853240 0.441198 +vt 0.727002 0.453325 +vt 0.854930 0.419425 +vt 0.924304 0.516307 +vt 0.847709 0.465468 +vt 0.944476 0.505392 +vt 0.932660 0.620289 +vt 0.957582 0.639217 +vt 0.963235 0.492572 +vt 0.982975 0.636506 +vt 0.651986 0.586137 +vt 0.974085 0.425479 +vt 0.885915 0.409359 +vt 0.712088 0.441124 +vt 1.000000 0.008414 +vt 0.978921 0.399028 +vt 0.894297 0.383031 +vt 0.916891 0.003929 +vt 0.822710 0.352283 +vt 0.834561 0.000001 +vt 0.760707 0.354848 +vt 0.739397 0.000000 +vt 0.689594 0.414136 +vt 0.642691 0.007416 +vt 0.756477 0.490620 +vt 0.709526 0.588101 +vt 0.670960 0.596854 +vt 0.740550 0.468871 +vt 0.849070 0.402909 +vt 0.749567 0.419582 +vt 0.853240 0.441198 +vt 0.727002 0.453325 +vt 0.854930 0.419425 +vt 0.924304 0.516307 +vt 0.847709 0.465468 +vt 0.944476 0.505392 +vt 0.932660 0.620289 +vt 0.957582 0.639217 +vt 0.963235 0.492572 +vt 0.982975 0.636506 +vt 0.651986 0.586137 +vt 0.974085 0.425479 +vt 0.885915 0.409359 +vt 0.712088 0.441124 +vt 1.000000 0.008414 +vt 0.978921 0.399028 +vt 0.894297 0.383031 +vt 0.916891 0.003929 +vt 0.822710 0.352283 +vt 0.834561 0.000001 +vt 0.760707 0.354848 +vt 0.739397 0.000000 +vt 0.689594 0.414136 +vt 0.642691 0.007416 +vt 0.756477 0.490620 +vt 0.709526 0.588101 +vt 0.670960 0.596854 +vt 0.740550 0.468871 +vt 0.849070 0.402909 +vt 0.749567 0.419582 +vt 0.853240 0.441198 +vt 0.727002 0.453325 +vt 0.854930 0.419425 +vt 0.924304 0.516307 +vt 0.847709 0.465468 +vt 0.944476 0.505392 +vt 0.932660 0.620289 +vt 0.957582 0.639217 +vt 0.963235 0.492572 +vt 0.982975 0.636506 +vt 0.651986 0.586137 +vt 0.974085 0.425479 +vt 0.885915 0.409359 +vt 0.712088 0.441124 +vt 0.350770 0.992591 +vt 0.308827 0.883889 +vt 0.384778 0.836945 +vt 0.470279 0.909152 +vt 0.776139 0.791890 +vt 0.748838 0.668985 +vt 0.838661 0.688066 +vt 0.613361 0.001953 +vt 0.613361 0.501732 +vt 0.460509 0.501732 +vt 0.460509 0.001953 +vt 0.293637 0.753973 +vt 0.741714 0.572150 +vt 0.892517 0.611056 +vt 0.980498 0.736300 +vt 0.891124 0.758070 +vt 0.414908 0.760781 +vt 0.526265 0.770946 +vt 0.307657 0.501732 +vt 0.307657 0.001953 +vt 0.963601 0.886471 +vt 0.883457 0.843656 +vt 0.392837 0.683662 +vt 0.488453 0.624099 +vt 0.154805 0.501732 +vt 0.154805 0.001953 +vt 0.851929 0.986328 +vt 0.821052 0.901634 +vt 0.327901 0.636527 +vt 0.367274 0.529625 +vt 0.001953 0.501732 +vt 0.001953 0.001953 +vt 0.703139 0.986328 +vt 0.736320 0.903076 +vt 0.246988 0.639780 +vt 0.211521 0.529625 +vt 0.613472 0.002064 +vt 0.613472 0.501843 +vt 0.460620 0.501842 +vt 0.460620 0.002064 +vt 0.592690 0.888063 +vt 0.672296 0.847742 +vt 0.184525 0.693546 +vt 0.086511 0.626896 +vt 0.307768 0.501842 +vt 0.307768 0.002064 +vt 0.574219 0.742591 +vt 0.660933 0.763134 +vt 0.168400 0.777459 +vt 0.045236 0.783554 +vt 0.154916 0.501842 +vt 0.154916 0.002064 +vt 0.651237 0.619072 +vt 0.709912 0.688420 +vt 0.209836 0.861318 +vt 0.104223 0.939033 +vt 0.002064 0.501842 +vt 0.002064 0.002064 +vn -0.7071 0.0000 0.7071 +vn -0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 0.7071 +vn 0.3162 0.8944 0.3162 +vn 0.2796 0.9185 -0.2796 +vn -0.3162 0.8944 -0.3162 +vn -0.3162 0.8944 0.3162 +vn 0.3162 0.8944 -0.3162 +vn -0.2796 0.9185 -0.2796 +vn 0.2796 0.9185 0.2796 +vn -0.2796 0.9185 0.2796 +vn 0.8045 0.5940 0.0000 +vn 0.1506 -0.9886 0.0000 +vn 1.0000 0.0000 -0.0000 +vn 0.3045 0.9525 0.0000 +vn 0.6306 -0.7761 -0.0000 +vn 0.4459 -0.7761 0.4459 +vn 0.5688 0.5940 0.5688 +vn 0.1065 -0.9886 0.1065 +vn 0.2153 0.9525 0.2153 +vn 0.0000 -0.7761 0.6306 +vn 0.0000 0.5940 0.8045 +vn 0.0000 -0.9886 0.1506 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 0.9525 0.3045 +vn -0.4459 -0.7761 0.4459 +vn -0.5688 0.5940 0.5688 +vn -0.1065 -0.9886 0.1065 +vn -0.2153 0.9525 0.2153 +vn -0.6306 -0.7761 0.0000 +vn -0.8045 0.5940 0.0000 +vn -0.1506 -0.9886 0.0000 +vn -1.0000 0.0000 0.0000 +vn -0.3045 0.9525 0.0000 +vn -0.4459 -0.7761 -0.4459 +vn -0.5688 0.5940 -0.5688 +vn -0.1065 -0.9886 -0.1065 +vn -0.2153 0.9525 -0.2153 +vn -0.0000 -0.7761 -0.6306 +vn -0.0000 0.5940 -0.8045 +vn -0.0000 -0.9886 -0.1506 +vn -0.0000 0.0000 -1.0000 +vn -0.0000 0.9525 -0.3045 +vn 0.4459 -0.7761 -0.4459 +vn 0.5688 0.5940 -0.5688 +vn 0.1065 -0.9886 -0.1065 +vn 0.2153 0.9525 -0.2153 +g Sphere_Sphere.001_None +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/8/4 6/7/4 2/9/4 1/10/4 +f 5/11/5 1/12/5 10/13/5 12/14/5 +f 6/7/6 8/5/6 19/15/6 20/16/6 +f 11/17/3 12/14/3 16/18/3 15/19/3 +f 3/20/7 7/21/7 11/17/7 9/22/7 +f 1/23/8 3/20/8 9/22/8 10/24/8 +f 7/21/9 5/11/9 12/14/9 11/17/9 +f 10/24/1 9/22/1 13/25/1 14/26/1 +f 12/14/4 10/13/4 14/27/4 16/18/4 +f 9/22/2 11/17/2 15/19/2 13/25/2 +f 4/3/1 2/2/1 17/28/1 18/29/1 +f 2/9/4 6/7/4 20/16/4 17/30/4 +f 8/5/2 4/3/2 18/29/2 19/15/2 +f 21/31/4 22/32/4 24/33/4 23/34/4 +f 23/34/1 24/33/1 28/35/1 27/36/1 +f 27/36/2 28/35/2 26/37/2 25/38/2 +f 25/38/3 26/37/3 22/39/3 21/40/3 +f 25/41/9 21/42/9 30/43/9 32/44/9 +f 26/37/10 28/35/10 39/45/10 40/46/10 +f 31/47/2 32/44/2 36/48/2 35/49/2 +f 23/50/8 27/51/8 31/47/8 29/52/8 +f 21/53/5 23/50/5 29/52/5 30/54/5 +f 27/51/7 25/41/7 32/44/7 31/47/7 +f 30/54/4 29/52/4 33/55/4 34/56/4 +f 32/44/3 30/43/3 34/57/3 36/48/3 +f 29/52/1 31/47/1 35/49/1 33/55/1 +f 24/33/4 22/32/4 37/58/4 38/59/4 +f 22/39/3 26/37/3 40/46/3 37/60/3 +f 28/35/1 24/33/1 38/59/1 39/45/1 +f 41/61/2 42/62/2 44/63/2 43/64/2 +f 43/64/3 44/63/3 48/65/3 47/66/3 +f 47/66/4 48/65/4 46/67/4 45/68/4 +f 45/68/1 46/67/1 42/69/1 41/70/1 +f 45/71/8 41/72/8 50/73/8 52/74/8 +f 46/67/11 48/65/11 59/75/11 60/76/11 +f 51/77/4 52/74/4 56/78/4 55/79/4 +f 43/80/9 47/81/9 51/77/9 49/82/9 +f 41/83/7 43/80/7 49/82/7 50/84/7 +f 47/81/5 45/71/5 52/74/5 51/77/5 +f 50/84/2 49/82/2 53/85/2 54/86/2 +f 52/74/1 50/73/1 54/87/1 56/78/1 +f 49/82/3 51/77/3 55/79/3 53/85/3 +f 44/63/2 42/62/2 57/88/2 58/89/2 +f 42/69/1 46/67/1 60/76/1 57/90/1 +f 48/65/3 44/63/3 58/89/3 59/75/3 +f 61/91/3 62/92/3 64/93/3 63/94/3 +f 63/94/4 64/93/4 68/95/4 67/96/4 +f 67/96/1 68/95/1 66/97/1 65/98/1 +f 65/98/2 66/97/2 62/99/2 61/100/2 +f 65/101/7 61/102/7 70/103/7 72/104/7 +f 66/97/12 68/95/12 79/105/12 80/106/12 +f 71/107/1 72/104/1 76/108/1 75/109/1 +f 63/110/5 67/111/5 71/107/5 69/112/5 +f 61/113/9 63/110/9 69/112/9 70/114/9 +f 67/111/8 65/101/8 72/104/8 71/107/8 +f 70/114/3 69/112/3 73/115/3 74/116/3 +f 72/104/2 70/103/2 74/117/2 76/108/2 +f 69/112/4 71/107/4 75/109/4 73/115/4 +f 64/93/3 62/92/3 77/118/3 78/119/3 +f 62/99/2 66/97/2 80/106/2 77/120/2 +f 68/95/4 64/93/4 78/119/4 79/105/4 +f 113/121/13 81/122/13 84/123/13 85/124/13 +f 83/125/14 114/126/14 87/127/14 +f 82/128/15 113/129/15 85/130/15 86/131/15 +f 81/122/16 100/132/16 84/123/16 +f 114/126/17 82/133/17 86/134/17 87/127/17 +f 87/127/18 86/134/18 90/135/18 91/136/18 +f 85/124/19 84/123/19 88/137/19 89/138/19 +f 83/125/20 87/127/20 91/136/20 +f 86/131/4 85/130/4 89/139/4 90/140/4 +f 84/123/21 100/132/21 88/137/21 +f 91/136/22 90/135/22 94/141/22 95/142/22 +f 89/138/23 88/137/23 92/143/23 93/144/23 +f 83/125/24 91/136/24 95/142/24 +f 90/140/25 89/139/25 93/145/25 94/146/25 +f 88/137/26 100/132/26 92/143/26 +f 95/142/27 94/141/27 98/147/27 99/148/27 +f 93/144/28 92/143/28 96/149/28 97/150/28 +f 83/125/29 95/142/29 99/148/29 +f 94/146/1 93/145/1 97/151/1 98/152/1 +f 92/143/30 100/132/30 96/149/30 +f 99/148/31 98/147/31 103/153/31 104/154/31 +f 97/150/32 96/149/32 101/155/32 102/156/32 +f 83/125/33 99/148/33 104/154/33 +f 98/157/34 97/158/34 102/159/34 103/160/34 +f 96/149/35 100/132/35 101/155/35 +f 104/154/36 103/153/36 107/161/36 108/162/36 +f 102/156/37 101/155/37 105/163/37 106/164/37 +f 83/125/38 104/154/38 108/162/38 +f 103/160/2 102/159/2 106/165/2 107/166/2 +f 101/155/39 100/132/39 105/163/39 +f 108/162/40 107/161/40 111/167/40 112/168/40 +f 106/164/41 105/163/41 109/169/41 110/170/41 +f 83/125/42 108/162/42 112/168/42 +f 107/166/43 106/165/43 110/171/43 111/172/43 +f 105/163/44 100/132/44 109/169/44 +f 112/168/45 111/167/45 82/173/45 114/174/45 +f 110/170/46 109/169/46 81/175/46 113/176/46 +f 83/125/47 112/168/47 114/174/47 +f 111/172/3 110/171/3 113/177/3 82/178/3 +f 109/169/48 100/132/48 81/175/48 diff --git a/mods/drinks/readme.md b/mods/drinks/readme.md new file mode 100644 index 0000000..d3b0c68 --- /dev/null +++ b/mods/drinks/readme.md @@ -0,0 +1,3 @@ +This mod aims to add more drinks to the world, and be easily expanded to support other mods that have fruits and veggies. + +There is optional support for the thirsty mod, if you have it installed drinking juices will fill your hydration. diff --git a/mods/drinks/screenshot.png b/mods/drinks/screenshot.png new file mode 100644 index 0000000..32633d3 Binary files /dev/null and b/mods/drinks/screenshot.png differ diff --git a/mods/drinks/textures/drinks_barrel.png b/mods/drinks/textures/drinks_barrel.png new file mode 100644 index 0000000..09b6412 Binary files /dev/null and b/mods/drinks/textures/drinks_barrel.png differ diff --git a/mods/drinks/textures/drinks_bottle_contents.png b/mods/drinks/textures/drinks_bottle_contents.png new file mode 100644 index 0000000..8456e9f Binary files /dev/null and b/mods/drinks/textures/drinks_bottle_contents.png differ diff --git a/mods/drinks/textures/drinks_bucket_contents.png b/mods/drinks/textures/drinks_bucket_contents.png new file mode 100644 index 0000000..badf594 Binary files /dev/null and b/mods/drinks/textures/drinks_bucket_contents.png differ diff --git a/mods/drinks/textures/drinks_drinking_glass.png b/mods/drinks/textures/drinks_drinking_glass.png new file mode 100644 index 0000000..8a722ad Binary files /dev/null and b/mods/drinks/textures/drinks_drinking_glass.png differ diff --git a/mods/drinks/textures/drinks_glass_bottle.png b/mods/drinks/textures/drinks_glass_bottle.png new file mode 100644 index 0000000..c4654d0 Binary files /dev/null and b/mods/drinks/textures/drinks_glass_bottle.png differ diff --git a/mods/drinks/textures/drinks_glass_contents.png b/mods/drinks/textures/drinks_glass_contents.png new file mode 100644 index 0000000..2490202 Binary files /dev/null and b/mods/drinks/textures/drinks_glass_contents.png differ diff --git a/mods/drinks/textures/drinks_press.png b/mods/drinks/textures/drinks_press.png new file mode 100644 index 0000000..4fe609b Binary files /dev/null and b/mods/drinks/textures/drinks_press.png differ diff --git a/mods/drinks/textures/drinks_silo.png b/mods/drinks/textures/drinks_silo.png new file mode 100644 index 0000000..c8513d3 Binary files /dev/null and b/mods/drinks/textures/drinks_silo.png differ diff --git a/mods/dungeon_loot/README.txt b/mods/dungeon_loot/README.txt new file mode 100644 index 0000000..c500d25 --- /dev/null +++ b/mods/dungeon_loot/README.txt @@ -0,0 +1,11 @@ +Minetest Game mod: dungeon_loot +=============================== +Adds randomly generated chests with some "loot" to generated dungeons, +an API to register additional loot is provided. +Only works if dungeons are actually enabled in mapgen flags. + +License information can be found in license.txt + +Authors of source code +---------------------- +Originally by sfan5 (MIT) diff --git a/mods/dungeon_loot/init.lua b/mods/dungeon_loot/init.lua new file mode 100644 index 0000000..9d8ac52 --- /dev/null +++ b/mods/dungeon_loot/init.lua @@ -0,0 +1,8 @@ +dungeon_loot = {} + +dungeon_loot.CHESTS_MIN = 0 -- not necessarily in a single dungeon +dungeon_loot.CHESTS_MAX = 2 +dungeon_loot.STACKS_PER_CHEST_MAX = 8 + +dofile(minetest.get_modpath("dungeon_loot") .. "/loot.lua") +dofile(minetest.get_modpath("dungeon_loot") .. "/mapgen.lua") diff --git a/mods/dungeon_loot/license.txt b/mods/dungeon_loot/license.txt new file mode 100644 index 0000000..0af30a0 --- /dev/null +++ b/mods/dungeon_loot/license.txt @@ -0,0 +1,24 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2017 sfan5 + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT diff --git a/mods/dungeon_loot/loot.lua b/mods/dungeon_loot/loot.lua new file mode 100644 index 0000000..347bfd5 --- /dev/null +++ b/mods/dungeon_loot/loot.lua @@ -0,0 +1,93 @@ +dungeon_loot.registered_loot = { + -- buckets + {name = "bucket:bucket_empty", chance = 0.55}, + -- water in deserts/ice or above ground, lava otherwise + {name = "bucket:bucket_water", chance = 0.45, + types = {"sandstone", "desert", "ice"}}, + {name = "bucket:bucket_water", chance = 0.45, y = {0, 32768}, + types = {"normal"}}, + {name = "bucket:bucket_lava", chance = 0.45, y = {-32768, -1}, + types = {"normal"}}, + + -- various items + {name = "default:stick", chance = 0.6, count = {3, 6}}, + {name = "default:flint", chance = 0.4, count = {1, 3}}, + {name = "vessels:glass_fragments", chance = 0.35, count = {1, 4}}, + {name = "carts:rail", chance = 0.35, count = {1, 6}}, + {name = "epic:arrow_tip", chance = .3, count = {1, 43}, y = {-512, -32}}, + {name = "commoditymarkget:gold_coins", chance = .1, count = {1, 800}, y = {-512, -256}}, + + -- farming / consumable + {name = "farming:string", chance = 0.5, count = {1, 8}}, + {name = "farming:wheat", chance = 0.5, count = {2, 5}}, + {name = "default:apple", chance = 0.4, count = {1, 4}}, + {name = "farming:seed_cotton", chance = 0.4, count = {1, 4}, + types = {"normal"}}, + {name = "default:cactus", chance = 0.4, count = {1, 4}, + types = {"sandstone", "desert"}}, + {name = "farming:coffee_beans", chance = 0.01, count = {1, 1}, y = {-32768, -512}}, + {name = "epic:healing_powder", chance = 0.03, count = {1, 3}, y = {-1024, -256}}, + + --scrolls + {name = "stations:scroll_teleport", chance = 0.02}, + {name = "stations:scroll_healing", chance = 0.02}, + {name = "stations:scroll_bloodstone_powder", chance = 0.3}, + {name = "stations:scroll_anti_fire", chance = 0.1}, + {name = "stations:scroll_wood_ash", chance = 0.5}, + {name = "stations:scroll_chitin", chance = 0.6}, + {name = "stations:scroll_sulfur_dust", chance = 0.6}, + {name = "stations:scroll_poison", chance = 0.2}, + + --illuminati + {name = "illuminati:core_off", chance = 0.1}, + {name = "illuminati:cone_off", chance = 0.1}, + + -- minerals + {name = "default:coal_lump", chance = 0.9, count = {1, 12}}, + {name = "default:gold_ingot", chance = 0.5}, + {name = "default:steel_ingot", chance = 0.4, count = {1, 6}}, + {name = "default:mese_crystal", chance = 0.1, count = {2, 3}}, + {name = "epic:titanium_lump", chance = 0.1, count = {1, 2}, y = {-32768, -24680}}, + {name = "epic:sulfur_lump", chance = .25, count = {4, 12}}, + + -- tools + {name = "default:sword_wood", chance = 0.6}, + {name = "default:pick_stone", chance = 0.3}, + {name = "default:axe_diamond", chance = 0.05}, + + -- natural materials + {name = "default:sand", chance = 0.8, count = {4, 32}, y = {-64, 32768}, + types = {"normal"}}, + {name = "default:desert_sand", chance = 0.8, count = {4, 32}, y = {-64, 32768}, + types = {"sandstone"}}, + {name = "default:desert_cobble", chance = 0.8, count = {4, 32}, + types = {"desert"}}, + {name = "default:snow", chance = 0.8, count = {8, 64}, y = {-64, 32768}, + types = {"ice"}}, + {name = "default:dirt", chance = 0.6, count = {2, 16}, y = {-64, 32768}, + types = {"normal", "sandstone", "desert"}}, + {name = "default:obsidian", chance = 0.25, count = {1, 3}, y = {-32768, -512}}, + {name = "default:mese", chance = 0.15, y = {-32768, -512}}, +} + +function dungeon_loot.register(t) + if t.name ~= nil then + t = {t} -- single entry + end + for _, loot in ipairs(t) do + table.insert(dungeon_loot.registered_loot, loot) + end +end + +function dungeon_loot._internal_get_loot(pos_y, dungeontype) + -- filter by y pos and type + local ret = {} + for _, l in ipairs(dungeon_loot.registered_loot) do + if l.y == nil or (pos_y >= l.y[1] and pos_y <= l.y[2]) then + if l.types == nil or table.indexof(l.types, dungeontype) ~= -1 then + table.insert(ret, l) + end + end + end + return ret +end diff --git a/mods/dungeon_loot/mapgen.lua b/mods/dungeon_loot/mapgen.lua new file mode 100644 index 0000000..624e9a8 --- /dev/null +++ b/mods/dungeon_loot/mapgen.lua @@ -0,0 +1,171 @@ +minetest.set_gen_notify({dungeon = true, temple = true}) + +local function noise3d_integer(noise, pos) + return math.abs(math.floor(noise:get_3d(pos) * 0x7fffffff)) +end + +local function random_sample(rand, list, count) + local ret = {} + for n = 1, count do + local idx = rand:next(1, #list) + table.insert(ret, list[idx]) + table.remove(list, idx) + end + return ret +end + +local function find_walls(cpos) + local is_wall = function(node) + return node.name ~= "air" and node.name ~= "ignore" + end + + local dirs = {{x=1, z=0}, {x=-1, z=0}, {x=0, z=1}, {x=0, z=-1}} + local get_node = minetest.get_node + + local ret = {} + local mindist = {x=0, z=0} + local min = function(a, b) return a ~= 0 and math.min(a, b) or b end + for _, dir in ipairs(dirs) do + for i = 1, 9 do -- 9 = max room size / 2 + local pos = vector.add(cpos, {x=dir.x*i, y=0, z=dir.z*i}) + + -- continue in that direction until we find a wall-like node + local node = get_node(pos) + if is_wall(node) then + local front_below = vector.subtract(pos, {x=dir.x, y=1, z=dir.z}) + local above = vector.add(pos, {x=0, y=1, z=0}) + + -- check that it: + --- is at least 2 nodes high (not a staircase) + --- has a floor + if is_wall(get_node(front_below)) and is_wall(get_node(above)) then + table.insert(ret, {pos = pos, facing = {x=-dir.x, y=0, z=-dir.z}}) + if dir.z == 0 then + mindist.x = min(mindist.x, i-1) + else + mindist.z = min(mindist.z, i-1) + end + end + -- abort even if it wasn't a wall cause something is in the way + break + end + end + end + + local biome = minetest.get_biome_data(cpos) + biome = biome and minetest.get_biome_name(biome.biome) or "" + local type = "normal" + if biome:find("desert") == 1 then + type = "desert" + elseif biome:find("sandstone_desert") == 1 then + type = "sandstone" + elseif biome:find("icesheet") == 1 then + type = "ice" + end + + return { + walls = ret, + size = {x=mindist.x*2, z=mindist.z*2}, + type = type, + } +end + +local function populate_chest(pos, rand, dungeontype) + --minetest.chat_send_all("chest placed at " .. minetest.pos_to_string(pos) .. " [" .. dungeontype .. "]") + --minetest.add_node(vector.add(pos, {x=0, y=1, z=0}), {name="default:torch", param2=1}) + + local item_list = dungeon_loot._internal_get_loot(pos.y, dungeontype) + -- take random (partial) sample of all possible items + local sample_n = math.min(#item_list, dungeon_loot.STACKS_PER_CHEST_MAX) + item_list = random_sample(rand, item_list, sample_n) + + -- apply chances / randomized amounts and collect resulting items + local items = {} + for _, loot in ipairs(item_list) do + if rand:next(0, 1000) / 1000 <= loot.chance then + local itemdef = minetest.registered_items[loot.name] + local amount = 1 + if loot.count ~= nil then + amount = rand:next(loot.count[1], loot.count[2]) + end + + if itemdef then + if itemdef.tool_capabilities then + for n = 1, amount do + local wear = rand:next(0.20 * 65535, 0.75 * 65535) -- 20% to 75% wear + table.insert(items, ItemStack({name = loot.name, wear = wear})) + end + elseif itemdef.stack_max == 1 then + -- not stackable, add separately + for n = 1, amount do + table.insert(items, loot.name) + end + else + table.insert(items, ItemStack({name = loot.name, count = amount})) + end + end + end + end + + -- place items at random places in chest + local inv = minetest.get_meta(pos):get_inventory() + local listsz = inv:get_size("main") + assert(listsz >= #items) + for _, item in ipairs(items) do + local index = rand:next(1, listsz) + if inv:get_stack("main", index):is_empty() then + inv:set_stack("main", index, item) + else + inv:add_item("main", item) -- space occupied, just put it anywhere + end + end +end + + +minetest.register_on_generated(function(minp, maxp, blockseed) + local gennotify = minetest.get_mapgen_object("gennotify") + local poslist = gennotify["dungeon"] or {} + for _, entry in ipairs(gennotify["temple"] or {}) do + table.insert(poslist, entry) + end + if #poslist == 0 then return end + + local noise = minetest.get_perlin(10115, 4, 0.5, 1) + local rand = PcgRandom(noise3d_integer(noise, poslist[1])) + + local candidates = {} + -- process at most 8 rooms to keep runtime of this predictable + local num_process = math.min(#poslist, 8) + for i = 1, num_process do + local room = find_walls(poslist[i]) + -- skip small rooms and everything that doesn't at least have 3 walls + if math.min(room.size.x, room.size.z) >= 4 and #room.walls >= 3 then + table.insert(candidates, room) + end + end + + local num_chests = rand:next(dungeon_loot.CHESTS_MIN, dungeon_loot.CHESTS_MAX) + num_chests = math.min(#candidates, num_chests) + local rooms = random_sample(rand, candidates, num_chests) + + for _, room in ipairs(rooms) do + -- choose place somewhere in front of any of the walls + local wall = room.walls[rand:next(1, #room.walls)] + local v, vi -- vector / axis that runs alongside the wall + if wall.facing.x ~= 0 then + v, vi = {x=0, y=0, z=1}, "z" + else + v, vi = {x=1, y=0, z=0}, "x" + end + local chestpos = vector.add(wall.pos, wall.facing) + local off = rand:next(-room.size[vi]/2 + 1, room.size[vi]/2 - 1) + chestpos = vector.add(chestpos, vector.multiply(v, off)) + + if minetest.get_node(chestpos).name == "air" then + -- make it face inwards to the room + local facedir = minetest.dir_to_facedir(vector.multiply(wall.facing, -1)) + minetest.add_node(chestpos, {name = "default:chest", param2 = facedir}) + populate_chest(chestpos, PcgRandom(noise3d_integer(noise, chestpos)), room.type) + end + end +end) diff --git a/mods/dungeon_loot/mod.conf b/mods/dungeon_loot/mod.conf new file mode 100644 index 0000000..79d8089 --- /dev/null +++ b/mods/dungeon_loot/mod.conf @@ -0,0 +1,3 @@ +name = dungeon_loot +description = Minetest Game mod: dungeon_loot +depends = default diff --git a/mods/dye/README.txt b/mods/dye/README.txt new file mode 100644 index 0000000..a2fbdd2 --- /dev/null +++ b/mods/dye/README.txt @@ -0,0 +1,13 @@ +Minetest Game mod: dye +====================== +See license.txt for license information. +See init.lua for documentation. + +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +Perttu Ahola (celeron55) (CC BY-SA 3.0) diff --git a/mods/dye/init.lua b/mods/dye/init.lua new file mode 100644 index 0000000..5dcdb14 --- /dev/null +++ b/mods/dye/init.lua @@ -0,0 +1,103 @@ +-- dye/init.lua + +dye = {} + +-- Make dye names and descriptions available globally + +dye.dyes = { + {'grey', 'Grey', '#808080'}, + {'dark_grey', 'Dark Grey', '#404040'}, + {'black', 'Black', '#1a1a1a'}, + {'violet', 'Violet', '#480680'}, + {'blue', 'Blue', '#00519d'}, + {'cyan', 'Cyan', '#00959d'}, + {'dark_green', 'Dark Green', '#004d00'}, + {'green', 'Green', '#008000'}, + {'yellow', 'Yellow', '#ffff00'}, + {'brown', 'Brown', '#40230f'}, + {'orange', 'Orange', '#ff5600'}, + {'red', 'Red', '#c91818'}, + {'magenta', 'Magenta', '#d80481'}, + {'pink', 'Pink', '#ff7dc8'}, + {'white', 'White', '#ffffff'}, +} + +-- Define items + +for _, row in ipairs(dye.dyes) do + local name = row[1] + local description = row[2] + local hex = row[3] + local groups = {dye = 1} + groups['color_' .. name] = 1 + + minetest.register_craftitem('dye:' .. name, { + inventory_image = '(dye.png^[multiply:'..hex..')^dye_mask.png', + description = description .. ' Dye', + groups = groups + }) + + minetest.register_craft({ + output = 'dye:' .. name .. ' 4', + recipe = { + {'group:flower,color_' .. name} + }, + }) +end + +-- Manually add coal -> black dye + +minetest.register_craft({ + output = 'dye:black 4', + recipe = { + {'group:coal'} + }, +}) + +-- Manually add blueberries->violet dye + +minetest.register_craft({ + output = 'dye:violet 2', + recipe = { + {'default:blueberries'} + }, +}) + +-- Mix recipes + +local dye_recipes = { + -- src1, src2, dst + -- RYB mixes + {'red', 'blue', 'violet'}, -- 'purple' + {'yellow', 'red', 'orange'}, + {'yellow', 'blue', 'green'}, + -- RYB complementary mixes + {'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 _, 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/dye/license.txt b/mods/dye/license.txt new file mode 100644 index 0000000..0e56673 --- /dev/null +++ b/mods/dye/license.txt @@ -0,0 +1,60 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) Nathan Salapat 2020 + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/dye/locale/dye.de.tr b/mods/dye/locale/dye.de.tr new file mode 100644 index 0000000..f73fb57 --- /dev/null +++ b/mods/dye/locale/dye.de.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Weißer Farbstoff +Grey Dye=Grauer Farbstoff +Dark Grey Dye=Dunkelgrauer Farbstoff +Black Dye=Schwarzer Farbstoff +Violet Dye=Violetter Farbstoff +Blue Dye=Blauer Farbstoff +Cyan Dye=Türkiser Farbstoff +Dark Green Dye=Dunkelgrüner Farbstoff +Green Dye=Grüner Farbstoff +Yellow Dye=Gelber Farbstoff +Brown Dye=Brauner Farbstoff +Orange Dye=Orange Farbstoff +Red Dye=Roter Farbstoff +Magenta Dye=Magenta Farbstoff +Pink Dye=Rosa Farbstoff diff --git a/mods/dye/locale/dye.es.tr b/mods/dye/locale/dye.es.tr new file mode 100644 index 0000000..bd04ef4 --- /dev/null +++ b/mods/dye/locale/dye.es.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Tinte blanco +Grey Dye=Tinte gris +Dark Grey Dye=Tinte gris oscuro +Black Dye=Tinte negro +Violet Dye=Tinte violeta +Blue Dye=Tinte azul +Cyan Dye=Tinte cián +Dark Green Dye=Tinte verde oscuro +Green Dye=Tinte verde +Yellow Dye=Tinte amarillo +Brown Dye=Tinte marrón +Orange Dye=Tinte naranja +Red Dye=Tinte rojo +Magenta Dye=Tinte magenta +Pink Dye=Tinte rosa diff --git a/mods/dye/locale/dye.fr.tr b/mods/dye/locale/dye.fr.tr new file mode 100644 index 0000000..390fa07 --- /dev/null +++ b/mods/dye/locale/dye.fr.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Colorant blanc +Grey Dye=Colorant gris +Dark Grey Dye=Colorant gris foncé +Black Dye=Colorant noir +Violet Dye=Colorant violet +Blue Dye=Colorant bleu +Cyan Dye=Colorant cyan +Dark Green Dye=Colorant vert foncé +Green Dye=Colorant vert +Yellow Dye=Colorant jaune +Brown Dye=Colorant marron +Orange Dye=Colorant orange +Red Dye=Colorant rouge +Magenta Dye=Colorant magenta +Pink Dye=Colorant rose diff --git a/mods/dye/locale/dye.it.tr b/mods/dye/locale/dye.it.tr new file mode 100644 index 0000000..e15e2b5 --- /dev/null +++ b/mods/dye/locale/dye.it.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Tintura bianca +Grey Dye=Tintura grigia +Dark Grey Dye=Tintura grigia scura +Black Dye=Tintura nera +Violet Dye=Tintura viola +Blue Dye=Tintura blu +Cyan Dye=Tintura ciano +Dark Green Dye=Tintura verde scura +Green Dye=Tintura verde +Yellow Dye=Tintura gialla +Brown Dye=Tintura marrone +Orange Dye=Tintura arancione +Red Dye=Tintura rossa +Magenta Dye=Tintura magenta +Pink Dye=Tintura rosa \ No newline at end of file diff --git a/mods/dye/locale/dye.ms.tr b/mods/dye/locale/dye.ms.tr new file mode 100644 index 0000000..50c0473 --- /dev/null +++ b/mods/dye/locale/dye.ms.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Pewarna Putih +Grey Dye=Pewarna Kelabu +Dark Grey Dye=Pewarna Kelabu Gelap +Black Dye=Pewarna Hitam +Violet Dye=Pewarna Ungu +Blue Dye=Pewarna Biru +Cyan Dye=Pewarna Biru Kehijauan +Dark Green Dye=Pewarna Hijau Gelap +Green Dye=Pewarna Hijau +Yellow Dye=Pewarna Kuning +Brown Dye=Pewarna Perang +Orange Dye=Pewarna Jingga +Red Dye=Pewarna Merah +Magenta Dye=Pewarna Merah Lembayung +Pink Dye=Pewarna Merah Jambu diff --git a/mods/dye/locale/dye.ru.tr b/mods/dye/locale/dye.ru.tr new file mode 100644 index 0000000..fa3c5c4 --- /dev/null +++ b/mods/dye/locale/dye.ru.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Ð‘ÐµÐ»Ð°Ñ ÐšÑ€Ð°Ñка +Grey Dye=Ð¡ÐµÑ€Ð°Ñ ÐšÑ€Ð°Ñка +Dark Grey Dye=Тёмно-Ð¡ÐµÑ€Ð°Ñ ÐšÑ€Ð°Ñка +Black Dye=Ð§ÐµÑ€Ð½Ð°Ñ ÐšÑ€Ð°Ñка +Violet Dye=Ð¤Ð¸Ð¾Ð»ÐµÑ‚Ð¾Ð²Ð°Ñ ÐšÑ€Ð°Ñка +Blue Dye=СинÑÑ ÐšÑ€Ð°Ñка +Cyan Dye=Ð“Ð¾Ð»ÑƒÐ±Ð°Ñ ÐšÑ€Ð°Ñка +Dark Green Dye=Тёмно-Ð—ÐµÐ»Ñ‘Ð½Ð°Ñ ÐšÑ€Ð°Ñка +Green Dye=Ð—ÐµÐ»Ñ‘Ð½Ð°Ñ ÐšÑ€Ð°Ñка +Yellow Dye=Ð–Ñ‘Ð»Ñ‚Ð°Ñ ÐšÑ€Ð°Ñка +Brown Dye=Ð‘ÑƒÑ€Ð°Ñ ÐšÑ€Ð°Ñка +Orange Dye=ÐžÑ€Ð°Ð½Ð¶ÐµÐ²Ð°Ñ ÐšÑ€Ð°Ñка +Red Dye=КраÑÐ½Ð°Ñ ÐšÑ€Ð°Ñка +Magenta Dye=ÐŸÑƒÑ€Ð¿ÑƒÑ€Ð½Ð°Ñ ÐšÑ€Ð°Ñка +Pink Dye=Ð Ð¾Ð·Ð¾Ð²Ð°Ñ ÐšÑ€Ð°Ñка diff --git a/mods/dye/locale/dye.se.tr b/mods/dye/locale/dye.se.tr new file mode 100644 index 0000000..27adb10 --- /dev/null +++ b/mods/dye/locale/dye.se.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=Vit Färg +Grey Dye=GrÃ¥ Färg +Dark Grey Dye=Mörk GrÃ¥ Färg +Black Dye=Svart Färg +Violet Dye=Violett Färg +Blue Dye=BlÃ¥ Färg +Cyan Dye=Cyan Färg +Dark Green Dye=Mörk Grön Färg +Green Dye=Grön Färg +Yellow Dye=Gul Färg +Brown Dye=Brun Färg +Orange Dye=Orange Färg +Red Dye=Röd Färg +Magenta Dye=Magenta Färg +Pink Dye=Rosa Färg \ No newline at end of file diff --git a/mods/dye/locale/dye.zh_CN.tr b/mods/dye/locale/dye.zh_CN.tr new file mode 100644 index 0000000..8dcf311 --- /dev/null +++ b/mods/dye/locale/dye.zh_CN.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=白染料 +Grey Dye=ç°æŸ“æ–™ +Dark Grey Dye=æš—ç°æŸ“æ–™ +Black Dye=黑染料 +Violet Dye=紫染料 +Blue Dye=è“染料 +Cyan Dye=é’染料 +Dark Green Dye=暗绿染料 +Green Dye=绿染料 +Yellow Dye=黄染料 +Brown Dye=棕染料 +Orange Dye=橙染料 +Red Dye=红染料 +Magenta Dye=å“红染料 +Pink Dye=粉红染料 diff --git a/mods/dye/locale/dye.zh_TW.tr b/mods/dye/locale/dye.zh_TW.tr new file mode 100644 index 0000000..cc60a21 --- /dev/null +++ b/mods/dye/locale/dye.zh_TW.tr @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye=白染料 +Grey Dye=ç°æŸ“æ–™ +Dark Grey Dye=æš—ç°æŸ“æ–™ +Black Dye=黑染料 +Violet Dye=紫染料 +Blue Dye=è—染料 +Cyan Dye=é’染料 +Dark Green Dye=暗綠染料 +Green Dye=綠染料 +Yellow Dye=黃染料 +Brown Dye=棕染料 +Orange Dye=橙染料 +Red Dye=紅染料 +Magenta Dye=å“紅染料 +Pink Dye=粉紅染料 diff --git a/mods/dye/locale/template.txt b/mods/dye/locale/template.txt new file mode 100644 index 0000000..c20bab5 --- /dev/null +++ b/mods/dye/locale/template.txt @@ -0,0 +1,16 @@ +# textdomain: dye +White Dye= +Grey Dye= +Dark Grey Dye= +Black Dye= +Violet Dye= +Blue Dye= +Cyan Dye= +Dark Green Dye= +Green Dye= +Yellow Dye= +Brown Dye= +Orange Dye= +Red Dye= +Magenta Dye= +Pink Dye= diff --git a/mods/dye/mod.conf b/mods/dye/mod.conf new file mode 100644 index 0000000..32bb816 --- /dev/null +++ b/mods/dye/mod.conf @@ -0,0 +1,2 @@ +name = dye +description = Minetest Game mod: dye diff --git a/mods/dye/textures/dye.png b/mods/dye/textures/dye.png new file mode 100644 index 0000000..718ea47 Binary files /dev/null and b/mods/dye/textures/dye.png differ diff --git a/mods/dye/textures/dye_mask.png b/mods/dye/textures/dye_mask.png new file mode 100644 index 0000000..9fc4b6c Binary files /dev/null and b/mods/dye/textures/dye_mask.png differ diff --git a/mods/earthbuild/README.md b/mods/earthbuild/README.md new file mode 100644 index 0000000..b6201b5 --- /dev/null +++ b/mods/earthbuild/README.md @@ -0,0 +1,85 @@ +# Earthbuild, by Dokimi + +Current version: 1.0.2 + +A mod for minetest that adds traditional dirt and vegetation based construction methods and technologies, which do not require the use of quarrying or mining. + + +# Instructions: +This mod aims to realistically capture these building techniques. Therefore it contains a mechanism which will degrade most earthen blocks to dirt if they are in contact with soil or water. This reflects the real world importance of keeping these materials dry. Make sure dirt based blocks (e.g. "Rammed Earth", "Cob" etc) are placed on foundations above the soil, or whitewashed. + +Each material has different pros and cons. Explore! + +Turf can only be aquired using the turf cutting tool on dirt with grass (to get the grass), or dirt with snow (it's a cold climate method). + +Compacted dirt can only be made using the dirt compactor. This is to simulate bare ground that has been cleared of vegetation but little else. + +# What are all these things? +- Cob: an ancient building material of straw and mud. +- Mud brick: cob shaped into bricks and dried. +- Rammed Earth: an ancient building technique of compressing earth into thick walls. +- Wattle and daub: woven sticks (the wattle), covered by daub (cob or something similar). +- Thatch: an ancient roofing method. Thick bundles of vegetation. +- Whitewash: a protective coating made from limestone. A little chemistry is used to turn it into a paint-like paste. +- Turf: soil held together by deep grass roots. Used to make thick insulating walls in places like Iceland. +- Drystack: Walls made from found stones (e.g. from clearing a field), stacked. Typically used for farm fences. +- Straw-bale walls: Bales of straw covered in cob (or similar). Historically used on farms with lots of excess straw. +- Bottle gourd: a pumpkin-like plant. The hollowed out fruits have long been used as storage vessels, bowls, etc. +- Fire sticks: the difficult task of rubbing two sticks together to start a fire via friction. + + + + +# License: + +Code is licensed under GNU GPLv3. + +Textures are licensed under CC BY-SA 3.0 Unported. + + +# Changelog: + +# 0.2 +- double amount of thatch made by recipe. +- Thatch grass recipes. +- Fixed supported whitewashed earth recipes. +- add clay pot. +- add primitive bed. +- stopped hearth from destroying blocks when another block is in the way. +- add mud brick +- remove flammability for wattle and daub +- changed rammed earth recipe to avoid conflict with moreblocks +- add wattle +- changed wattle and daub, and whitewashed wattle and daub to nodebox +- changed recipe for wattle and daub. +- remove wattle and daub wall register +- adjust groups +- add furnace +- adjust wattle recipe +- hearth breakable by hand +- wattle and thatch as fuels +- adjust whitewash recipe to need a lower ratio of gravel + +# 1.0 +- More realistic whitewash crafting (via quicklime) +- Add "Loose Wattle" +- Add "Stick Platform" and "Stick Platform with Brush" +- Add "Wattle Door" and "Wattle Trapdoor" +- Add Storage: basket, clay pot, and bottle gourd +- Add woven mat +- Improved Hearth (fuel use, and smoke effects) +- Add Drystack +- Add dirt compactor tool +- Add Turf construction (via turf cutting tool) +- Add Fire sticks +- Degradation mechanism for earthen blocks +- Numerous minor additions and adjustments + +# 1.0.1 +- Fix crashing bug with dirt compactor and turf cutter +- Add mod.conf file + +# 1.0.2 +- Nodeboxes and better meta handling for storage +- Remove conflicting papyrus weaving recipe +- dry dirt for rammed earth recipe diff --git a/mods/earthbuild/bed.lua b/mods/earthbuild/bed.lua new file mode 100644 index 0000000..7192746 --- /dev/null +++ b/mods/earthbuild/bed.lua @@ -0,0 +1,34 @@ +---------------------------------------------------------- +-- Bed + + +beds.register_bed("earthbuild:primitive_bed", { + description = "Primitive Bed", + inventory_image = "earthbuild_primitive_bed.png", + wield_image = "earthbuild_primitive_bed.png", + tiles = { + bottom = { + "earthbuild_thatch.png^[transformR90", + "default_wood.png", + "earthbuild_bed_side.png", + "earthbuild_bed_side.png^[transformfx", + "earthbuild_bed_side.png" + }, + top = { + "earthbuild_thatch.png^[transformR90", + "default_wood.png", + "earthbuild_bed_side.png", + "earthbuild_bed_side.png^[transformfx", + "earthbuild_bed_side.png", + } + }, + nodebox = { + bottom = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, + top = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, + }, + selectionbox = {-0.5, -0.5, -0.5, 0.5, 0.06, 1.5}, + recipe = { + {"earthbuild:thatch", "earthbuild:thatch", "earthbuild:thatch"}, + {"group:wood", "group:wood", "group:wood"}, + }, +}) diff --git a/mods/earthbuild/clay_pot.lua b/mods/earthbuild/clay_pot.lua new file mode 100644 index 0000000..5f1b031 --- /dev/null +++ b/mods/earthbuild/clay_pot.lua @@ -0,0 +1,246 @@ +---------------------------------------------------------- +-- Clay Pot (i.e. a clay bucket) + +------------------------------------------------- +--Functions + + +--protection function +local function check_protection(pos, name, text) + if minetest.is_protected(pos, name) then + minetest.log("action", (name ~= "" and name or "A mod") + .. " tried to " .. text + .. " at protected position " + .. minetest.pos_to_string(pos) + .. " with a bucket") + minetest.record_protection_violation(pos, name) + return true + end + return false +end + +-------------- +-- Can't just use the bucket api because that gives the player back the default steel bucket... +--otherwise this is just the same as from buckets +local earthbuild = {} +earthbuild.liquids = {} + +function register_liquid(source, flowing, itemname, inventory_image, name, + groups, force_renew) + + earthbuild.liquids[source] = { + source = source, + flowing = flowing, + itemname = itemname, + force_renew = force_renew, + } + earthbuild.liquids[flowing] = earthbuild.liquids[source] + + + if itemname ~= nil then + minetest.register_craftitem(itemname, { + description = name, + inventory_image = inventory_image, + stack_max = 1, + liquids_pointable = true, + groups = groups, + + on_place = function(itemstack, user, pointed_thing) + if minetest.check_player_privs(user.get_player_name(user), {spill=true}) then + -- Must be pointing to node + if pointed_thing.type ~= "node" then + return + end + + local node = minetest.get_node_or_nil(pointed_thing.under) + local ndef = node and minetest.registered_nodes[node.name] + + -- Call on_rightclick if the pointed node defines it + if ndef and ndef.on_rightclick and + user and not user:get_player_control().sneak then + return ndef.on_rightclick( + pointed_thing.under, + node, user, + itemstack) + end + + local lpos + + -- Check if pointing to a buildable node + if ndef and ndef.buildable_to then + -- buildable; replace the node + lpos = pointed_thing.under + else + -- not buildable to; place the liquid above + -- check if the node above can be replaced + + lpos = pointed_thing.above + node = minetest.get_node_or_nil(lpos) + local above_ndef = node and minetest.registered_nodes[node.name] + + if not above_ndef or not above_ndef.buildable_to then + -- do not remove the bucket with the liquid + return itemstack + end + end + + if check_protection(lpos, user + and user:get_player_name() + or "", "place "..source) then + return + end + + minetest.set_node(lpos, {name = source}) + minetest.log('action', user:get_player_name()..' placed '..source..' at '..minetest.pos_to_string(lpos)) + return ItemStack("earthbuild:clay_pot") + end + end + }) + end +end + + +---------------------------------------------------------- +--Register unfired pot +minetest.register_craftitem("earthbuild:unfired_clay_pot", { + description = "Unfired Clay Pot", + inventory_image = "earthbuild_unfired_clay_pot.png", + stack_max = 99, +}) + +--Register useable pot +minetest.register_craftitem("earthbuild:clay_pot", { + description = "Clay Pot", + inventory_image = "earthbuild_clay_pot.png", + stack_max = 99, + liquids_pointable = true, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "object" then + pointed_thing.ref:punch(user, 1.0, { full_punch_interval=1.0 }, nil) + return user:get_wielded_item() + elseif pointed_thing.type ~= "node" then + -- do nothing if it's neither object nor node + return + end + -- Check if pointing to a liquid source + local node = minetest.get_node(pointed_thing.under) + local liquiddef = earthbuild.liquids[node.name] + local item_count = user:get_wielded_item():get_count() + + if liquiddef ~= nil + and liquiddef.itemname ~= nil + and node.name == liquiddef.source then + if check_protection(pointed_thing.under, + user:get_player_name(), + "take ".. node.name) then + return + end + + -- default set to return filled bucket + local giving_back = liquiddef.itemname + + -- check if holding more than 1 empty bucket + if item_count > 1 then + + -- if space in inventory add filled bucked, otherwise drop as item + local inv = user:get_inventory() + if inv:room_for_item("main", {name=liquiddef.itemname}) then + inv:add_item("main", liquiddef.itemname) + else + local pos = user:getpos() + pos.y = math.floor(pos.y + 0.5) + minetest.add_item(pos, liquiddef.itemname) + end + + -- set to return empty buckets minus 1 + giving_back = "earthbuild:clay_pot "..tostring(item_count-1) + + end + + -- force_renew requires a source neighbour + local source_neighbor = false + if liquiddef.force_renew then + source_neighbor = + minetest.find_node_near(pointed_thing.under, 1, liquiddef.source) + end + if not (source_neighbor and liquiddef.force_renew) then + minetest.add_node(pointed_thing.under, {name = "air"}) + end + + return ItemStack(giving_back) + else + -- non-liquid nodes will have their on_punch triggered + local node_def = minetest.registered_nodes[node.name] + if node_def then + node_def.on_punch(pointed_thing.under, node, user, pointed_thing) + end + return user:get_wielded_item() + end + end, +}) + + +------------------------------------------------- +--Register the liquids the pot can be used for + +register_liquid( + "default:water_source", + "default:water_flowing", + "earthbuild:clay_pot_water", + "earthbuild_clay_pot_water.png", + "Water Clay Pot", + {water_bucket = 1} +) + +register_liquid( + "default:river_water_source", + "default:river_water_flowing", + "earthbuild:clay_pot_river_water", + "earthbuild_clay_pot_river_water.png", + "River Water Clay Pot", + {water_bucket = 1}, + true +) + +register_liquid( + "default:lava_source", + "default:lava_flowing", + "earthbuild:clay_pot_lava", + "earthbuild_clay_pot_lava.png", + "Clay Pot Lava" +) + +--Register lava as a fuel source +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:clay_pot_lava", + burntime = 60, + replacements = {{"earthbuild:clay_pot_lava", "earthbuild:clay_pot"}}, +}) + + +--------------------------------------- +--Recipes to make the pot + +--Craft unfired pot +minetest.register_craft({ + output = 'earthbuild:unfired_clay_pot 1', + recipe = { + {'default:clay_lump', '', 'default:clay_lump'}, + {'', 'default:clay_lump', ''}, + } +}) + +--Craft unfired pot back into clay +minetest.register_craft({ + output = 'default:clay_lump 3', + recipe = {{'earthbuild:unfired_clay_pot'}} +}) + +--Cook unfired pot to give the useable bucket +minetest.register_craft({ + type = "cooking", + output = "earthbuild:clay_pot", + recipe = "earthbuild:unfired_clay_pot", + cooktime = 3, +}) diff --git a/mods/earthbuild/depends.txt b/mods/earthbuild/depends.txt new file mode 100644 index 0000000..b5a9630 --- /dev/null +++ b/mods/earthbuild/depends.txt @@ -0,0 +1,6 @@ +default +stairs +walls +fire +beds +doors diff --git a/mods/earthbuild/description.txt b/mods/earthbuild/description.txt new file mode 100644 index 0000000..5667b82 --- /dev/null +++ b/mods/earthbuild/description.txt @@ -0,0 +1,7 @@ +Earthbuild + +by Dokimi + +Adds traditional dirt and vegetation based construction methods and technologies, which do not require the use of stone or mining. + +Aims to reflect building styles that have been in use since neolithic times, and are still common in areas with little stone or resources. \ No newline at end of file diff --git a/mods/earthbuild/doors.lua b/mods/earthbuild/doors.lua new file mode 100644 index 0000000..6cd6565 --- /dev/null +++ b/mods/earthbuild/doors.lua @@ -0,0 +1,54 @@ +---------------------------------------------------------- +-- Doors + +------------------------------------------------- + +--Wattle Door + +doors.register("door_wattle", { + tiles = {{ name = "earthbuild_door_wattle.png", backface_culling = true }}, + description = "Wattle Door", + inventory_image = "earthbuild_door_wattle_inv.png", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 1}, + recipe = { + {"earthbuild:wattle", "earthbuild:wattle"}, + {"earthbuild:wattle", "earthbuild:wattle"}, + {"earthbuild:wattle", "earthbuild:wattle"}, + } +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "doors:door_wattle", + burntime = 3, +}) + + + +--Wattle Trapdoor + +doors.register_trapdoor("earthbuild:trapdoor_wattle", { + description = "Wattle Trapdoor", + inventory_image = "earthbuild_trapdoor_wattle.png", + wield_image = "earthbuild_trapdoor_wattle.png", + tile_front = "earthbuild_trapdoor_wattle.png", + tile_side = "earthbuild_trapdoor_wattle_side.png", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 1, door = 1}, +}) + +minetest.register_craft({ + output = 'earthbuild:trapdoor_wattle 2', + recipe = { + {'earthbuild:wattle', 'earthbuild:wattle', ''}, + {'earthbuild:wattle', 'earthbuild:wattle', ''}, + {'', '', ''}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "trapdoor_wattle", + burntime = 3, +}) + diff --git a/mods/earthbuild/drystack.lua b/mods/earthbuild/drystack.lua new file mode 100644 index 0000000..0832e11 --- /dev/null +++ b/mods/earthbuild/drystack.lua @@ -0,0 +1,57 @@ +------------------------------------------------------------- +--DRYSTACK +-- construction from loose stones, boulders etc + + +--------------------------------- +--DRYSTACK WALLS +-- walls made from stacked stones +-- made from loose found stones + +minetest.register_node("earthbuild:drystack", { + description = "Drystack Wall", + tiles = {"earthbuild_drystack.png"}, + groups = {cracky = 3, stone = 2, oddly_breakable_by_hand = 1}, + sounds = default.node_sound_stone_defaults(), +}) + +--find good stones in the gravel +minetest.register_craft({ + output = 'earthbuild:drystack', + recipe = { + {'default:gravel', '', 'default:gravel'}, + } +}) + +--stack flints +minetest.register_craft({ + output = 'earthbuild:drystack', + recipe = { + {'default:flint', 'default:flint', 'default:flint'}, + {'default:flint', 'default:flint', 'default:flint'}, + {'default:flint', 'default:flint', 'default:flint'}, + } +}) + + +--recycle field wall +minetest.register_craft({ + output = 'earthbuild:drystack', + recipe = { + {'earthbuild:drystack_wall'}, + } +}) + + + +-- Stairs and slab for drystack +stairs.register_stair_and_slab("drystack", "earthbuild:drystack", + {cracky = 3, stone = 2, oddly_breakable_by_hand = 1}, + {"earthbuild_drystack.png"}, + "Drystack Stair", + "Drystack Slab", + default.node_sound_stone_defaults()) + +--Wall for drystack +walls.register("earthbuild:drystack_wall", "Drystack Field Wall", "earthbuild_drystack.png", + "earthbuild:drystack", default.node_sound_stone_defaults()) diff --git a/mods/earthbuild/earth.lua b/mods/earthbuild/earth.lua new file mode 100644 index 0000000..3b0d979 --- /dev/null +++ b/mods/earthbuild/earth.lua @@ -0,0 +1,299 @@ +---------------------------------------------------------- +-- Earthen Construction +-- blocks made from dirt +------------------------------------------------- + + + + + + + + +------------------------------- +--Compacted dirt +--i.e. a dirt floor +-- this is to simulate dirt floored buildings... +-- where the only preparation was clearing the vegetation +--created via dirt compactor tool + +minetest.register_node("earthbuild:compacted_dirt", { + description = "Compacted Dirt", + tiles = {"earthbuild_compacted_dirt.png"}, + groups = {crumbly = 2}, + drop = 'default:dirt', + sounds = default.node_sound_dirt_defaults(), +}) + + + + +----------------------------------------------------- +--TURF +-- the grass layer sliced off from the soil. +-- uses the grass roots for strength. +--grass still grows on top +--craft... only using grass layer, so need to harvest dirt_with_grass... +-- turf cutter to override default drop dirt. + + +--------- +--Turf +minetest.register_node('earthbuild:turf', { + description = 'Turf Wall', + drawtype = "normal", + tiles = { "default_grass.png", + "earthbuild_compacted_dirt.png", + "earthbuild_turf.png", + "earthbuild_turf.png", + "earthbuild_turf.png", + "earthbuild_turf.png"}, + paramtype = "light", + --drop = "default:dirt", + groups = {crumbly = 2, falling_node = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + + +-------------- +--Turf with drystack. +-- this is typically used at the bottom of walls. +-- would make both materials go further (1/2 each). +minetest.register_node('earthbuild:turf_and_drystack', { + description = 'Turf and Drystack Wall', + drawtype = "normal", + tiles = { "default_grass.png", + "earthbuild_compacted_dirt.png", + "earthbuild_turf_and_drystack.png", + "earthbuild_turf_and_drystack.png", + "earthbuild_turf_and_drystack.png", + "earthbuild_turf_and_drystack.png"}, + paramtype = "light", + groups = {cracky = 3, crumbly = 1, oddly_breakable_by_hand = 1, falling_node = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +--craft turf and drystack +minetest.register_craft({ + output = 'earthbuild:turf_and_drystack 2', + recipe = { + {'earthbuild:turf'}, + {'earthbuild:drystack'}, + } +}) + + +---------------------------------------------------------- +--EARTH, COB, and MUD BRICK NODES AND CRAFTS +--Note on digging strenghts: +-- Rammed earth is hard e.g. like default sandstone {crumbly = 1, cracky = 3} +-- cob is stronger than dirt {crumbly = 3}, but softer than rammed earth (i.e. 2) +-- all are easy with a pick axe {cracky = 3} + + +--Note on falling: +--all of these are massive lumps of mud... so need support. +--apparently domes, arches etc can be made with cob and mudbrick but are difficult. +-- limited this ability to mudbrick... to give some point to making it. + +--Note on merits of each block: +--all are stronger/more aesthetic than dirt. +--rammed earth: when have lots of/only dirt and want hard walls. +-- cob: a precursor to mudbricks, or for wattle and daub. Use when don't need supports. +-- mudbrick: more versatile than cob (no falling) + + + + +--------------------------- +--Rammed Earth + +minetest.register_node('earthbuild:rammed_earth', { + description = 'Rammed Earth', + drawtype = "normal", + tiles = { + "earthbuild_rammed_earth.png", + "earthbuild_rammed_earth_side.png", + "earthbuild_rammed_earth_side.png", + "earthbuild_rammed_earth_side.png", + "earthbuild_rammed_earth_side.png", + "earthbuild_rammed_earth_side.png" +}, + paramtype = "light", + --drop = "default:dirt", + groups = {crumbly = 1, cracky = 3, falling_node = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds rammed_earth recipes + +minetest.register_craft({ + output = 'earthbuild:rammed_earth 1', + recipe = { + {'default:dirt'}, + {'default:dirt'}, + {'default:dirt'}, + } +}) + +--only for rammed as cob is typically made with water +minetest.register_craft({ + output = 'earthbuild:rammed_earth 1', + recipe = { + {'default:dry_dirt'}, + {'default:dry_dirt'}, + {'default:dry_dirt'}, + } +}) + + +------------------------------------------ +--Cob + +minetest.register_node('earthbuild:cob', { + description = 'Cob', + drawtype = "normal", + tiles = {"earthbuild_cob.png"}, + paramtype = "light", + --drop = "default:dirt", + groups = {crumbly = 2, cracky = 3, falling_node = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds cob recipes + +minetest.register_craft({ + output = 'earthbuild:cob 2', + recipe = { + {'default:dirt', '', 'default:dirt'}, + {'', 'group:grass', ''}, + {'', '', ''}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:cob 2', + recipe = { + {'default:dirt', '', 'default:dirt'}, + {'', 'group:dry_grass', ''}, + {'', '', ''}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:cob 2', + recipe = { + {'default:dirt', '', 'default:dirt'}, + {'', 'default:junglegrass', ''}, + {'', '', ''}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:cob 2', + recipe = { + {'default:dirt', '', 'default:dirt'}, + {'', 'default:dry_shrub', ''}, + {'', '', ''}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:cob 2', + recipe = { + {'default:dirt', '', 'default:dirt'}, + {'', 'default:papyrus', ''}, + {'', '', ''}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:cob 2', + recipe = { + {'default:dirt', '', 'default:dirt'}, + {'', 'farming:wheat', ''}, + {'', '', ''}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:cob 2', + recipe = { + {'default:dirt', '', 'default:dirt'}, + {'', 'group:leaves', ''}, + {'', '', ''}, + } +}) + +-- craft the cob from mudbrick +-- (they are the same stuff, just arranged differently) +minetest.register_craft({ + output = 'earthbuild:cob', + recipe = {{'earthbuild:mud_brick'}} +}) + + +--------------------------------------------------------- +--MUD BRICK NODES AND CRAFTS + +minetest.register_node('earthbuild:mud_brick', { + description = 'Mud Brick', + drawtype = "normal", + tiles = {"earthbuild_mud_brick.png"}, + paramtype = "light", + groups = {crumbly = 2, cracky = 3}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- craft the mud brick from cob +-- (they are the same stuff, just arranged differently) +minetest.register_craft({ + output = 'earthbuild:mud_brick', + recipe = {{'earthbuild:cob'}} +}) + + + +---------------------------------------------------------- +--STAIRS AND SLABS NODES + +-- Stairs and slab for rammed earth +stairs.register_stair_and_slab("rammed_earth", "earthbuild:rammed_earth", + {crumbly = 1, cracky = 3, falling_node = 1}, + {"earthbuild_rammed_earth.png"}, + "Rammed Earth Stair", + "Rammed Earth Slab", + default.node_sound_dirt_defaults()) + + +-- Stairs and slab for cob +stairs.register_stair_and_slab("cob", "earthbuild:cob", + {crumbly = 2, cracky = 3, falling_node = 1}, + {"earthbuild_cob.png"}, + "Cob Stair", + "Cob Slab", + default.node_sound_dirt_defaults()) + + +-- Stairs and slab for mud brick +stairs.register_stair_and_slab("mud_brick", "earthbuild:mud_brick", + {crumbly = 2, cracky = 3}, + {"earthbuild_mud_brick.png"}, + "Mud Brick Stair", + "Mud Brick Slab", + default.node_sound_dirt_defaults()) + + +-- Stairs and slab for Turf +stairs.register_stair_and_slab("turf", "earthbuild:turf", + {crumbly = 2, falling_node = 1}, + { "default_grass.png", + "earthbuild_compacted_dirt.png", + "earthbuild_turf.png", + "earthbuild_turf.png", + "earthbuild_turf.png", + "earthbuild_turf.png"}, + "Turf Stair", + "Turf Slab", + default.node_sound_dirt_defaults()) diff --git a/mods/earthbuild/earthship.lua b/mods/earthbuild/earthship.lua new file mode 100644 index 0000000..972e9f6 --- /dev/null +++ b/mods/earthbuild/earthship.lua @@ -0,0 +1,43 @@ +---------------------------------------------------------- +-- Modern Eco-Construction +-- techniques more popular today/only possible with present technology +--(although some techniques are actually very old) +------------------------------------------------- + + + +------------------------------------------------- +--STRAW BALE +--made from straw bales (or equivalent), covered with some layer (e.g. clay, plaster etc) +--for our purposes... cob then whitewash will do +--common in farms where straw is abundant, but soil is valuable. + +minetest.register_node('earthbuild:strawbale', { + description = 'Straw-bale Wall', + drawtype = "normal", + tiles = {"earthbuild_wattle_and_daub.png"}, + paramtype = "light", + --drop = "default:dirt", + groups = {crumbly = 1, snappy = 2, falling_node = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +--make from thatch +minetest.register_craft({ + output = 'earthbuild:strawbale 6', + recipe = { + {'earthbuild:thatch', 'earthbuild:thatch', 'earthbuild:thatch'}, + {'earthbuild:thatch', 'earthbuild:thatch', 'earthbuild:thatch'}, + {'', 'earthbuild:cob', ''}, + } +}) + +--make from straw +minetest.register_craft({ + output = 'earthbuild:strawbale 6', + recipe = { + {'farming:straw', 'farming:straw', 'farming:straw'}, + {'farming:straw', 'farming:straw', 'farming:straw'}, + {'', 'earthbuild:cob', ''}, + } +}) diff --git a/mods/earthbuild/farming.lua b/mods/earthbuild/farming.lua new file mode 100644 index 0000000..858c0f3 --- /dev/null +++ b/mods/earthbuild/farming.lua @@ -0,0 +1,91 @@ +---------------------------------------------------------- +-- Bottle Gourd + +------------------------------------------------- + + +farming.register_plant("earthbuild:bottlegourd", { + description = "Bottle Gourd seed", + paramtype2 = "meshoptions", + inventory_image = "earthbuild_bottlegourd_seed.png", + steps = 7, + minlight = 13, + maxlight = default.LIGHT_MAX, + fertility = {"grassland", "rainforest"}, + groups = {flammable = 4}, + place_param2 = 3, +}) + + + + + +---------------------- +--Gourd Crafts + +--Vessel +minetest.register_node("earthbuild:bottlegourd_cup", { + description = "Bottlegourd Cup (empty)", + drawtype = "nodebox", + tiles = { "earthbuild_bottlegourd_cup_top.png", + "earthbuild_bottlegourd_bot.png", + "earthbuild_bottlegourd_cup.png", + "earthbuild_bottlegourd_cup.png", + "earthbuild_bottlegourd_cup.png", + "earthbuild_bottlegourd_cup.png", + "earthbuild_bottlegourd_cup.png", + "earthbuild_bottlegourd_cup.png", + }, + inventory_image = "earthbuild_bottlegourd_cup.png", + wield_image = "earthbuild_bottlegourd_cup.png", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.25, 0.25, -0.0, 0.25}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.25, 0.25, -0.0, 0.25}, + } + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_wood_defaults(), +}) + + +minetest.register_craft({ + output = 'earthbuild:bottlegourd_cup', + recipe = { + {'earthbuild:bottlegourd'}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:bottlegourd_cup", + burntime = 1, +}) + + + + + + + + + +------------ +--Collect wild seeds +--a tropical species so... + +minetest.override_item("default:junglegrass", {drop = { + max_items = 1, + items = { + {items = {'farming:seed_cotton'},rarity = 8}, + {items = {'earthbuild:seed_bottlegourd'},rarity = 8}, + {items = {'default:junglegrass'}}, + } +}}) diff --git a/mods/earthbuild/furnace.lua b/mods/earthbuild/furnace.lua new file mode 100644 index 0000000..3bb12e3 --- /dev/null +++ b/mods/earthbuild/furnace.lua @@ -0,0 +1,375 @@ +------------------------------------------------------------- +--FURNACE +--this is mostly just copied from default. +-- +-- +-- Formspecs +-- + +local function active_formspec(fuel_percent, item_percent) + local formspec = + "size[8,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "list[current_name;src;2.75,0.5;1,1;]".. + "list[current_name;fuel;2.75,2.5;1,1;]".. + "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. + (100-fuel_percent)..":default_furnace_fire_fg.png]".. + "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:".. + (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. + "list[current_name;dst;4.75,0.96;2,2;]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "listring[current_name;dst]".. + "listring[current_player;main]".. + "listring[current_name;src]".. + "listring[current_player;main]".. + "listring[current_name;fuel]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) + return formspec +end + +local inactive_formspec = + "size[8,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + "list[current_name;src;2.75,0.5;1,1;]".. + "list[current_name;fuel;2.75,2.5;1,1;]".. + "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. + "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]".. + "list[current_name;dst;4.75,0.96;2,2;]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "listring[current_name;dst]".. + "listring[current_player;main]".. + "listring[current_name;src]".. + "listring[current_player;main]".. + "listring[current_name;fuel]".. + "listring[current_player;main]".. + default.get_hotbar_bg(0, 4.25) + +-- +-- Node callback functions that are the same for active and inactive furnace +-- + +local function can_dig(pos, player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src") +end + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if listname == "fuel" then + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + if inv:is_empty("src") then + meta:set_string("infotext", "Furnace is empty") + end + return stack:get_count() + else + return 0 + end + elseif listname == "src" then + return stack:get_count() + elseif listname == "dst" then + return 0 + end +end + +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + if minetest.is_protected(pos, player:get_player_name()) then + return 0 + end + return stack:get_count() +end + +local function swap_node(pos, name) + local node = minetest.get_node(pos) + if node.name == name then + return + end + node.name = name + minetest.swap_node(pos, node) +end + +local function furnace_node_timer(pos, elapsed) + -- + -- Inizialize metadata + -- + local meta = minetest.get_meta(pos) + local fuel_time = meta:get_float("fuel_time") or 0 + local src_time = meta:get_float("src_time") or 0 + local fuel_totaltime = meta:get_float("fuel_totaltime") or 0 + + local inv = meta:get_inventory() + local srclist, fuellist + + local cookable, cooked + local fuel + + local update = true + while update do + update = false + + srclist = inv:get_list("src") + fuellist = inv:get_list("fuel") + + -- + -- Cooking + -- + + -- Check if we have cookable content + local aftercooked + cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cookable = cooked.time ~= 0 + + -- Check if we have enough fuel to burn + if fuel_time < fuel_totaltime then + -- The furnace is currently active and has enough fuel + fuel_time = fuel_time + elapsed + -- If there is a cookable item then check if it is ready yet + if cookable then + src_time = src_time + elapsed + if src_time >= cooked.time then + -- Place result in dst list if possible + if inv:room_for_item("dst", cooked.item) then + inv:add_item("dst", cooked.item) + inv:set_stack("src", 1, aftercooked.items[1]) + src_time = src_time - cooked.time + update = true + end + end + end + else + -- Furnace ran out of fuel + if cookable then + -- We need to get new fuel + 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 + fuel_totaltime = 0 + src_time = 0 + else + -- 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 + else + -- We don't need to get new fuel since there is no cookable item + fuel_totaltime = 0 + src_time = 0 + end + fuel_time = 0 + end + + 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 + -- + local formspec = inactive_formspec + local item_state + local item_percent = 0 + if cookable then + item_percent = math.floor(src_time / cooked.time * 100) + if item_percent > 100 then + item_state = "100% (output full)" + else + item_state = item_percent .. "%" + end + else + if srclist[1]:is_empty() then + item_state = "Empty" + else + item_state = "Not cookable" + end + end + + local fuel_state = "Empty" + local active = "inactive " + local result = false + + if fuel_totaltime ~= 0 then + active = "active " + local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100) + fuel_state = fuel_percent .. "%" + formspec = active_formspec(fuel_percent, item_percent) + swap_node(pos, "earthbuild:earthen_furnace_active") + -- make sure timer restarts automatically + result = true + else + if not fuellist[1]:is_empty() then + fuel_state = "0%" + end + swap_node(pos, "earthbuild:earthen_furnace") + -- stop timer on the inactive furnace + minetest.get_node_timer(pos):stop() + end + + local infotext = "Furnace " .. active .. "(Item: " .. item_state .. "; Fuel: " .. fuel_state .. ")" + + -- + -- Set meta values + -- + meta:set_float("fuel_totaltime", fuel_totaltime) + meta:set_float("fuel_time", fuel_time) + meta:set_float("src_time", src_time) + meta:set_string("formspec", formspec) + meta:set_string("infotext", infotext) + + return result +end + +-- +-- Node definitions +-- + +minetest.register_node("earthbuild:earthen_furnace", { + description = "Earthen Furnace", + tiles = { + "earthbuild_furnace_top.png", "earthbuild_furnace_side.png", + "earthbuild_furnace_side.png", "earthbuild_furnace_side.png", + "earthbuild_furnace_side.png", "earthbuild_furnace_front.png" + }, + paramtype2 = "facedir", + groups = {crumbly = 2, cracky = 3}, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + + can_dig = can_dig, + + on_timer = furnace_node_timer, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", inactive_formspec) + local inv = meta:get_inventory() + inv:set_size('src', 1) + inv:set_size('fuel', 1) + inv:set_size('dst', 4) + end, + + on_metadata_inventory_move = function(pos) + minetest.get_node_timer(pos):start(1.0) + end, + on_metadata_inventory_put = function(pos) + -- start timer function, it will sort out whether furnace can burn or not. + minetest.get_node_timer(pos):start(1.0) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "src", drops) + default.get_inventory_drops(pos, "fuel", drops) + default.get_inventory_drops(pos, "dst", drops) + drops[#drops+1] = "earthbuild:earthen_furnace" + minetest.remove_node(pos) + return drops + end, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, +}) + +minetest.register_node("earthbuild:earthen_furnace_active", { + description = "Earthen Furnace", + tiles = { + { + image = "earthbuild_furnace_top_active.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.5 + }, + }, + "earthbuild_furnace_side.png", + "earthbuild_furnace_side.png", "earthbuild_furnace_side.png", + "earthbuild_furnace_side.png", + { + image = "earthbuild_furnace_front_active.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.5 + }, + } + }, + paramtype2 = "facedir", + light_source = 8, + drop = "earthbuild:earthen_furnace", + groups = {crumbly = 2, cracky = 3, not_in_creative_inventory=1}, + legacy_facedir_simple = true, + is_ground_content = false, + sounds = default.node_sound_stone_defaults(), + on_timer = furnace_node_timer, + + can_dig = can_dig, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, +}) + + +---------------------------------------- +--CRAFT + +minetest.register_craft({ + output = 'earthbuild:earthen_furnace', + recipe = { + {'earthbuild:cob', 'earthbuild:cob', 'earthbuild:cob'}, + {'earthbuild:cob', '', 'earthbuild:cob'}, + {'earthbuild:cob', 'earthbuild:hearth', 'earthbuild:cob'}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:earthen_furnace', + recipe = { + {'earthbuild:rammed_earth', 'earthbuild:rammed_earth', 'earthbuild:rammed_earth'}, + {'earthbuild:rammed_earth', '', 'earthbuild:rammed_earth'}, + {'earthbuild:rammed_earth', 'earthbuild:hearth', 'earthbuild:rammed_earth'}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:earthen_furnace', + recipe = { + {'earthbuild:mud_brick', 'earthbuild:mud_brick', 'earthbuild:mud_brick'}, + {'earthbuild:mud_brick', '', 'earthbuild:mud_brick'}, + {'earthbuild:mud_brick', 'earthbuild:hearth', 'earthbuild:mud_brick'}, + } +}) diff --git a/mods/earthbuild/hearth.lua b/mods/earthbuild/hearth.lua new file mode 100644 index 0000000..20ba9b8 --- /dev/null +++ b/mods/earthbuild/hearth.lua @@ -0,0 +1,248 @@ +-------------------------------------------------- +--HEARTH + +------------------------------------------------ +--Functions + + + +---------- +-- On construct +-- set form +local hearth_on_construct = function(pos) + local inv = minetest.get_meta(pos):get_inventory() + inv:set_size("fuel", 1) + + local meta = minetest.get_meta(pos) + meta:set_string("formspec", + "size[8,5.3]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;fuel;3.5,0;1,1;]" .. + "list[current_player;main;0,1.15;8,1;]" .. + "list[current_player;main;0,2.38;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,1.15) + ) +end + + + +---------- +--Digging only if no fuel +local hearth_can_dig = function(pos, player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("fuel") +end + + +------------- +-- Only fuel items allowed +local hearth_allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if listname == "fuel" then + if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then + return stack:get_count() + else + return 0 + end + end + return 0 +end + + +-------------- +--Particle Effects + +local function hearth_fire_on(pos, time) + local meta = minetest.get_meta(pos) + --flames + minetest.add_particlespawner({ + amount = 4, + time = time, + minpos = {x = pos.x - 0.1, y = pos.y + 0.6, z = pos.z - 0.1}, + maxpos = {x = pos.x + 0.1, y = pos.y + 1, z = pos.z + 0.1}, + minvel = {x= 0, y= 0, z= 0}, + maxvel = {x= 0.001, y= 0.001, z= 0.001}, + minacc = {x= 0, y= 0, z= 0}, + maxacc = {x= 0.001, y= 0.001, z= 0.001}, + minexptime = 3, + maxexptime = 5, + minsize = 4, + maxsize = 8, + collisiondetection = false, + vertical = true, + texture = "fire_basic_flame_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1 + }, + glow = 13, + }) + + --Smoke + minetest.add_particlespawner({ + amount = 4, + time = time, + minpos = {x = pos.x - 0.1, y = pos.y + 0.8, z = pos.z - 0.1}, + maxpos = {x = pos.x + 0.1, y = pos.y + 1, z = pos.z + 0.1}, + minvel = {x= 0, y= 0, z= 0}, + maxvel = {x= 0.01, y= 0.07, z= 0.01}, + minacc = {x= 0, y= 0, z= 0}, + maxacc = {x= 0.01, y= 0.2, z= 0.01}, + minexptime = 5, + maxexptime = 20, + minsize = 1, + maxsize = 8, + collisiondetection = true, + vertical = true, + texture = "default_item_smoke.png", + --animation = {type="vertical_frames", aspect_w=16, aspect_h=16, length = 0.7,}, + }) +end + + + +---------- +--Burn +--add flames and burn fuel +local hearth_burn = function(pos, elapsed) + local pos_above = {x=pos.x, y=pos.y+1, z=pos.z} + local node_above = minetest.get_node(pos_above) + local timer = minetest.get_node_timer(pos) + + local inv = minetest.get_inventory({type="node", pos=pos}) + local item = inv:get_stack("fuel", 1) + local fuel_burned = minetest.get_craft_result({method="fuel", width=1, items={item:peek_item(1)}}).time + + --remove light... + -- so it doesn't stay on permanently + if inv:is_empty("fuel") and node_above.name == "earthbuild:hearth_air" then + minetest.set_node(pos_above, {name = "air"}) + end + + --burn item and add smoke and flames + if fuel_burned > 0 and (node_above.name == "air" or node_above.name == "earthbuild:hearth_air") then + --randomly remove an item of fuel based on it's burn time. + --this is so it can get through the fuel slowly, but.. + -- still do frequent flames + --i.e. every X sec it will have a 1/X chance of burning + local burn_time = fuel_burned * 30 + local burn_it = math.random(1, burn_time) + --it's luck was up, it got burnt away. + if burn_it == 1 then + item:set_count(item:get_count() - 1) + inv:set_stack("fuel", 1, item) + end + + --if has no light + if node_above.name == "air" then + minetest.set_node(pos_above, {name = "earthbuild:hearth_air"}) + end + + --do fire effects and restart timer + timer:start(5) + hearth_fire_on(pos, 5) + minetest.sound_play("fire_small",{pos=pos, max_hear_distance = 15, loop=false, gain=0.2}) + end +end + +--Removed node..make sure to remove light +local no_hearth = function(pos, oldnode) + local pos_above = {x=pos.x, y=pos.y+1, z=pos.z} + local node_above = minetest.get_node(pos_above) + + if node_above.name == "earthbuild:hearth_air" then + minetest.set_node(pos_above, {name = "air"}) + end +end + +------------------------------------------------- +--Node + +-- adds hearth + +minetest.register_node('earthbuild:hearth', { + description = 'Hearth', + drawtype = "normal", + tiles = { + "earthbuild_hearth_top.png", + "earthbuild_cob.png", + "earthbuild_hearth_side.png", + "earthbuild_hearth_side.png", + "earthbuild_hearth_side.png", + "earthbuild_hearth_side.png" +}, + paramtype = "light", + drop = "earthbuild:hearth", + groups = {crumbly = 1, cracky = 1, oddly_breakable_by_hand = 2}, + damage_per_second = 1, + sounds = default.node_sound_dirt_defaults(), + + on_construct = hearth_on_construct, + can_dig = hearth_can_dig, + allow_metadata_inventory_put = hearth_allow_metadata_inventory_put, + on_metadata_inventory_put = hearth_burn, + on_timer = hearth_burn, + after_destruct = no_hearth, + +}) + +----------------------------------------- +--Hearth Air +--this is to add a light source +-- an invisible glowing block added above the fire when burning +--this is needed because particles give no light +minetest.register_node("earthbuild:hearth_air", { + description = "Hearth Air", + tiles = {"earthbuild_hearth_top.png"}, + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + protected = true, + groups = {not_in_creative_inventory = 1}, + light_source= 9, + on_blast = function(pos) + end, +}) + + + +---------------------------------------------- +--Crafts + +-- adds hearth recipes + +minetest.register_craft({ + output = 'earthbuild:hearth', + recipe = { + {'', 'group:tree', ''}, + {'group:stick', 'group:stick', 'group:stick'}, + {'', 'earthbuild:rammed_earth', ''}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:hearth', + recipe = { + {'', 'group:tree', ''}, + {'group:stick', 'group:stick', 'group:stick'}, + {'', 'earthbuild:cob', ''}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:hearth', + recipe = { + {'', 'group:tree', ''}, + {'group:stick', 'group:stick', 'group:stick'}, + {'default:dirt', 'default:dirt', 'default:dirt'}, + } +}) diff --git a/mods/earthbuild/init.lua b/mods/earthbuild/init.lua new file mode 100644 index 0000000..f95c10f --- /dev/null +++ b/mods/earthbuild/init.lua @@ -0,0 +1,124 @@ +------------------------------------------------------------- +--Do files +------------------------------------------------------------- +dofile(minetest.get_modpath("earthbuild").."/earth.lua") +dofile(minetest.get_modpath("earthbuild").."/roofing.lua") +dofile(minetest.get_modpath("earthbuild").."/wattle.lua") +dofile(minetest.get_modpath("earthbuild").."/whitewash.lua") +dofile(minetest.get_modpath("earthbuild").."/drystack.lua") +dofile(minetest.get_modpath("earthbuild").."/earthship.lua") + +dofile(minetest.get_modpath("earthbuild").."/tools.lua") +dofile(minetest.get_modpath("earthbuild").."/clay_pot.lua") +dofile(minetest.get_modpath("earthbuild").."/bed.lua") +dofile(minetest.get_modpath("earthbuild").."/furnace.lua") +dofile(minetest.get_modpath("earthbuild").."/doors.lua") +dofile(minetest.get_modpath("earthbuild").."/storage.lua") +dofile(minetest.get_modpath("earthbuild").."/weaving.lua") +dofile(minetest.get_modpath("earthbuild").."/hearth.lua") +dofile(minetest.get_modpath("earthbuild").."/farming.lua") + + + +--------------------------------------------------------------- +--MISC STUFF + + +---------------------------- +-- DEGRADE +--Most of these construction need special care. +--they must be kept dry or they fall to bits. +--Therefore the degradation mechanism simulates how builders cope with that. +--Earthen blocks must be kept away from moisture/soil +-- simulates water, worms etc breaking it back up to dirt +--Therefore they must be kept off the ground/dry/whitewashed +-- A fairly slow process +--Some things are more durable than others... + + +--Fast. Things that are already dirt like, easily decomposed +minetest.register_abm({ + label = "Fast degrade Earthbuild", + nodenames = { + "earthbuild:compacted_dirt", + "earthbuild:strawbale", + "earthbuild:thatch", + "stairs:thatch", + "stairs:slab_thatch", + "earthbuild:turf", + "stairs:stair_turf", + "stairs:slab_turf", + }, + neighbors = { + "group:soil", + "group:water", + }, + interval = 180, + chance = 250, + catch_up = false, + action = function(pos, node) + --turn back to dirt + minetest.set_node(pos, {name = "default:dirt"}) + end +}) + +--Medium. Harder to degrade, but no special resistance. +minetest.register_abm({ + label = "Degrade Earthbuild", + nodenames = { + "earthbuild:cob", + "earthbuild:mud_brick", + "stairs:stair_cob", + "stairs:stair_mud_brick", + "stairs:slab_cob", + "stairs:slab_mud_brick", + }, + neighbors = { + "group:soil", + "group:water", + }, + interval = 360, + chance = 500, + catch_up = false, + action = function(pos, node) + --turn back to dirt + minetest.set_node(pos, {name = "default:dirt"}) + end +}) + +--Slow. Resistant, or partly protected +minetest.register_abm({ + label = "Slow Degrade Earthbuild", + nodenames = { + "earthbuild:rammed_earth", + "stairs:stair_rammed_earth", + "stairs:slab_rammed_earth", + "earthbuild:wattle_and_daub", + "earthbuild:supported_rammed_earth", + "earthbuild:junglewood_supported_rammed_earth", + "earthbuild:pine_wood_supported_rammed_earth", + "earthbuild:acacia_wood_supported_rammed_earth", + "earthbuild:aspen_wood_supported_rammed_earth", + "earthbuild:supported_cob", + "earthbuild:junglewood_supported_cob", + "earthbuild:pine_wood_supported_cob", + "earthbuild:acacia_wood_supported_cob", + "earthbuild:aspen_wood_supported_cob" + }, + neighbors = { + "group:soil", + "group:water", + }, + interval = 720, + chance = 1000, + catch_up = false, + action = function(pos, node) + if node.name == "earthbuild:wattle_and_daub" then + --daub falls off + minetest.set_node(pos, {name = "earthbuild:wattle"}) + else + --turn back to dirt + minetest.set_node(pos, {name = "default:dirt"}) + end + end +}) diff --git a/mods/earthbuild/license.txt b/mods/earthbuild/license.txt new file mode 100644 index 0000000..d3ebd7a --- /dev/null +++ b/mods/earthbuild/license.txt @@ -0,0 +1,655 @@ +License of source code +---------------------- +Copyright (C) 2019 Dokimi + +---------------------- + + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . diff --git a/mods/earthbuild/mod.conf b/mods/earthbuild/mod.conf new file mode 100644 index 0000000..0c6b4d5 --- /dev/null +++ b/mods/earthbuild/mod.conf @@ -0,0 +1,5 @@ +author = Dokimi +description = Adds traditional dirt and vegetation based construction methods and technologies, which do not require the use of stone or mining. Aims to reflect building styles that have been in use since neolithic times, and are still common in areas with little stone or resources. +release = 1.0.1 +title = Earthbuild +name = earthbuild diff --git a/mods/earthbuild/roofing.lua b/mods/earthbuild/roofing.lua new file mode 100644 index 0000000..56a9bc1 --- /dev/null +++ b/mods/earthbuild/roofing.lua @@ -0,0 +1,523 @@ +---------------------------------------------------------- +-- Roofing +-- Materials for making a roof, upper story floors, shelves etc +------------------------------------------------- + + +----------------------------------------------------------- +--EARTH AND COB WOOD SUPPORTED NODES AND CRAFTS + +--RAMMED EARTH +-------------------- +-- supported rammed_earth + +minetest.register_node('earthbuild:supported_rammed_earth', { + description = 'Supported Rammed Earth', + drawtype = "normal", + tiles = { + "earthbuild_rammed_earth.png", + "default_wood.png", + "earthbuild_supported_rammed_earth.png", + "earthbuild_supported_rammed_earth.png", + "earthbuild_supported_rammed_earth.png", + "earthbuild_supported_rammed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds supported rammed_earth recipe + +minetest.register_craft({ + output = 'earthbuild:supported_rammed_earth 3', + recipe = { + {'earthbuild:rammed_earth', 'earthbuild:rammed_earth', 'earthbuild:rammed_earth'}, + {'default:wood', '', ''}, + {'', '', ''}, + } +}) + +------------------------ +-- jungle wood supported rammed_earth + +minetest.register_node('earthbuild:junglewood_supported_rammed_earth', { + description = 'Jungle Wood Supported Rammed Earth', + drawtype = "normal", + tiles = { + "earthbuild_rammed_earth.png", + "default_junglewood.png", + "earthbuild_junglewood_supported_rammed_earth.png", + "earthbuild_junglewood_supported_rammed_earth.png", + "earthbuild_junglewood_supported_rammed_earth.png", + "earthbuild_junglewood_supported_rammed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds jungle wood supported rammed_earth recipe + +minetest.register_craft({ + output = 'earthbuild:junglewood_supported_rammed_earth 3', + recipe = { + {'earthbuild:rammed_earth', 'earthbuild:rammed_earth', 'earthbuild:rammed_earth'}, + {'default:junglewood', '', ''}, + {'', '', ''}, + } +}) + +--------------------------- +-- pine wood supported rammed_earth + +minetest.register_node('earthbuild:pine_wood_supported_rammed_earth', { + description = 'Pine Wood Supported Rammed Earth', + drawtype = "normal", + tiles = { + "earthbuild_rammed_earth.png", + "default_pine_wood.png", + "earthbuild_pine_wood_supported_rammed_earth.png", + "earthbuild_pine_wood_supported_rammed_earth.png", + "earthbuild_pine_wood_supported_rammed_earth.png", + "earthbuild_pine_wood_supported_rammed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds pine wood supported rammed_earth recipe + +minetest.register_craft({ + output = 'earthbuild:pine_wood_supported_rammed_earth 3', + recipe = { + {'earthbuild:rammed_earth', 'earthbuild:rammed_earth', 'earthbuild:rammed_earth'}, + {'default:pine_wood', '', ''}, + {'', '', ''}, + } +}) + +----------------------------- +-- acacia wood supported rammed_earth + +minetest.register_node('earthbuild:acacia_wood_supported_rammed_earth', { + description = 'Acacia Wood Supported Rammed Earth', + drawtype = "normal", + tiles = { + "earthbuild_rammed_earth.png", + "default_acacia_wood.png", + "earthbuild_acacia_wood_supported_rammed_earth.png", + "earthbuild_acacia_wood_supported_rammed_earth.png", + "earthbuild_acacia_wood_supported_rammed_earth.png", + "earthbuild_acacia_wood_supported_rammed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds acacia wood supported rammed_earth recipe + +minetest.register_craft({ + output = 'earthbuild:acacia_wood_supported_rammed_earth 3', + recipe = { + {'earthbuild:rammed_earth', 'earthbuild:rammed_earth', 'earthbuild:rammed_earth'}, + {'default:acacia_wood', '', ''}, + {'', '', ''}, + } +}) + +---------------------------- +-- aspen wood supported rammed_earth + +minetest.register_node('earthbuild:aspen_wood_supported_rammed_earth', { + description = 'Aspen Wood Supported Rammed Earth', + drawtype = "normal", + tiles = { + "earthbuild_rammed_earth.png", + "default_aspen_wood.png", + "earthbuild_aspen_wood_supported_rammed_earth.png", + "earthbuild_aspen_wood_supported_rammed_earth.png", + "earthbuild_aspen_wood_supported_rammed_earth.png", + "earthbuild_aspen_wood_supported_rammed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds aspen wood supported rammed_earth recipe + +minetest.register_craft({ + output = 'earthbuild:aspen_wood_supported_rammed_earth 3', + recipe = { + {'earthbuild:rammed_earth', 'earthbuild:rammed_earth', 'earthbuild:rammed_earth'}, + {'default:aspen_wood', '', ''}, + {'', '', ''}, + } +}) + +--COB +------------------------------- +-- supported cob + +minetest.register_node('earthbuild:supported_cob', { + description = 'Supported Cob', + drawtype = "normal", + tiles = { + "earthbuild_cob.png", + "default_wood.png", + "earthbuild_supported_cob.png", + "earthbuild_supported_cob.png", + "earthbuild_supported_cob.png", + "earthbuild_supported_cob.png" +}, + paramtype = "light", + groups = {crumbly = 2, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds supported cob recipe + +minetest.register_craft({ + output = 'earthbuild:supported_cob 3', + recipe = { + {'earthbuild:cob', 'earthbuild:cob', 'earthbuild:cob'}, + {'default:wood', '', ''}, + {'', '', ''}, + } +}) + +-------------------------------- +-- adds jungle wood supported cob + +minetest.register_node('earthbuild:junglewood_supported_cob', { + description = 'Jungle Wood Supported Cob', + drawtype = "normal", + tiles = { + "earthbuild_cob.png", + "default_junglewood.png", + "earthbuild_junglewood_supported_cob.png", + "earthbuild_junglewood_supported_cob.png", + "earthbuild_junglewood_supported_cob.png", + "earthbuild_junglewood_supported_cob.png" +}, + paramtype = "light", + groups = {crumbly = 2, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds jungle wood supported cob recipe + +minetest.register_craft({ + output = 'earthbuild:junglewood_supported_cob 3', + recipe = { + {'earthbuild:cob', 'earthbuild:cob', 'earthbuild:cob'}, + {'default:junglewood', '', ''}, + {'', '', ''}, + } +}) + +------------------------------------ +-- adds pine wood supported cob + +minetest.register_node('earthbuild:pine_wood_supported_cob', { + description = 'Pine Wood Supported Cob', + drawtype = "normal", + tiles = { + "earthbuild_cob.png", + "default_pine_wood.png", + "earthbuild_pine_wood_supported_cob.png", + "earthbuild_pine_wood_supported_cob.png", + "earthbuild_pine_wood_supported_cob.png", + "earthbuild_pine_wood_supported_cob.png" +}, + paramtype = "light", + groups = {crumbly = 2, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds pine wood supported cob recipe + +minetest.register_craft({ + output = 'earthbuild:pine_wood_supported_cob 3', + recipe = { + {'earthbuild:cob', 'earthbuild:cob', 'earthbuild:cob'}, + {'default:pine_wood', '', ''}, + {'', '', ''}, + } +}) + +--------------------------------- +-- acacia wood supported cob + +minetest.register_node('earthbuild:acacia_wood_supported_cob', { + description = 'Acacia Wood Supported Cob', + drawtype = "normal", + tiles = { + "earthbuild_cob.png", + "default_acacia_wood.png", + "earthbuild_acacia_wood_supported_cob.png", + "earthbuild_acacia_wood_supported_cob.png", + "earthbuild_acacia_wood_supported_cob.png", + "earthbuild_acacia_wood_supported_cob.png" +}, + paramtype = "light", + groups = {crumbly = 2, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds acacia wood supported cob recipe + +minetest.register_craft({ + output = 'earthbuild:acacia_wood_supported_cob 3', + recipe = { + {'earthbuild:cob', 'earthbuild:cob', 'earthbuild:cob'}, + {'default:acacia_wood', '', ''}, + {'', '', ''}, + } +}) + +---------------------------------- +-- aspen wood supported cob + +minetest.register_node('earthbuild:aspen_wood_supported_cob', { + description = 'Aspen Wood Supported Cob', + drawtype = "normal", + tiles = { + "earthbuild_cob.png", + "default_aspen_wood.png", + "earthbuild_aspen_wood_supported_cob.png", + "earthbuild_aspen_wood_supported_cob.png", + "earthbuild_aspen_wood_supported_cob.png", + "earthbuild_aspen_wood_supported_cob.png" +}, + paramtype = "light", + groups = {crumbly = 2, cracky = 3, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +--------------------------------- +-- aspen wood supported cob recipe + +minetest.register_craft({ + output = 'earthbuild:aspen_wood_supported_cob 3', + recipe = { + {'earthbuild:cob', 'earthbuild:cob', 'earthbuild:cob'}, + {'default:aspen_wood', '', ''}, + {'', '', ''}, + } +}) + + +----------------------------------------------------------- +--THATCH NODES AND CRAFTS + +-- adds thatch + +minetest.register_node('earthbuild:thatch', { + description = 'Thatch', + drawtype = "normal", + tiles = {"earthbuild_thatch.png"}, + paramtype = "light", + drop = "earthbuild:thatch", + groups = {snappy=3, flammable=1}, + sounds = default.node_sound_leaves_defaults(), +}) + +-- adds thatch recipes + +minetest.register_craft({ + output = 'earthbuild:thatch 6', + recipe = { + {'group:leaves', 'group:leaves', 'group:leaves'}, + {'group:leaves', 'group:leaves', 'group:leaves'}, + {'group:leaves', 'group:leaves', 'group:leaves'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:thatch 6', + recipe = { + {'group:grass', 'group:grass', 'group:grass'}, + {'group:grass', 'group:grass', 'group:grass'}, + {'group:grass', 'group:grass', 'group:grass'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:thatch 6', + recipe = { + {'group:dry_grass', 'group:dry_grass', 'group:dry_grass'}, + {'group:dry_grass', 'group:dry_grass', 'group:dry_grass'}, + {'group:dry_grass', 'group:dry_grass', 'group:dry_grass'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:thatch 6', + recipe = { + {'default:junglegrass', 'default:junglegrass', 'default:junglegrass'}, + {'default:junglegrass', 'default:junglegrass', 'default:junglegrass'}, + {'default:junglegrass', 'default:junglegrass', 'default:junglegrass'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:thatch 6', + recipe = { + {'default:papyrus', 'default:papyrus', 'default:papyrus'}, + {'default:papyrus', 'default:papyrus', 'default:papyrus'}, + {'default:papyrus', 'default:papyrus', 'default:papyrus'}, + } +}) + + + + +---------------------------------------------------------- +---------------------- +-- Stick platform + +minetest.register_node("earthbuild:stick_platform", { + description = "Stick Platform", + drawtype = "nodebox", + tiles = { "earthbuild_stick_platform_top.png", + "earthbuild_stick_platform_top.png", + "earthbuild_stick_platform_side.png", + "earthbuild_stick_platform_side.png", + "earthbuild_stick_platform_side.png", + "earthbuild_stick_platform_side.png"}, + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.375, -0.5, 0.5, 0.501, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, 0.375, -0.5, 0.5, 0.501, 0.5}, + }, + + }, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 1,}, + sounds = default.node_sound_wood_defaults(), +}) + + +--recipe for stick platform +minetest.register_craft({ + output = 'earthbuild:stick_platform 5', + recipe = { + {'group:stick', '', 'group:stick'}, + {'', 'group:stick', ''}, + {'group:stick', '', 'group:stick'}, + } +}) + +--recycle stick platform +minetest.register_craft({ + output = 'default:stick 5', + recipe = { + {'earthbuild:stick_platform'} + } +}) + + +---------------------- +-- Stick platform with brush +--(this mimics how a mud roof is typically made... +-- cob would go on top. More realistic than the wood supported ones) + +minetest.register_node("earthbuild:stick_platform_with_brush", { + description = "Stick Platform with Brush", + drawtype = "nodebox", + tiles = { "earthbuild_thatch.png", "earthbuild_stick_platform_with_brush.png", "earthbuild_stick_platform_with_brush_side.png", "earthbuild_stick_platform_with_brush_side.png", "earthbuild_stick_platform_with_brush_side.png", "earthbuild_stick_platform_with_brush_side.png"}, + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.25, -0.5, 0.5, 0.5, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, 0.25, -0.5, 0.5, 0.5, 0.5}, + }, + }, + + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 1,}, + sounds = default.node_sound_wood_defaults(), +}) + + +--recipe for stick platform with brush +minetest.register_craft({ + output = 'earthbuild:stick_platform_with_brush 6', + recipe = { + {'', 'earthbuild:thatch', ''}, + {'earthbuild:stick_platform', 'earthbuild:stick_platform', 'earthbuild:stick_platform'}, + {'earthbuild:stick_platform', 'earthbuild:stick_platform', 'earthbuild:stick_platform'}, + } +}) + +--recycle stick platform with brush +minetest.register_craft({ + output = 'earthbuild:stick_platform', + recipe = { + {'earthbuild:stick_platform_with_brush'} + } +}) + + + +---------------------------------------------------------- +--STAIRS AND SLABS NODES + + +-- Stairs and slab for thatch +stairs.register_stair_and_slab("thatch", "earthbuild:thatch", + {snappy=3, flammable=1}, + {"earthbuild_thatch.png"}, + "Thatch Stair", + "Thatch Slab", + default.node_sound_leaves_defaults()) + + +---------------------------------------------- +--Burnables + +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:thatch", + burntime = 9, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "stairs:stair_thatch", + burntime = 8, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "stairs:slab_thatch", + burntime = 3, +}) + + +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:stick_platform", + burntime = 1.5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:stick_platform_with_brush", + burntime = 3, +}) diff --git a/mods/earthbuild/screenshot.png b/mods/earthbuild/screenshot.png new file mode 100644 index 0000000..48697c8 Binary files /dev/null and b/mods/earthbuild/screenshot.png differ diff --git a/mods/earthbuild/sounds/dig_crumbly.ogg b/mods/earthbuild/sounds/dig_crumbly.ogg new file mode 100644 index 0000000..a0b2a1f Binary files /dev/null and b/mods/earthbuild/sounds/dig_crumbly.ogg differ diff --git a/mods/earthbuild/sounds/fire_small.ogg b/mods/earthbuild/sounds/fire_small.ogg new file mode 100644 index 0000000..5aac595 Binary files /dev/null and b/mods/earthbuild/sounds/fire_small.ogg differ diff --git a/mods/earthbuild/sounds/fire_sticks.ogg b/mods/earthbuild/sounds/fire_sticks.ogg new file mode 100644 index 0000000..d780123 Binary files /dev/null and b/mods/earthbuild/sounds/fire_sticks.ogg differ diff --git a/mods/earthbuild/sounds/placehold b/mods/earthbuild/sounds/placehold new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/mods/earthbuild/sounds/placehold @@ -0,0 +1 @@ + diff --git a/mods/earthbuild/storage.lua b/mods/earthbuild/storage.lua new file mode 100644 index 0000000..71cd65f --- /dev/null +++ b/mods/earthbuild/storage.lua @@ -0,0 +1,316 @@ +------------------------------------------------------------- +local function is_owner(pos, name) + local owner = minetest.get_meta(pos):get_string("owner") + if owner == "" or owner == name or minetest.check_player_privs(name, "protection_bypass") then + return true + end + return false +end + +--------------------------------------------------- +local function get_storage_formspec(pos) + local formspec ="size[8,7]" .. + default.gui_bg .. + default.gui_bg_img .. + default.gui_slots .. + "list[current_name;main;0,0.3;8,2]" .. + "list[current_player;main;0,2.85;8,1]" .. + "list[current_player;main;0,4.08;8,3;8]" .. + "listring[current_name;main]" .. + "listring[current_player;main]" + return formspec +end + + +------------------------------------------------------------- +--Storage Pot + +--Unfired pot (not usuable... must be cooked) + +minetest.register_craftitem("earthbuild:storage_pot_unfired", { + description = "Unfired Clay Storage Pot", + inventory_image = "earthbuild_storage_pot_unfired.png", + stack_max = 99, +}) + + + + +--Finished Pot +minetest.register_node("earthbuild:storage_pot", { + description = "Clay Storage Pot", + tiles = {"earthbuild_storage_pot_top.png", + "earthbuild_storage_pot_top.png", + "earthbuild_storage_pot.png", + "earthbuild_storage_pot.png", + "earthbuild_storage_pot.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.375, -0.5, -0.375, 0.375, -0.375, 0.375}, + {-0.375, 0.375, -0.375, 0.375, 0.5, 0.375}, + {-0.4375, -0.375, -0.4375, 0.4375, -0.25, 0.4375}, + {-0.4375, 0.25, -0.4375, 0.4375, 0.375, 0.4375}, + {-0.5, -0.25, -0.5, 0.5, 0.25, 0.5}, + } + }, + groups = {oddly_breakable_by_hand = 3}, + sounds = default.node_sound_stone_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_storage_formspec(pos, 8, 2)) + local inv = meta:get_inventory() + inv:set_size("main", 8*3) + meta:set_string("infotext", "Clay Storage Pot") + end, + + can_dig = function(pos, player) + local inv = minetest.get_meta(pos):get_inventory() + local name = "" + if player then + name = player:get_player_name() + end + return is_owner(pos, name) and inv:is_empty("main") + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if is_owner(pos, player:get_player_name()) then + return count + end + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) + and not string.match(stack:get_name(), "backpacks:") then + return stack:get_count() + end + return 0 + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) then + return stack:get_count() + end + return 0 + end, + + on_blast = function(pos) + end, +}) + + + +--Craft unfired pot + +minetest.register_craft({ + output = "earthbuild:storage_pot_unfired", + recipe = { + {"default:clay_lump", "default:clay_lump", "default:clay_lump"}, + {"default:clay_lump", "", "default:clay_lump"}, + {"default:clay_lump", "default:clay_lump", "default:clay_lump"}, + } +}) + + + +--Recycle unfired pot + +minetest.register_craft({ + output = "default:clay_lump 8", + recipe = { + {"earthbuild:storage_pot_unfired"}} +}) + + +--Cook unfired pot to give the useable pot +minetest.register_craft({ + type = "cooking", + output = "earthbuild:storage_pot", + recipe = "earthbuild:storage_pot_unfired", + cooktime = 10, +}) + + + +-------------------------------------------- +--Basket +minetest.register_node("earthbuild:basket", { + description = "Basket", + tiles = {"earthbuild_basket_top.png", + "earthbuild_basket_top.png", + "earthbuild_basket.png", + "earthbuild_basket.png", + "earthbuild_basket.png"}, + drawtype = "nodebox", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.25, 0.375, -0.25, 0.25, 0.5, 0.25}, + {-0.375, -0.25, -0.375, 0.375, 0.3125, 0.375}, + {-0.3125, -0.375, -0.3125, 0.3125, -0.25, 0.3125}, + {-0.25, -0.5, -0.25, 0.25, -0.375, 0.25}, + {-0.3125, 0.3125, -0.3125, 0.3125, 0.375, 0.3125}, + } + }, + + groups = {oddly_breakable_by_hand = 3}, + sounds = default.node_sound_leaves_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_storage_formspec(pos, 8, 2)) + local inv = meta:get_inventory() + inv:set_size("main", 8*2) + meta:set_string("infotext", "Basket") + end, + + can_dig = function(pos, player) + local inv = minetest.get_meta(pos):get_inventory() + local name = "" + if player then + name = player:get_player_name() + end + return is_owner(pos, name) and inv:is_empty("main") + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if is_owner(pos, player:get_player_name()) then + return count + end + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) + and not string.match(stack:get_name(), "backpacks:") then + return stack:get_count() + end + return 0 + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) then + return stack:get_count() + end + return 0 + end, + + on_blast = function(pos) + end, +}) + + +--Craft basket +minetest.register_craft({ + output = "earthbuild:basket", + recipe = { + {"earthbuild:woven_mat", "earthbuild:woven_mat", "earthbuild:woven_mat"}, + {"earthbuild:woven_mat", "", "earthbuild:woven_mat"}, + {"earthbuild:woven_mat", "earthbuild:woven_mat", "earthbuild:woven_mat"}, + } +}) + +--burn basket +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:basket", + burntime = 8, +}) + + + +----------------------------------------------------- +--Gourd Container + +--Vessel +minetest.register_node("earthbuild:bottlegourd_container", { + description = "Bottlegourd Container", + drawtype = "nodebox", + tiles = { "earthbuild_bottlegourd_container_top.png", + "earthbuild_bottlegourd_bot.png", + "earthbuild_bottlegourd_container.png", + "earthbuild_bottlegourd_container.png", + "earthbuild_bottlegourd_container.png", + "earthbuild_bottlegourd_container.png", + "earthbuild_bottlegourd_container.png", + "earthbuild_bottlegourd_container.png", + }, + inventory_image = "earthbuild_bottlegourd_container.png", + wield_image = "earthbuild_bottlegourd_container.png", + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.25, 0.25, -0.0, 0.25}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.25, -0.5, -0.25, 0.25, -0.0, 0.25}, + } + }, + groups = {dig_immediate = 3,}, + sounds = default.node_sound_wood_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", get_storage_formspec(pos, 8, 2)) + local inv = meta:get_inventory() + inv:set_size("main", 1*1) + meta:set_string("infotext", "Bottle Gourd") + end, + + can_dig = function(pos, player) + local inv = minetest.get_meta(pos):get_inventory() + local name = "" + if player then + name = player:get_player_name() + end + return is_owner(pos, name) and inv:is_empty("main") + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + if is_owner(pos, player:get_player_name()) then + return count + end + return 0 + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) + and not string.match(stack:get_name(), "backpacks:") then + return stack:get_count() + end + return 0 + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if is_owner(pos, player:get_player_name()) then + return stack:get_count() + end + return 0 + end, + + on_blast = function(pos) + end, +}) + + +minetest.register_craft({ + output = 'earthbuild:bottlegourd_container', + recipe = { + {'earthbuild:bottlegourd_cup', 'earthbuild:bottlegourd_cup'}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:bottlegourd_container", + burntime = 1, +}) diff --git a/mods/earthbuild/textures/earthbuild_acacia_wood_supported_cob.png b/mods/earthbuild/textures/earthbuild_acacia_wood_supported_cob.png new file mode 100644 index 0000000..72f9cc9 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_acacia_wood_supported_cob.png differ diff --git a/mods/earthbuild/textures/earthbuild_acacia_wood_supported_rammed_earth.png b/mods/earthbuild/textures/earthbuild_acacia_wood_supported_rammed_earth.png new file mode 100644 index 0000000..e3d45fb Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_acacia_wood_supported_rammed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_acacia_wood_supported_whitewashed_earth.png b/mods/earthbuild/textures/earthbuild_acacia_wood_supported_whitewashed_earth.png new file mode 100644 index 0000000..08f1ea6 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_acacia_wood_supported_whitewashed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_aspen_wood_supported_cob.png b/mods/earthbuild/textures/earthbuild_aspen_wood_supported_cob.png new file mode 100644 index 0000000..974384f Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_aspen_wood_supported_cob.png differ diff --git a/mods/earthbuild/textures/earthbuild_aspen_wood_supported_rammed_earth.png b/mods/earthbuild/textures/earthbuild_aspen_wood_supported_rammed_earth.png new file mode 100644 index 0000000..5edaa07 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_aspen_wood_supported_rammed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_aspen_wood_supported_whitewashed_earth.png b/mods/earthbuild/textures/earthbuild_aspen_wood_supported_whitewashed_earth.png new file mode 100644 index 0000000..0d15d6a Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_aspen_wood_supported_whitewashed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_basket.png b/mods/earthbuild/textures/earthbuild_basket.png new file mode 100644 index 0000000..04ea24a Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_basket.png differ diff --git a/mods/earthbuild/textures/earthbuild_basket_top.png b/mods/earthbuild/textures/earthbuild_basket_top.png new file mode 100644 index 0000000..c98eb52 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_basket_top.png differ diff --git a/mods/earthbuild/textures/earthbuild_bed_side.png b/mods/earthbuild/textures/earthbuild_bed_side.png new file mode 100644 index 0000000..1e718f3 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bed_side.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd.png b/mods/earthbuild/textures/earthbuild_bottlegourd.png new file mode 100644 index 0000000..dbd8d68 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_1.png b/mods/earthbuild/textures/earthbuild_bottlegourd_1.png new file mode 100644 index 0000000..a79d6f4 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_1.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_2.png b/mods/earthbuild/textures/earthbuild_bottlegourd_2.png new file mode 100644 index 0000000..a62f6ab Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_2.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_3.png b/mods/earthbuild/textures/earthbuild_bottlegourd_3.png new file mode 100644 index 0000000..859c212 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_3.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_4.png b/mods/earthbuild/textures/earthbuild_bottlegourd_4.png new file mode 100644 index 0000000..b5d6e0a Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_4.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_5.png b/mods/earthbuild/textures/earthbuild_bottlegourd_5.png new file mode 100644 index 0000000..31b0844 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_5.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_6.png b/mods/earthbuild/textures/earthbuild_bottlegourd_6.png new file mode 100644 index 0000000..1b1adf5 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_6.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_7.png b/mods/earthbuild/textures/earthbuild_bottlegourd_7.png new file mode 100644 index 0000000..7c81c6b Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_7.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_bot.png b/mods/earthbuild/textures/earthbuild_bottlegourd_bot.png new file mode 100644 index 0000000..4ba322a Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_bot.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_container.png b/mods/earthbuild/textures/earthbuild_bottlegourd_container.png new file mode 100644 index 0000000..1f260a9 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_container.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_container_top.png b/mods/earthbuild/textures/earthbuild_bottlegourd_container_top.png new file mode 100644 index 0000000..53afe38 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_container_top.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_cup.png b/mods/earthbuild/textures/earthbuild_bottlegourd_cup.png new file mode 100644 index 0000000..0919104 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_cup.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_cup_top.png b/mods/earthbuild/textures/earthbuild_bottlegourd_cup_top.png new file mode 100644 index 0000000..a1cb8b7 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_cup_top.png differ diff --git a/mods/earthbuild/textures/earthbuild_bottlegourd_seed.png b/mods/earthbuild/textures/earthbuild_bottlegourd_seed.png new file mode 100644 index 0000000..bd2202d Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_bottlegourd_seed.png differ diff --git a/mods/earthbuild/textures/earthbuild_clay_pot.png b/mods/earthbuild/textures/earthbuild_clay_pot.png new file mode 100644 index 0000000..0220c38 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_clay_pot.png differ diff --git a/mods/earthbuild/textures/earthbuild_clay_pot_lava.png b/mods/earthbuild/textures/earthbuild_clay_pot_lava.png new file mode 100644 index 0000000..1da9e5a Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_clay_pot_lava.png differ diff --git a/mods/earthbuild/textures/earthbuild_clay_pot_river_water.png b/mods/earthbuild/textures/earthbuild_clay_pot_river_water.png new file mode 100644 index 0000000..d9ef251 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_clay_pot_river_water.png differ diff --git a/mods/earthbuild/textures/earthbuild_clay_pot_water.png b/mods/earthbuild/textures/earthbuild_clay_pot_water.png new file mode 100644 index 0000000..9c13e3a Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_clay_pot_water.png differ diff --git a/mods/earthbuild/textures/earthbuild_cob.png b/mods/earthbuild/textures/earthbuild_cob.png new file mode 100644 index 0000000..ac0a8fd Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_cob.png differ diff --git a/mods/earthbuild/textures/earthbuild_compacted_dirt.png b/mods/earthbuild/textures/earthbuild_compacted_dirt.png new file mode 100644 index 0000000..e2b69ca Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_compacted_dirt.png differ diff --git a/mods/earthbuild/textures/earthbuild_dirt_compactor.png b/mods/earthbuild/textures/earthbuild_dirt_compactor.png new file mode 100644 index 0000000..63139a1 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_dirt_compactor.png differ diff --git a/mods/earthbuild/textures/earthbuild_door_wattle.png b/mods/earthbuild/textures/earthbuild_door_wattle.png new file mode 100644 index 0000000..43cb536 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_door_wattle.png differ diff --git a/mods/earthbuild/textures/earthbuild_door_wattle_inv.png b/mods/earthbuild/textures/earthbuild_door_wattle_inv.png new file mode 100644 index 0000000..5cfeade Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_door_wattle_inv.png differ diff --git a/mods/earthbuild/textures/earthbuild_drystack.png b/mods/earthbuild/textures/earthbuild_drystack.png new file mode 100644 index 0000000..7fe1953 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_drystack.png differ diff --git a/mods/earthbuild/textures/earthbuild_fire_sticks.png b/mods/earthbuild/textures/earthbuild_fire_sticks.png new file mode 100644 index 0000000..43d8de3 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_fire_sticks.png differ diff --git a/mods/earthbuild/textures/earthbuild_flintaxe.png b/mods/earthbuild/textures/earthbuild_flintaxe.png new file mode 100644 index 0000000..45b2bfb Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_flintaxe.png differ diff --git a/mods/earthbuild/textures/earthbuild_flintknife.png b/mods/earthbuild/textures/earthbuild_flintknife.png new file mode 100644 index 0000000..e5bd22c Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_flintknife.png differ diff --git a/mods/earthbuild/textures/earthbuild_furnace_front.png b/mods/earthbuild/textures/earthbuild_furnace_front.png new file mode 100644 index 0000000..55f7a39 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_furnace_front.png differ diff --git a/mods/earthbuild/textures/earthbuild_furnace_front_active.png b/mods/earthbuild/textures/earthbuild_furnace_front_active.png new file mode 100644 index 0000000..9f63fba Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_furnace_front_active.png differ diff --git a/mods/earthbuild/textures/earthbuild_furnace_side.png b/mods/earthbuild/textures/earthbuild_furnace_side.png new file mode 100644 index 0000000..07ade0d Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_furnace_side.png differ diff --git a/mods/earthbuild/textures/earthbuild_furnace_top.png b/mods/earthbuild/textures/earthbuild_furnace_top.png new file mode 100644 index 0000000..c843109 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_furnace_top.png differ diff --git a/mods/earthbuild/textures/earthbuild_furnace_top_active.png b/mods/earthbuild/textures/earthbuild_furnace_top_active.png new file mode 100644 index 0000000..9c68046 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_furnace_top_active.png differ diff --git a/mods/earthbuild/textures/earthbuild_hearth_side.png b/mods/earthbuild/textures/earthbuild_hearth_side.png new file mode 100644 index 0000000..89ff7d5 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_hearth_side.png differ diff --git a/mods/earthbuild/textures/earthbuild_hearth_top.png b/mods/earthbuild/textures/earthbuild_hearth_top.png new file mode 100644 index 0000000..df2ff5b Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_hearth_top.png differ diff --git a/mods/earthbuild/textures/earthbuild_junglewood_supported_cob.png b/mods/earthbuild/textures/earthbuild_junglewood_supported_cob.png new file mode 100644 index 0000000..5070ec8 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_junglewood_supported_cob.png differ diff --git a/mods/earthbuild/textures/earthbuild_junglewood_supported_rammed_earth.png b/mods/earthbuild/textures/earthbuild_junglewood_supported_rammed_earth.png new file mode 100644 index 0000000..106d453 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_junglewood_supported_rammed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_junglewood_supported_whitewashed_earth.png b/mods/earthbuild/textures/earthbuild_junglewood_supported_whitewashed_earth.png new file mode 100644 index 0000000..73ff838 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_junglewood_supported_whitewashed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_mud_brick.png b/mods/earthbuild/textures/earthbuild_mud_brick.png new file mode 100644 index 0000000..db63409 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_mud_brick.png differ diff --git a/mods/earthbuild/textures/earthbuild_pine_wood_supported_cob.png b/mods/earthbuild/textures/earthbuild_pine_wood_supported_cob.png new file mode 100644 index 0000000..e4d2dd7 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_pine_wood_supported_cob.png differ diff --git a/mods/earthbuild/textures/earthbuild_pine_wood_supported_rammed_earth.png b/mods/earthbuild/textures/earthbuild_pine_wood_supported_rammed_earth.png new file mode 100644 index 0000000..b9e75e5 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_pine_wood_supported_rammed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_pine_wood_supported_whitewashed_earth.png b/mods/earthbuild/textures/earthbuild_pine_wood_supported_whitewashed_earth.png new file mode 100644 index 0000000..1f5bc50 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_pine_wood_supported_whitewashed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_primitive_bed.png b/mods/earthbuild/textures/earthbuild_primitive_bed.png new file mode 100644 index 0000000..74d314b Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_primitive_bed.png differ diff --git a/mods/earthbuild/textures/earthbuild_quicklime.png b/mods/earthbuild/textures/earthbuild_quicklime.png new file mode 100644 index 0000000..a95128b Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_quicklime.png differ diff --git a/mods/earthbuild/textures/earthbuild_rammed_earth.png b/mods/earthbuild/textures/earthbuild_rammed_earth.png new file mode 100644 index 0000000..a753d5f Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_rammed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_rammed_earth_side.png b/mods/earthbuild/textures/earthbuild_rammed_earth_side.png new file mode 100644 index 0000000..6203aa4 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_rammed_earth_side.png differ diff --git a/mods/earthbuild/textures/earthbuild_stick_platform_side.png b/mods/earthbuild/textures/earthbuild_stick_platform_side.png new file mode 100644 index 0000000..3c5f94b Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_stick_platform_side.png differ diff --git a/mods/earthbuild/textures/earthbuild_stick_platform_top.png b/mods/earthbuild/textures/earthbuild_stick_platform_top.png new file mode 100644 index 0000000..35d5ce3 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_stick_platform_top.png differ diff --git a/mods/earthbuild/textures/earthbuild_stick_platform_with_brush.png b/mods/earthbuild/textures/earthbuild_stick_platform_with_brush.png new file mode 100644 index 0000000..caa2b2b Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_stick_platform_with_brush.png differ diff --git a/mods/earthbuild/textures/earthbuild_stick_platform_with_brush_side.png b/mods/earthbuild/textures/earthbuild_stick_platform_with_brush_side.png new file mode 100644 index 0000000..8a5e511 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_stick_platform_with_brush_side.png differ diff --git a/mods/earthbuild/textures/earthbuild_storage_pot.png b/mods/earthbuild/textures/earthbuild_storage_pot.png new file mode 100644 index 0000000..b8479c8 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_storage_pot.png differ diff --git a/mods/earthbuild/textures/earthbuild_storage_pot_top.png b/mods/earthbuild/textures/earthbuild_storage_pot_top.png new file mode 100644 index 0000000..18d225c Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_storage_pot_top.png differ diff --git a/mods/earthbuild/textures/earthbuild_storage_pot_unfired.png b/mods/earthbuild/textures/earthbuild_storage_pot_unfired.png new file mode 100644 index 0000000..d9e3bc0 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_storage_pot_unfired.png differ diff --git a/mods/earthbuild/textures/earthbuild_supported_cob.png b/mods/earthbuild/textures/earthbuild_supported_cob.png new file mode 100644 index 0000000..53af6d2 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_supported_cob.png differ diff --git a/mods/earthbuild/textures/earthbuild_supported_rammed_earth.png b/mods/earthbuild/textures/earthbuild_supported_rammed_earth.png new file mode 100644 index 0000000..c1e9372 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_supported_rammed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_supported_whitewashed_earth.png b/mods/earthbuild/textures/earthbuild_supported_whitewashed_earth.png new file mode 100644 index 0000000..58bac8d Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_supported_whitewashed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_thatch.png b/mods/earthbuild/textures/earthbuild_thatch.png new file mode 100644 index 0000000..f2f7e94 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_thatch.png differ diff --git a/mods/earthbuild/textures/earthbuild_trapdoor_wattle.png b/mods/earthbuild/textures/earthbuild_trapdoor_wattle.png new file mode 100644 index 0000000..6fd3f28 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_trapdoor_wattle.png differ diff --git a/mods/earthbuild/textures/earthbuild_trapdoor_wattle_side.png b/mods/earthbuild/textures/earthbuild_trapdoor_wattle_side.png new file mode 100644 index 0000000..f6799ca Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_trapdoor_wattle_side.png differ diff --git a/mods/earthbuild/textures/earthbuild_turf.png b/mods/earthbuild/textures/earthbuild_turf.png new file mode 100644 index 0000000..936a542 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_turf.png differ diff --git a/mods/earthbuild/textures/earthbuild_turf_and_drystack.png b/mods/earthbuild/textures/earthbuild_turf_and_drystack.png new file mode 100644 index 0000000..8aaae49 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_turf_and_drystack.png differ diff --git a/mods/earthbuild/textures/earthbuild_turf_cutter.png b/mods/earthbuild/textures/earthbuild_turf_cutter.png new file mode 100644 index 0000000..c173086 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_turf_cutter.png differ diff --git a/mods/earthbuild/textures/earthbuild_unfired_clay_pot.png b/mods/earthbuild/textures/earthbuild_unfired_clay_pot.png new file mode 100644 index 0000000..49b06b7 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_unfired_clay_pot.png differ diff --git a/mods/earthbuild/textures/earthbuild_wattle.png b/mods/earthbuild/textures/earthbuild_wattle.png new file mode 100644 index 0000000..ffeb627 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_wattle.png differ diff --git a/mods/earthbuild/textures/earthbuild_wattle_and_daub.png b/mods/earthbuild/textures/earthbuild_wattle_and_daub.png new file mode 100644 index 0000000..4eb1c65 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_wattle_and_daub.png differ diff --git a/mods/earthbuild/textures/earthbuild_wattle_loose.png b/mods/earthbuild/textures/earthbuild_wattle_loose.png new file mode 100644 index 0000000..583bb4f Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_wattle_loose.png differ diff --git a/mods/earthbuild/textures/earthbuild_wattle_top.png b/mods/earthbuild/textures/earthbuild_wattle_top.png new file mode 100644 index 0000000..3cee469 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_wattle_top.png differ diff --git a/mods/earthbuild/textures/earthbuild_whitewash.png b/mods/earthbuild/textures/earthbuild_whitewash.png new file mode 100644 index 0000000..e6b1094 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_whitewash.png differ diff --git a/mods/earthbuild/textures/earthbuild_whitewashed_earth.png b/mods/earthbuild/textures/earthbuild_whitewashed_earth.png new file mode 100644 index 0000000..080853e Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_whitewashed_earth.png differ diff --git a/mods/earthbuild/textures/earthbuild_woven_mat.png b/mods/earthbuild/textures/earthbuild_woven_mat.png new file mode 100644 index 0000000..c98eb52 Binary files /dev/null and b/mods/earthbuild/textures/earthbuild_woven_mat.png differ diff --git a/mods/earthbuild/tools.lua b/mods/earthbuild/tools.lua new file mode 100644 index 0000000..acdb93c --- /dev/null +++ b/mods/earthbuild/tools.lua @@ -0,0 +1,274 @@ +-------------------------------------------------- +--TOOLS + +---------------------------------------------------- +--FLINT TOOLS + +--Flint axe +-- sharper than stone axe but less durable +-- sharpeness is half way between stone and steel + +minetest.register_tool("earthbuild:flint_axe", { + description = "Flint Axe", + inventory_image = "earthbuild_flintaxe.png", + tool_capabilities = { + full_punch_interval = 1.2, + max_drop_level=0, + groupcaps={ + choppy={times={[1]=2.75, [2]=1.70, [3]=1.15}, uses=15, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = "default_tool_breaks"}, +}) + +--Craft flint axe +minetest.register_craft({ + output = 'earthbuild:flint_axe', + recipe = { + {'default:flint', 'group:stick'}, + {'', 'group:stick'}, + } +}) + + + +--Flint knife +-- sharper than stone but less durable +-- sharpeness is half way between stone and steel + +minetest.register_tool("earthbuild:flint_knife", { + description = "Flint knife", + inventory_image = "earthbuild_flintknife.png", + tool_capabilities = { + full_punch_interval = 1.2, + max_drop_level=0, + groupcaps={ + snappy={times={[1]=2.75, [2]=1.3, [3]=0.38}, uses=15, maxlevel=2}, + }, + damage_groups = {fleshy=5}, + }, + sound = {breaks = "default_tool_breaks"}, +}) + + +--Craft flint knife + +minetest.register_craft({ + output = 'earthbuild:flint_knife', + recipe = { + {'default:flint'}, + {'group:stick'}, + } +}) + + +------------------------------------------------- +--CONSTRUCTION Tools + +----------------- +--Dirt compactor +--a tool for compacting dirt floors. +-- the only way to get compacted dirt. +local ram = function(itemstack, user, pointed_thing) + + local player_name = user:get_player_name() + + --quit if not valid + if pointed_thing.type ~= "node" then + return + end + + local pos = pointed_thing.under + local node = minetest.get_node(pos) + + if minetest.get_item_group(node.name, "soil") == 1 then + minetest.sound_play("dig_crumbly",{pos=pos, max_hear_distance = 5, loop=false, gain=0.5}) + + minetest.set_node(pos, {name="earthbuild:compacted_dirt"}) + + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(player_name)) then + -- Wear tool + local wdef = itemstack:get_definition() + itemstack:add_wear(700) + -- Tool break sound + if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then + minetest.sound_play(wdef.sound.breaks, {pos = sound_pos, gain = 0.5}) + end + return itemstack + end + end +end + + +--Dirt Compactor +minetest.register_tool("earthbuild:dirt_compactor", { + description = "Dirt Compactor", + inventory_image = "earthbuild_dirt_compactor.png", + groups = {flammable = 2}, + sound = {breaks = "default_tool_breaks"}, + on_use = ram +}) + +--Craft dirt compactor +minetest.register_craft({ + output = 'earthbuild:dirt_compactor', + recipe = { + {'group:stick','default:shovel_wood','group:stick'}, + } +}) + + +-------------------- +--Turf cutter +--a modified shovel so can dig turf from dirt_with_grass, +--leaves behind dirt, with a chance of destroying the dirt +local turf_cut = function(itemstack, user, pointed_thing) + + local player_name = user:get_player_name() + + --quit if not valid + if pointed_thing.type ~= "node" then + return + end + + local pos = pointed_thing.under + local node = minetest.get_node(pos) + + --use healthy grass, or snowy ground... (it is a cold climate technique) + if node.name == "default:dirt_with_grass" or node.name == "default:dirt_with_snow" then + --take turf + minetest.sound_play("dig_crumbly",{pos=pos, max_hear_distance = 5, loop=false, gain=0.5}) + local inv = user:get_inventory() + inv:add_item("main", "earthbuild:turf") + + --chance of depleting dirt + local chance = math.random(1,2) + if chance == 1 then + minetest.set_node(pos, {name="air"}) + --minetest.dig_node(pos) + else + minetest.set_node(pos, {name="default:dirt"}) + end + + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(player_name)) then + -- Wear tool + local wdef = itemstack:get_definition() + itemstack:add_wear(700) + -- Tool break sound + if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then + minetest.sound_play(wdef.sound.breaks, {pos = sound_pos, gain = 0.5}) + end + return itemstack + end + end +end + + + + +--turf cutter +minetest.register_tool("earthbuild:turf_cutter", { + description = "Turf Cutter", + inventory_image = "earthbuild_turf_cutter.png", + groups = {flammable = 2}, + sound = {breaks = "default_tool_breaks"}, + on_use = turf_cut +}) + +--Craft Turf cutter +--modified shovel +minetest.register_craft({ + output = 'earthbuild:turf_cutter', + recipe = { + {'group:stick','default:shovel_wood',''}, + } +}) + + + +------------------------------------------------------- +-- Fire Sticks + +minetest.register_tool("earthbuild:fire_sticks", { + description = "Fire Sticks", + inventory_image = "earthbuild_fire_sticks.png", + sound = {breaks = "default_tool_breaks"}, + + on_use = function(itemstack, user, pointed_thing) + local sound_pos = pointed_thing.above or user:get_pos() + minetest.sound_play( + "fire_sticks", + {pos = sound_pos, gain = 0.5, max_hear_distance = 8} + ) + local player_name = user:get_player_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 + 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(pointed_thing.under, user) + elseif minetest.get_item_group(node_under, "flammable") >= 1 + and minetest.get_node(pointed_thing.above).name == "air" then + minetest.set_node(pointed_thing.above, {name = "fire:basic_flame"}) + end + end + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(player_name)) then + -- Wear tool + local wdef = itemstack:get_definition() + itemstack:add_wear(2000) + -- Tool break sound + if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then + minetest.sound_play(wdef.sound.breaks, {pos = sound_pos, gain = 0.5}) + end + return itemstack + end + end +}) + + +--craft fire_sticks +minetest.register_craft({ + output = 'earthbuild:fire_sticks', + recipe = { + {'group:stick'}, + {'group:stick'}, + {'group:leaves'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:fire_sticks', + recipe = { + {'group:stick'}, + {'group:stick'}, + {'group:grass'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:fire_sticks', + recipe = { + {'group:stick'}, + {'group:stick'}, + {'group:dry_grass'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:fire_sticks', + recipe = { + {'group:stick'}, + {'group:stick'}, + {'default:dry_shrub'}, + } +}) diff --git a/mods/earthbuild/wattle.lua b/mods/earthbuild/wattle.lua new file mode 100644 index 0000000..7d27c87 --- /dev/null +++ b/mods/earthbuild/wattle.lua @@ -0,0 +1,156 @@ +---------------------------------------------------------- +-- Wattle Construction +-- woven stick based construction +------------------------------------------------- + + + +----------------------------------------------------------- +--WATTLE AND DAUB NODES AND CRAFTS + +--adds wattle +minetest.register_node('earthbuild:wattle', { + description = 'Wattle', + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}}, + -- connect_bottom = + connect_front = {{-1/8, -1/2, -1/2, 1/8, 1/2, -1/8}}, + connect_left = {{-1/2, -1/2, -1/8, -1/8, 1/2, 1/8}}, + connect_back = {{-1/8, -1/2, 1/8, 1/8, 1/2, 1/2}}, + connect_right = {{ 1/8, -1/2, -1/8, 1/2, 1/2, 1/8}}, + }, + connects_to = { "group:crumbly", "group:wood", "group:tree", "group:stone", 'earthbuild:wattle', 'earthbuild:wattle_loose',}, + paramtype = "light", + tiles = {"earthbuild_wattle_top.png", "earthbuild_wattle_top.png","earthbuild_wattle.png", "earthbuild_wattle.png", "earthbuild_wattle.png", "earthbuild_wattle.png" }, + inventory_image = "earthbuild_wattle.png", + wield_image = "earthbuild_wattle.png", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 1,}, + sounds = default.node_sound_wood_defaults(), +}) + +-- adds wattle recipe +--(1 wattle per stick, makes it 4 times 'better' than wood) +minetest.register_craft({ + output = 'earthbuild:wattle 4', + recipe = { + {'', '', ''}, + {'', 'group:stick', ''}, + {'group:stick', 'group:stick', 'group:stick'}, + } +}) + +--recover wattle from wattle and daub +minetest.register_craft({ + output = 'earthbuild:wattle', + recipe = {{'earthbuild:wattle_and_daub'}} +}) + +minetest.register_craft({ + output = 'earthbuild:wattle', + recipe = {{'earthbuild:whitewashed_wattle_and_daub'}} +}) + + +--recycle wattle +minetest.register_craft({ + output = 'default:stick', + recipe = { + {'earthbuild:wattle'} + } +}) + + +---------------------------- +--adds loose wattle (a crude window... or for resource saving) + +minetest.register_node('earthbuild:wattle_loose', { + description = 'Loose Wattle', + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-1/8, -1/2, -1/8, 1/8, 1/2, 1/8}}, + -- connect_bottom = + connect_front = {{-1/8, -1/2, -1/2, 1/8, 1/2, -1/8}}, + connect_left = {{-1/2, -1/2, -1/8, -1/8, 1/2, 1/8}}, + connect_back = {{-1/8, -1/2, 1/8, 1/8, 1/2, 1/2}}, + connect_right = {{ 1/8, -1/2, -1/8, 1/2, 1/2, 1/8}}, + }, + connects_to = { "group:crumbly", "group:wood", "group:tree", "group:stone", 'earthbuild:wattle', 'earthbuild:wattle_loose', 'earthbuild:thatch'}, + paramtype = "light", + tiles = {"earthbuild_wattle_top.png", "earthbuild_wattle_top.png","earthbuild_wattle_loose.png", "earthbuild_wattle_loose.png", "earthbuild_wattle_loose.png", "earthbuild_wattle_loose.png" }, + inventory_image = "earthbuild_wattle_loose.png", + wield_image = "earthbuild_wattle_loose.png", + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 1,}, + sounds = default.node_sound_wood_defaults(), +}) + + +--split +minetest.register_craft({ + output = 'earthbuild:wattle_loose 4', + recipe = {{ 'earthbuild:wattle','earthbuild:wattle'}} +}) + +--combine +minetest.register_craft({ + output = 'earthbuild:wattle', + recipe = {{'earthbuild:wattle_loose', 'earthbuild:wattle_loose'}} +}) + +--recycle loose wattle? +--would only be half a stick... force to recombine into wattle + + +---------------------------- +-- adds wattle_and_daub +minetest.register_node('earthbuild:wattle_and_daub', { + description = 'Wattle and Daub', + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-1/4, -1/2, -1/4, 1/4, 1/2, 1/4}}, + -- connect_bottom = + connect_front = {{-1/4, -1/2, -1/2, 1/4, 1/2, -1/4}}, + connect_left = {{-1/2, -1/2, -1/4, -1/4, 1/2, 1/4}}, + connect_back = {{-1/4, -1/2, 1/4, 1/4, 1/2, 1/2}}, + connect_right = {{ 1/4, -1/2, -1/4, 1/2, 1/2, 1/4}}, + }, + connects_to = { "group:crumbly", "group:wood", "group:tree", "group:stone",'earthbuild:wattle', 'earthbuild:wattle_loose',}, + paramtype = "light", + tiles = {"earthbuild_wattle_and_daub.png"}, + inventory_image = "earthbuild_wattle_and_daub.png", + wield_image = "earthbuild_wattle_and_daub.png", + groups = {crumbly = 2, cracky = 3, choppy = 2}, + sounds = default.node_sound_dirt_defaults(), +}) + + +-- adds wattle_and_daub recipes + +minetest.register_craft({ + output = 'earthbuild:wattle_and_daub 6', + recipe = { + {'earthbuild:wattle', 'earthbuild:wattle', 'earthbuild:wattle'}, + {'earthbuild:wattle', 'earthbuild:wattle', 'earthbuild:wattle'}, + {'', 'earthbuild:cob', ''}, + } +}) + + + +---------------------------------------------- +--Burnables + +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:wattle", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:wattle_loose", + burntime = 1.5, +}) diff --git a/mods/earthbuild/weaving.lua b/mods/earthbuild/weaving.lua new file mode 100644 index 0000000..fe1e685 --- /dev/null +++ b/mods/earthbuild/weaving.lua @@ -0,0 +1,94 @@ +---------------------------------------------------------- +-- Weaving + +------------------------------------------------- + +--Woven mat + +minetest.register_node("earthbuild:woven_mat", { + description = "Woven Mat", + drawtype = "nodebox", + tiles = {"earthbuild_woven_mat.png"}, + paramtype = "light", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.48, 0.5}, + }, + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.48, 0.5}, + }, + }, + + groups = {snappy=3, flammable = 3,}, + sounds = default.node_sound_leaves_defaults(), +}) + + + + +-- adds mat recipes + +minetest.register_craft({ + output = 'earthbuild:woven_mat', + recipe = { + {'', '', ''}, + {'', '', ''}, + {'group:leaves', 'group:leaves', 'group:leaves'}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:woven_mat', + recipe = { + {'', '', ''}, + {'', '', ''}, + {'default:junglegrass', 'default:junglegrass', 'default:junglegrass'}, + } +}) + + + +minetest.register_craft({ + output = 'earthbuild:woven_mat', + recipe = { + {'', '', ''}, + {'', '', ''}, + {'group:grass', 'group:grass', 'group:grass'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:woven_mat', + recipe = { + {'', '', ''}, + {'', '', ''}, + {'group:dry_grass', 'group:dry_grass', 'group:dry_grass'}, + } +}) + +--[[ +--conflicts with default paper :-( +minetest.register_craft({ + output = 'earthbuild:woven_mat', + recipe = { + {'', '', ''}, + {'', '', ''}, + {'default:papyrus', 'default:papyrus', 'default:papyrus'}, + } +}) +]] + + +--Burn it + +minetest.register_craft({ + type = "fuel", + recipe = "earthbuild:woven_mat", + burntime = 1, +}) + diff --git a/mods/earthbuild/whitewash.lua b/mods/earthbuild/whitewash.lua new file mode 100644 index 0000000..3da2d0a --- /dev/null +++ b/mods/earthbuild/whitewash.lua @@ -0,0 +1,463 @@ +---------------------------------------------------------- +-- Whitewash +-- Coloring added to surfaces +--historically used for aesthetics, durability, hygiene +------------------------------------------------- +--Note on crafting: +-- made from slaked lime (+ optional additives) +--slaked lime is from quicklime mixed with water +-- quicklime is made by burning limestone +--...and limestone is not currently in the game. +--(but coral is, and limestone rocks could be found in gravel). + +--Note on crafting ratios: +--control ratio at cooking stage. More lime rich -> more quicklime. +--wash is spread thin... +--so one block of pure lime (e.g. coral) covers many. 18? +--assume gravel is 1/3rd limestone. + +--Note on digging strength: +--cures to limestone (sort of), so give a boost to digging strength +-- {crumbly = 1, cracky = 2} +-- makes it like stone. Gives a reason for making it, other than aesthetics + + +---------------------------------------------------- + +--------------------------------------------- +--Sourcing The Whitewash itself + +--Quicklime +minetest.register_craftitem("earthbuild:quicklime", { + description = "Quicklime", + inventory_image = "earthbuild_quicklime.png", + stack_max = 99, +}) + +--Whitewash (technically Slaked lime) +minetest.register_craftitem("earthbuild:whitewash", { + description = "Whitewash", + inventory_image = "earthbuild_whitewash.png", + stack_max = 99, +}) + +---------------- +--Cooking to get quicklime +--Cook coral to give quicklime +minetest.register_craft({ + type = "cooking", + output = "earthbuild:quicklime 9", + recipe = "default:coral_skeleton", + cooktime = 3, +}) + + +---------------------- +--Slake the quicklime in water to make whitewash +--with clay pots +minetest.register_craft({ + output = 'earthbuild:whitewash 6', + recipe = { + {'earthbuild:quicklime','earthbuild:quicklime','earthbuild:quicklime'}, + {'earthbuild:quicklime','earthbuild:quicklime','earthbuild:quicklime'}, + {'','earthbuild:clay_pot_water',''}, + }, + replacements = {{"earthbuild:clay_pot_water", "earthbuild:clay_pot"}} +}) + +minetest.register_craft({ + output = 'earthbuild:whitewash 6', + recipe = { + {'earthbuild:quicklime','earthbuild:quicklime','earthbuild:quicklime'}, + {'earthbuild:quicklime','earthbuild:quicklime','earthbuild:quicklime'}, + {'','earthbuild:clay_pot_river_water',''}, + }, + replacements = {{"earthbuild:clay_pot_river_water", "earthbuild:clay_pot"}} +}) + +--with default buckets +minetest.register_craft({ + output = 'earthbuild:whitewash 6', + recipe = { + {'earthbuild:quicklime','earthbuild:quicklime','earthbuild:quicklime'}, + {'earthbuild:quicklime','earthbuild:quicklime','earthbuild:quicklime'}, + {'','bucket:bucket_water',''}, + }, + replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}} +}) + +minetest.register_craft({ + output = 'earthbuild:whitewash 6', + recipe = { + {'earthbuild:quicklime','earthbuild:quicklime','earthbuild:quicklime'}, + {'earthbuild:quicklime','earthbuild:quicklime','earthbuild:quicklime'}, + {'','bucket:bucket_river_water',''}, + }, + replacements = {{"bucket:bucket_river_water", "bucket:bucket_empty"}} +}) + + + +-------------------------------------------------------------- +--WHITEWASH NODES AND CRAFTS + +-------------------------------------- +--Wattle and Daub + +minetest.register_node('earthbuild:whitewashed_wattle_and_daub', { + description = 'Whitewashed Wattle and Daub', + drawtype = "nodebox", + node_box = { + type = "connected", + fixed = {{-1/4, -1/2, -1/4, 1/4, 1/2, 1/4}}, + -- connect_bottom = + connect_front = {{-1/4, -1/2, -1/2, 1/4, 1/2, -1/4}}, + connect_left = {{-1/2, -1/2, -1/4, -1/4, 1/2, 1/4}}, + connect_back = {{-1/4, -1/2, 1/4, 1/4, 1/2, 1/2}}, + connect_right = {{ 1/4, -1/2, -1/4, 1/2, 1/2, 1/4}}, + }, + connects_to = { "group:crumbly", "group:wood", "group:tree", "group:stone", 'earthbuild:wattle', 'earthbuild:wattle_loose'}, + paramtype = "light", + tiles = {"earthbuild_whitewashed_earth.png"}, + inventory_image = "earthbuild_whitewashed_earth.png", + wield_image = "earthbuild_whitewashed_earth.png", + groups = {crumbly = 1, cracky = 2, choppy = 2}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds whitewashed_wattle_and_daub recipes +minetest.register_craft({ + output = 'earthbuild:whitewashed_wattle_and_daub', + recipe = { + {'earthbuild:wattle_and_daub', 'earthbuild:whitewash'}, + } +}) + + + +-------------------------------------- +-- Mud brick + +minetest.register_node('earthbuild:whitewashed_mud_brick', { + description = 'Whitewashed Mud Brick', + drawtype = "normal", + tiles = {"earthbuild_whitewashed_earth.png"}, + paramtype = "light", + groups = {crumbly = 1, cracky = 2}, + sounds = default.node_sound_dirt_defaults(), +}) + + +-- adds whitewashed_mud_brick recipes +minetest.register_craft({ + output = 'earthbuild:whitewashed_mud_brick', + recipe = { + {'earthbuild:mud_brick', 'earthbuild:whitewash'}, + } +}) + + + +------------------------------------------ +-- Earth (both from cob and rammed earth...as they end up indistinguishable) + +minetest.register_node('earthbuild:whitewashed_earth', { + description = 'Whitewashed Earth', + drawtype = "normal", + tiles = {"earthbuild_whitewashed_earth.png"}, + paramtype = "light", + groups = {crumbly = 1, cracky = 2, falling_node = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + + +-- adds whitewashed_earth recipes + +minetest.register_craft({ + output = 'earthbuild:whitewashed_earth', + recipe = { + {'earthbuild:cob', 'earthbuild:whitewash'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:whitewashed_earth', + recipe = { + {'earthbuild:rammed_earth', 'earthbuild:whitewash'}, + } +}) + + + + +-------------------------------------------- +-- Supported Earth Roof + +----------- +-- supported earth +minetest.register_node('earthbuild:supported_whitewashed_earth', { + description = 'Supported Whitewashed Earth', + drawtype = "normal", + tiles = { + "earthbuild_whitewashed_earth.png", + "default_wood.png", + "earthbuild_supported_whitewashed_earth.png", + "earthbuild_supported_whitewashed_earth.png", + "earthbuild_supported_whitewashed_earth.png", + "earthbuild_supported_whitewashed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 2, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds supported whitewashed_earth recipes + +minetest.register_craft({ + output = 'earthbuild:supported_whitewashed_earth', + recipe = { + {'earthbuild:supported_rammed_earth', 'earthbuild:whitewash'}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:supported_whitewashed_earth', + recipe = { + {'earthbuild:supported_cob', 'earthbuild:whitewash'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:supported_whitewashed_earth 3', + recipe = { + {'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth'}, + {'default:wood', '', ''}, + {'', '', ''}, + } +}) + + +----------------------------- +-- jungle wood supported earth + +minetest.register_node('earthbuild:junglewood_supported_whitewashed_earth', { + description = 'Jungle Wood Supported Whitewashed Earth', + drawtype = "normal", + tiles = { + "earthbuild_whitewashed_earth.png", + "default_junglewood.png", + "earthbuild_junglewood_supported_whitewashed_earth.png", + "earthbuild_junglewood_supported_whitewashed_earth.png", + "earthbuild_junglewood_supported_whitewashed_earth.png", + "earthbuild_junglewood_supported_whitewashed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 2, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds junglewood supported whitewashed_earth recipes + +minetest.register_craft({ + output = 'earthbuild:junglewood_supported_whitewashed_earth', + recipe = { + {'earthbuild:junglewood_supported_rammed_earth', 'earthbuild:whitewash'}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:junglewood_supported_whitewashed_earth', + recipe = { + {'earthbuild:junglewood_supported_cob', 'earthbuild:whitewash'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:junglewood_supported_whitewashed_earth 3', + recipe = { + {'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth'}, + {'default:junglewood', '', ''}, + {'', '', ''}, + } +}) + + +------------------------------------ +-- pine wood supported earth + +minetest.register_node('earthbuild:pine_wood_supported_whitewashed_earth', { + description = 'Pine Wood Supported Whitewashed Earth', + drawtype = "normal", + tiles = { + "earthbuild_whitewashed_earth.png", + "default_pine_wood.png", + "earthbuild_pine_wood_supported_whitewashed_earth.png", + "earthbuild_pine_wood_supported_whitewashed_earth.png", + "earthbuild_pine_wood_supported_whitewashed_earth.png", + "earthbuild_pine_wood_supported_whitewashed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 2, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + + +-- adds pine wood supported whitewashed_earth recipes + +minetest.register_craft({ + output = 'earthbuild:pine_wood_supported_whitewashed_earth', + recipe = { + {'earthbuild:pine_wood_supported_rammed_earth', 'earthbuild:whitewash'}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:pine_wood_supported_whitewashed_earth', + recipe = { + {'earthbuild:pine_wood_supported_cob', 'earthbuild:whitewash'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:pine_wood_supported_whitewashed_earth 3', + recipe = { + {'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth'}, + {'default:pine_wood', '', ''}, + {'', '', ''}, + } +}) + + +------------------------------- +-- acacia wood supported earth + +minetest.register_node('earthbuild:acacia_wood_supported_whitewashed_earth', { + description = 'Acacia Wood Supported Whitewashed Earth', + drawtype = "normal", + tiles = { + "earthbuild_whitewashed_earth.png", + "default_acacia_wood.png", + "earthbuild_acacia_wood_supported_whitewashed_earth.png", + "earthbuild_acacia_wood_supported_whitewashed_earth.png", + "earthbuild_acacia_wood_supported_whitewashed_earth.png", + "earthbuild_acacia_wood_supported_whitewashed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 2, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds acacia wood supported whitewashed_earth recipes + +minetest.register_craft({ + output = 'earthbuild:acacia_wood_supported_whitewashed_earth', + recipe = { + {'earthbuild:acacia_wood_supported_rammed_earth', 'earthbuild:whitewash'}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:acacia_wood_supported_whitewashed_earth', + recipe = { + {'earthbuild:acacia_wood_supported_cob', 'earthbuild:whitewash'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:acacia_wood_supported_whitewashed_earth 3', + recipe = { + {'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth'}, + {'default:acacia_wood', '', ''}, + {'', '', ''}, + } +}) + +----------------------------------------------- +-- aspen wood supported earth + +minetest.register_node('earthbuild:aspen_wood_supported_whitewashed_earth', { + description = 'Aspen Wood Supported Whitewashed Earth', + drawtype = "normal", + tiles = { + "earthbuild_whitewashed_earth.png", + "default_aspen_wood.png", + "earthbuild_aspen_wood_supported_whitewashed_earth.png", + "earthbuild_aspen_wood_supported_whitewashed_earth.png", + "earthbuild_aspen_wood_supported_whitewashed_earth.png", + "earthbuild_aspen_wood_supported_whitewashed_earth.png" +}, + paramtype = "light", + groups = {crumbly = 1, cracky = 2, choppy = 2, flammable=1}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- adds aspen wood supported whitewashed_earth recipes + +minetest.register_craft({ + output = 'earthbuild:aspen_wood_supported_whitewashed_earth', + recipe = { + {'earthbuild:aspen_wood_supported_rammed_earth', 'earthbuild:whitewash'}, + } +}) + + +minetest.register_craft({ + output = 'earthbuild:aspen_wood_supported_whitewashed_earth', + recipe = { + {'earthbuild:aspen_wood_supported_cob', 'earthbuild:whitewash'}, + } +}) + +minetest.register_craft({ + output = 'earthbuild:aspen_wood_supported_whitewashed_earth 3', + recipe = { + {'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth', 'earthbuild:whitewashed_earth'}, + {'default:aspen_wood', '', ''}, + {'', '', ''}, + } +}) + + + +------------------------------------------ +--STRAW-BALE +minetest.register_node('earthbuild:whitewashed_strawbale', { + description = 'Whitewashed Straw-bale Wall', + drawtype = "normal", + tiles = {"earthbuild_whitewashed_earth.png"}, + paramtype = "light", + --drop = "default:dirt", + groups = {crumbly = 1, snappy = 1, falling_node = 1}, + sounds = default.node_sound_dirt_defaults(), +}) + +minetest.register_craft({ + output = 'earthbuild:whitewashed_strawbale', + recipe = { + {'earthbuild:strawbale', 'earthbuild:whitewash'}, + } +}) + +---------------------------------------------- +--STAIRS and SLABS + +-- Stairs and slab for whitewashed_earth +stairs.register_stair_and_slab("whitewashed_earth", "earthbuild:whitewashed_earth", + {crumbly = 1, cracky = 2, falling_node = 1}, + {"earthbuild_whitewashed_earth.png"}, + "Whitewashed Earth Stair", + "Whitewashed Earth Slab", + default.node_sound_dirt_defaults()) + + +-- Stairs and slab for whitewashed_mud_brick +stairs.register_stair_and_slab("whitewashed_mud_brick", "earthbuild:whitewashed_mud_brick", + {crumbly = 1, cracky = 2}, + {"earthbuild_whitewashed_earth.png"}, + "Whitewashed Earth Stair", + "Whitewashed Earth Slab", + default.node_sound_dirt_defaults()) diff --git a/mods/env_sounds/README.txt b/mods/env_sounds/README.txt new file mode 100644 index 0000000..42835d2 --- /dev/null +++ b/mods/env_sounds/README.txt @@ -0,0 +1,13 @@ +Minetest Game mod: env_sounds +============================= +See license.txt for license information. + +Authors of source code +---------------------- +paramat (MIT) + +Authors of media (sounds) +------------------------- +Yuval (CC0 1.0) +https://freesound.org/people/Yuval/sounds/197023/ + env_sounds_water.*.ogg diff --git a/mods/env_sounds/init.lua b/mods/env_sounds/init.lua new file mode 100644 index 0000000..546e990 --- /dev/null +++ b/mods/env_sounds/init.lua @@ -0,0 +1,64 @@ +-- Parameters + +local radius = 8 -- Water node search radius around player + +-- End of parameters + + +local river_source_sounds = minetest.settings:get_bool("river_source_sounds") + + +-- Update sound for player + +local function update_sound(player) + local player_name = player:get_player_name() + local ppos = player:get_pos() + local areamin = vector.subtract(ppos, radius) + local areamax = vector.add(ppos, radius) + local water_nodes = {"default:water_flowing", "default:river_water_flowing"} + if river_source_sounds then + table.insert(water_nodes, "default:river_water_source") + end + local wpos, _ = minetest.find_nodes_in_area(areamin, areamax, water_nodes) + local waters = #wpos + if waters == 0 then + return + end + + -- Find average position of water positions + local wposav = vector.new() + for _, pos in ipairs(wpos) do + wposav.x = wposav.x + pos.x + wposav.y = wposav.y + pos.y + wposav.z = wposav.z + pos.z + end + wposav = vector.divide(wposav, waters) + + minetest.sound_play( + "env_sounds_water", + { + pos = wposav, + to_player = player_name, + gain = math.min(0.04 + waters * 0.004, 0.4), + } + ) +end + + +-- Update sound 'on joinplayer' + +minetest.register_on_joinplayer(function(player) + update_sound(player) +end) + + +-- Cyclic sound update + +local function cyclic_update() + for _, player in pairs(minetest.get_connected_players()) do + update_sound(player) + end + minetest.after(3.5, cyclic_update) +end + +minetest.after(0, cyclic_update) diff --git a/mods/env_sounds/license.txt b/mods/env_sounds/license.txt new file mode 100644 index 0000000..ff8867d --- /dev/null +++ b/mods/env_sounds/license.txt @@ -0,0 +1,57 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2019 paramat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (sounds) +-------------------------- + +CC0 1.0 Universal (CC0 1.0) Public Domain Dedication +Yuval + +No Copyright + +The person who associated a work with this deed has dedicated the work to the +public domain by waiving all of his or her rights to the work worldwide under +copyright law, including all related and neighboring rights, to the extent +allowed by law. + +You can copy, modify, distribute and perform the work, even for commercial +purposes, all without asking permission. See Other Information below. + +Other Information: + +In no way are the patent or trademark rights of any person affected by CC0, nor +are the rights that other persons may have in the work or in how the work is +used, such as publicity or privacy rights. + +Unless expressly stated otherwise, the person who associated a work with this +deed makes no warranties about the work, and disclaims liability for all uses +of the work, to the fullest extent permitted by applicable law. + +When using or citing the work, you should not imply endorsement by the author +or the affirmer. + +For more details: +https://creativecommons.org/publicdomain/zero/1.0/ diff --git a/mods/env_sounds/mod.conf b/mods/env_sounds/mod.conf new file mode 100644 index 0000000..ad6feb3 --- /dev/null +++ b/mods/env_sounds/mod.conf @@ -0,0 +1,3 @@ +name = env_sounds +description = Minetest Game mod: env_sounds +depends = default diff --git a/mods/env_sounds/sounds/env_sounds_water.1.ogg b/mods/env_sounds/sounds/env_sounds_water.1.ogg new file mode 100644 index 0000000..aa80882 Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_water.1.ogg differ diff --git a/mods/env_sounds/sounds/env_sounds_water.2.ogg b/mods/env_sounds/sounds/env_sounds_water.2.ogg new file mode 100644 index 0000000..b3ff114 Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_water.2.ogg differ diff --git a/mods/env_sounds/sounds/env_sounds_water.3.ogg b/mods/env_sounds/sounds/env_sounds_water.3.ogg new file mode 100644 index 0000000..431a6ed Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_water.3.ogg differ diff --git a/mods/env_sounds/sounds/env_sounds_water.4.ogg b/mods/env_sounds/sounds/env_sounds_water.4.ogg new file mode 100644 index 0000000..56c2ee2 Binary files /dev/null and b/mods/env_sounds/sounds/env_sounds_water.4.ogg differ diff --git a/mods/epic/ABMs.lua b/mods/epic/ABMs.lua new file mode 100644 index 0000000..a62834b --- /dev/null +++ b/mods/epic/ABMs.lua @@ -0,0 +1,165 @@ +minetest.register_abm({ + label = 'Floating stones', + nodenames = {'epic:float_stone'}, + neighbors = {'air'}, + interval = 17, + chance = 3, + action = function(pos, node) + local new_pos = ({x=pos.x, y=pos.y+1, z=pos.z}) + local abovenode = minetest.get_node(new_pos).name + if abovenode == 'air' then + local timer = minetest.get_node_timer(pos) + timer:start(1) + end + end, +}) + +minetest.register_abm({ + label = 'Fire Embers', + nodenames = {'default:lava_source', 'default:lava_flowing', 'fire:permanent_flame', 'fire:basic_flame'}, + interval = 13, + chance = 7, + action = function(pos, node) + if minetest.get_node({x=pos.x, y=pos.y+1.0, z=pos.z}).name == 'air' then + particles_embers(pos) + end + end +}) + +minetest.register_abm({ + label = 'sulfur formation', + nodenames = {'default:stone'}, + neighbors = {'default:lava_source', 'default:lava_flowing'}, + interval = 20, + chance = 60, + action = function(pos, node) + if pos.y < -100 then + if minetest.find_node_near(pos, 3, {'epic:mineral_sulfur'}) ~= nil then + return + end + minetest.set_node(pos, {name='epic:mineral_sulfur'}) + end + end, +}) + +minetest.register_abm({ + label = 'lumberjack step removal', + nodenames = {'lumberjack:step'}, + interval = 151, + chance = 21, + action = function(pos) + minetest.remove_node(pos) + end +}) + +minetest.register_abm({ + label = 'Glow sapphire growth', + nodenames = {'caverealms:glow_crystal'}, + neighbors = {'caverealms:glow_ore'}, + interval = 30, + chance = 17, + action = function(pos, node) + local pos1 = {x=pos.x+1, y=pos.y-1, z=pos.z+1} + local pos0 = {x=pos.x-1, y=pos.y-1, z=pos.z-1} + local can_replace = minetest.find_nodes_in_area(pos0, pos1, 'default:lava_source') + local replace_num = #can_replace + if replace_num ~= 8 then + return + end + local height = 0 + while node.name == "caverealms:glow_crystal" and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + if height == 4 or node.name ~= 'air' then + return + end + minetest.set_node(pos, {name = 'caverealms:glow_crystal'}) + return true + end +}) + +minetest.register_abm({ + label = 'Glow amethyst growth', + nodenames = {'caverealms:glow_amethyst'}, + neighbors = {'caverealms:glow_amethyst_ore'}, + interval = 30, + chance = 17, + action = function(pos, node) + local pos1 = {x=pos.x+1, y=pos.y-1, z=pos.z+1} + local pos0 = {x=pos.x-1, y=pos.y-1, z=pos.z-1} + local can_replace = minetest.find_nodes_in_area(pos0, pos1, 'default:lava_source') + local replace_num = #can_replace + if replace_num ~= 8 then + return + end + local height = 0 + while node.name == "caverealms:glow_amethyst" and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + if height == 4 or node.name ~= 'air' then + return + end + minetest.set_node(pos, {name = 'caverealms:glow_amethyst'}) + return true + end +}) + +minetest.register_abm({ + label = 'Glow sapphire growth', + nodenames = {'caverealms:glow_emerald'}, + neighbors = {'caverealms:glow_emerald_ore'}, + interval = 30, + chance = 17, + action = function(pos, node) + local pos1 = {x=pos.x+1, y=pos.y-1, z=pos.z+1} + local pos0 = {x=pos.x-1, y=pos.y-1, z=pos.z-1} + local can_replace = minetest.find_nodes_in_area(pos0, pos1, 'default:lava_source') + local replace_num = #can_replace + if replace_num ~= 8 then + return + end + local height = 0 + while node.name == "caverealms:glow_emerald" and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + if height == 4 or node.name ~= 'air' then + return + end + minetest.set_node(pos, {name = 'caverealms:glow_emerald'}) + return true + end +}) + +minetest.register_abm({ + label = 'Glow ruby growth', + nodenames = {'caverealms:glow_ruby'}, + neighbors = {'caverealms:glow_ruby_ore'}, + interval = 30, + chance = 17, + action = function(pos, node) + local pos1 = {x=pos.x+1, y=pos.y-1, z=pos.z+1} + local pos0 = {x=pos.x-1, y=pos.y-1, z=pos.z-1} + local can_replace = minetest.find_nodes_in_area(pos0, pos1, 'default:lava_source') + local replace_num = #can_replace + if replace_num ~= 8 then + return + end + local height = 0 + while node.name == 'caverealms:glow_ruby' and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + if height == 4 or node.name ~= 'air' then + return + end + minetest.set_node(pos, {name = 'caverealms:glow_ruby'}) + return true + end +}) diff --git a/mods/epic/armor.lua b/mods/epic/armor.lua new file mode 100644 index 0000000..a5aba37 --- /dev/null +++ b/mods/epic/armor.lua @@ -0,0 +1,259 @@ +armor:register_armor('epic:crown', { + description = 'Admin Crown', + inventory_image = 'epic_crown_inv.png', + groups = {armor_head=1, armor_use=0, armor_fire=5, armor_block=100, armor_water=5, physics_jump=0.5, physics_speed=1.3, armor_heal = 20, not_in_creative_inventory=1}, + armor_groups = {fleshy=100}, + damage_groups = {cracky=2, snappy=1, level=3}, + on_drop = function(itemstack, dropper, pos) + return + end, +}) + +armor:register_armor('epic:cap_deception', { + description = 'Fur Cap of Deception', + inventory_image = 'epic_cap_deception_inv.png', + groups = {armor_head=1, armor_use=300, armor_block=1, physics_jump=-0.12, physics_speed=-.1, armor_heal = 2, not_in_creative_inventory=1}, + armor_groups = {fleshy=25}, + damage_groups = {cracky=2, snappy=1, level=3}, +}) + +--[[default groups: +Elements: armor_head, armor_torso, armor_legs, armor_feet +Attributes: armor_heal, armor_fire, armor_water, armor_block +Armor_heal actively heals the wearer. Max HP is 50. +Armor_fire protects against fire and lava. +Armor_water allows for breathing underwater. +Armor_block determins if an attack with deal damage. +Physics: physics_jump, physics_speed, physics_gravity +Durability: armor_use, flammable + +{'epic:float_crystal', 'gravity'}, +{'epic:bloodstone', 'healing'}, +{'epic:huntite', 'fire'}, +{'ocean:prismarine_crystals', 'water'}, +{'epic:garnet', 'speed'}, +{'quartz:quartz_crystal_piece', 'jump'} + +Armor Stats Shields can improve these values. +wood +Level 27, block 6% +steel +Level 37.8, block 24% +Bronze +Level 45, block 36% +Gold +Level 48.6, block 44% +Diamond +Level 63, block 60% +Diamond Enchanted +Level 66.6, block 68% +Titanium +Level 21.6, block 80% +--]] + +--Actinolite armor provides lower gravity. +armor:register_armor('epic:helmet_gravity', { + _doc_items_crafting = 'This tool is crafted in the Crystal Workshop.', + description = 'Diamond helmet with Actinolite enchantment', + inventory_image = 'epic_helmet_inv.png^epic_gravity_overlay.png', + groups = {armor_head=1, armor_block=17, armor_use=190, physics_gravity=-.15}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, choppy=1, level=4}, +}) + +armor:register_armor('epic:chestplate_gravity', { + description = 'Diamond chestplate with Actinolite enchantment', + inventory_image = 'epic_chestplate_inv.png^epic_gravity_overlay.png', + groups = {armor_torso=1, armor_block=17, armor_use=190, physics_gravity=-.2}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:leggings_gravity', { + description = 'Diamond leggings with Actinolite enchantment', + inventory_image = 'epic_leggings_inv.png^epic_gravity_overlay.png', + groups = {armor_legs=1, armor_block=17, armor_use=190, physics_gravity=-.2}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:boots_gravity', { + description = 'Diamond boots with Actinolite enchantment', + inventory_image = 'epic_boots_inv.png^epic_gravity_overlay.png', + groups = {armor_feet=1, armor_block=17, armor_use=190, physics_gravity=-.15}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +--Bloodstone armor provides healing. +armor:register_armor('epic:helmet_healing', { + description = 'Diamond helmet with Bloodstone enchantment', + inventory_image = 'epic_helmet_inv.png^epic_healing_overlay.png', + groups = {armor_head=1, armor_block=17, armor_use=190, armor_heal=1}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:chestplate_healing', { + description = 'Diamond chestplate with Bloodstone enchantment', + inventory_image = 'epic_chestplate_inv.png^epic_healing_overlay.png', + groups = {armor_torso=1, armor_block=17, armor_use=190, armor_heal=1}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:leggings_healing', { + description = 'Diamond leggings with Bloodstone enchantment', + inventory_image = 'epic_leggings_inv.png^epic_healing_overlay.png', + groups = {armor_legs=1, armor_block=17, armor_use=190, armor_heal=1}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:boots_healing', { + description = 'Diamond boots with Bloodstone enchantment', + inventory_image = 'epic_boots_inv.png^epic_healing_overlay.png', + groups = {armor_feet=1, armor_block=17, armor_use=190, armor_heal=1}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +--huntite armor provides fire protection. +armor:register_armor('epic:helmet_fire', { + description = 'Diamond helmet with Huntite enchantment', + inventory_image = 'epic_helmet_inv.png^epic_fire_overlay.png', + groups = {armor_head=1, armor_block=17, armor_use=380, armor_fire=1, flammable=1}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:chestplate_fire', { + description = 'Diamond chestplate with Huntite enchantment', + inventory_image = 'epic_chestplate_inv.png^epic_fire_overlay.png', + groups = {armor_torso=1, armor_block=17, armor_use=190, armor_fire=2, flammable=1}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:leggings_fire', { + description = 'Diamond leggings with Huntite enchantment', + inventory_image = 'epic_leggings_inv.png^epic_fire_overlay.png', + groups = {armor_legs=1, armor_block=17, armor_use=190, armor_fire=2, flammable=1}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:boots_fire', { + description = 'Diamond boots with Huntite enchantment', + inventory_image = 'epic_boots_inv.png^epic_fire_overlay.png', + groups = {armor_feet=1, armor_block=17, armor_use=380, armor_fire=1, flammable=11}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +--prismarine crystals armor provides underwater breathing. +armor:register_armor('epic:helmet_water', { + description = 'Diamond helmet with Prismarine enchantment', + inventory_image = 'epic_helmet_inv.png^epic_water_overlay.png', + groups = {armor_head=1, armor_block=17, armor_use=190, armor_water=1}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:chestplate_water', { + description = 'Diamond chestplate with Prismarine enchantment', + inventory_image = 'epic_chestplate_inv.png^epic_water_overlay.png', + groups = {armor_torso=1, armor_block=17, armor_use=190, armor_water=1}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:leggings_water', { + description = 'Diamond leggings with Prismarine enchantment', + inventory_image = 'epic_leggings_inv.png^epic_water_overlay.png', + groups = {armor_legs=1, armor_block=17, armor_use=190, armor_water=1}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:boots_water', { + description = 'Diamond boots with Prismarine enchantment', + inventory_image = 'epic_boots_inv.png^epic_water_overlay.png', + groups = {armor_feet=1, armor_block=17, armor_use=190, armor_water=1}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +--Garnet crystals armor provides speed. +armor:register_armor('epic:helmet_speed', { + description = 'Diamond helmet with Garnet enchantment', + inventory_image = 'epic_helmet_inv.png^epic_speed_overlay.png', + groups = {armor_head=1, armor_block=17, armor_use=190, physics_speed=.2}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:chestplate_speed', { + description = 'Diamond chestplate with Garnet enchantment', + inventory_image = 'epic_chestplate_inv.png^epic_speed_overlay.png', + groups = {armor_torso=1, armor_block=17, armor_use=190, physics_speed=.4}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:leggings_speed', { + description = 'Diamond leggings with Garnet enchantment', + inventory_image = 'epic_leggings_inv.png^epic_speed_overlay.png', + groups = {armor_legs=1, armor_block=17, armor_use=190, physics_speed=.4}, + armor_groups = {fleshy=21}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:boots_speed', { + description = 'Diamond boots with Garnet enchantment', + inventory_image = 'epic_boots_inv.png^epic_speed_overlay.png', + groups = {armor_feet=1, armor_block=17, armor_use=190, physics_speed=.2}, + armor_groups = {fleshy=16}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +--Titanium, very light, high block chance, but low damge absorbtion. +armor:register_armor('epic:helmet_titanium', { + description = 'Titanium helmet', + inventory_image = 'epic_helmet_titanium_inv.png', + groups = {armor_head=1, armor_block=15, armor_use=180, physics_speed=.15, physics_jump=0.1}, + armor_groups = {fleshy=4}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:chestplate_titanium', { + description = 'Titanium chestplate', + inventory_image = 'epic_chestplate_titanium_inv.png', + groups = {armor_torso=1, armor_block=25, armor_use=180, physics_speed=.25, physics_jump=0.1}, + armor_groups = {fleshy=8}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:leggings_titanium', { + description = 'Titanium leggings', + inventory_image = 'epic_leggings_titanium_inv.png', + groups = {armor_legs=1, armor_block=25, armor_use=180, physics_speed=.25, physics_jump=0.1}, + armor_groups = {fleshy=8}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:boots_titanium', { + description = 'Titanium boots', + inventory_image = 'epic_boots_titanium_inv.png', + groups = {armor_feet=1, armor_block=15, armor_use=180, physics_speed=.15, physics_jump=0.1}, + armor_groups = {fleshy=4}, + damage_groups = {cracky=2, snappy=1, level=4}, +}) + +armor:register_armor('epic:shield_titanium', { + description = 'Titanium shield', + inventory_image = 'epic_inv_shield_titanium.png', + groups = {armor_shield=1, armor_block=15, armor_use=180}, + armor_groups = {fleshy=10}, + damage_groups = {cracky=2, snappy=3, choppy=2, crumbly=1, level=2}, +}) diff --git a/mods/epic/awards.lua b/mods/epic/awards.lua new file mode 100644 index 0000000..892e61e --- /dev/null +++ b/mods/epic/awards.lua @@ -0,0 +1,26 @@ +awards.register_award('frequent_flier',{ + title = 'Frequent Flier', + description = 'Join the game 50 times', + icon = '', + secret = true, + trigger = { + type = 'join', + target = 50, + }, + prizes = { + 'commoditymarket:gold_coins 1000', + }, +}) + +awards.register_award('forest_ranger',{ + title = 'Forest Ranger', + description = 'Harvest 10000 burnt trees.', + icon = '', + secret = true, + trigger = { + type = 'dig', + node = 'epic:tree_ash', + target = 10000 + }, +-- prizes = {'epic:ranger_hat'}, +}) diff --git a/mods/epic/craftitems.lua b/mods/epic/craftitems.lua new file mode 100644 index 0000000..71b8708 --- /dev/null +++ b/mods/epic/craftitems.lua @@ -0,0 +1,145 @@ +minetest.register_craftitem('epic:float_crystal', { + description = 'Actinolite Crystal', + inventory_image = 'epic_actinolite_crystal.png' +}) + +minetest.register_craftitem('epic:float_crystal_shard', { + description = 'Actinolite Crystal Shard', + inventory_image = 'epic_actinolite_crystal_shard.png', + stack_max = 891, +}) + +minetest.register_craftitem('epic:bloodstone', { + description = 'Bloodstone', + inventory_image = 'epic_bloodstone.png' +}) + +minetest.register_craftitem('epic:bloodstone_shard', { + description = 'Bloodstone Shard', + inventory_image = 'epic_bloodstone_shard.png', + stack_max = 891, +}) + +minetest.register_craftitem('epic:bloodstone_powder', { + description = 'Bloodstone Powder', + inventory_image = 'epic_bloodstone_powder.png', + stack_max = 999, +}) + +minetest.register_craftitem('epic:teleport_powder', { + description = 'Teleport powder', + inventory_image = 'epic_teleport_powder.png', +}) + +minetest.register_craftitem('epic:ash', { + description = 'Wood ash', + inventory_image = 'epic_ash.png', +}) + +minetest.register_craftitem('epic:healing_powder', { + description = 'Healing powder', + inventory_image = 'epic_healing_powder.png', + on_use = function(itemstack, user, pointed_thing) + local hp = user:get_hp() + user:set_hp(hp+20) + local pos = user:get_pos() + particles_healing(pos) + local objs = minetest.get_objects_inside_radius(pos, 4) + for _, obj in pairs(objs) do + if obj:is_player() then + local hp = obj:get_hp() + local x = hp + hp/4 + obj:set_hp(x) + end + end + itemstack:take_item(1); return itemstack + end +}) + +minetest.register_craftitem('epic:salt_lump', { + description = 'Salt lump', + inventory_image = 'epic_salt_lump.png' +}) + +minetest.register_craftitem('epic:salt', { + description = 'Salt', + inventory_image = 'epic_salt.png' +}) + +minetest.register_craftitem('epic:potassium_nitrate', { + description = 'Potassium Nitrate', + inventory_image = 'epic_potassium_nitrate.png' +}) + +minetest.register_craftitem('epic:sulfur_lump', { + description = 'Sulfur lump', + inventory_image = 'epic_sulfur_lump.png' +}) + +minetest.register_craftitem('epic:sulfur_dust', { + description = 'Sulfur dust', + inventory_image = 'epic_sulfur_dust.png' +}) + +minetest.register_craftitem('epic:garnet', { + description = 'Garnet', + inventory_image = 'epic_garnet.png' +}) + +minetest.register_craftitem('epic:arrow_tip', { + description = 'Arrow tip', + inventory_image = 'epic_arrow_tip.png' +}) + +minetest.register_craftitem('epic:titanium_lump', { + description = 'Titanium lump', + inventory_image = 'epic_titanium_lump.png' +}) + +minetest.register_craftitem('epic:titanium_ingot', { + description = 'Titanium ingot', + inventory_image = 'epic_titanium_ingot.png' +}) + +minetest.register_craftitem('epic:deed', { + description = 'Land deed', + inventory_image = 'epic_deed.png' +}) + +minetest.register_craftitem('epic:huntite', { + description = 'Huntite', + inventory_image = 'epic_huntite.png' +}) + +minetest.register_craftitem('epic:lead_lump', { + description = 'Lead lump', + inventory_image = 'epic_lead_lump.png', +}) + +minetest.register_craftitem('epic:lead_wire', { + description = 'Lead wire', + inventory_image = 'epic_lead_wire.png', +}) + +minetest.register_craftitem('epic:laputa', { + description = 'Laputa', + inventory_image = 'epic_laputa_inv.png', + groups = {not_in_creative_inventory=1}, + on_use = function(itemstack, user, pointed_thing) + local pos = user:get_pos() + local lower_pos = {x=pos.x, y=pos.y-3, z=pos.z} + minetest.set_node(lower_pos, {name = 'epic:floating_base'}) + itemstack:take_item(1); + return itemstack + end, +}) + +minetest.register_craftitem('epic:glowstone_fragment', { + description = 'Glowstone Fragment', + inventory_image = 'epic_glowstone_fragment.png', +}) + +minetest.register_craftitem('epic:glowingdiamond', { + description = 'Glowing Diamond', + inventory_image = 'epic_glowingdiamond.png', +}) diff --git a/mods/epic/crafts.lua b/mods/epic/crafts.lua new file mode 100644 index 0000000..d422a97 --- /dev/null +++ b/mods/epic/crafts.lua @@ -0,0 +1,213 @@ +local crystals = { + {'float_crystal', 'float_crystal_shard'}, + {'bloodstone', 'bloodstone_shard'}, +} + +for i in ipairs (crystals) do + local crystal = crystals[i][1] + local shard = crystals[i][2] + + minetest.register_craft({ + output = 'epic:'..shard..' 9', + recipe = { + {'epic:'..crystal} + } + }) +end + +minetest.register_craft({ + output = 'default:dirt', + recipe = { + {'epic:scorched_dirt', 'bonemeal:mulch'} + } +}) + +minetest.register_craft({ + output = 'default:dirt 2', + recipe = { + {'epic:scorched_dirt', 'compost:compost'} + } +}) + +minetest.register_craft({ + output = 'default:dirt 2', + recipe = { + {'default:dry_dirt', 'compost:compost'} + } +}) + +minetest.register_craft({ + output = 'default:book', + recipe = { + {'default:book_written'} + } +}) + +minetest.register_craft({ + output = 'shields:shield_wood', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + {'', 'group:wood', ''} + } +}) + +minetest.register_craft({ + output = '3d_armor:helmet_wood', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', '', 'group:wood'}, + {'', '', ''}, + }, +}) +minetest.register_craft({ + output = '3d_armor:chestplate_wood', + recipe = { + {'group:wood', '', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', 'group:wood', 'group:wood'}, + }, +}) +minetest.register_craft({ + output = '3d_armor:leggings_wood', + recipe = { + {'group:wood', 'group:wood', 'group:wood'}, + {'group:wood', '', 'group:wood'}, + {'group:wood', '', 'group:wood'}, + }, +}) +minetest.register_craft({ + output = '3d_armor:boots_wood', + recipe = { + {'group:wood', '', 'group:wood'}, + {'group:wood', '', 'group:wood'}, + }, +}) + +minetest.register_craft({ + type = 'cooking', + output = 'epic:titanium_ingot', + recipe = 'epic:titanium_lump', + cooktime = 30 +}) + +minetest.register_craft({ + type = 'cooking', + output = 'epic:glowstone_fragment 2', + recipe = 'nether:glowstone', + cooktime = 30 +}) + +minetest.register_craft({ + output = 'epic:wood_ash 4', + recipe = {{'epic:tree_ash'}} +}) + +minetest.register_craft({ + type = 'cooking', + output = 'default:dry_dirt', + recipe = 'default:dirt', + cooktime = 2 +}) + +minetest.register_craft({ + type = 'cooking', + output = 'epic:scorched_dirt', + recipe = 'default:dry_dirt', + cooktime = 2 +}) + +minetest.register_craft({ + output = 'default:dirt_with_grass', + recipe = { + {'default:grass_1'}, + {'default:dirt'}, + }, +}) + +minetest.register_craft({ + output = 'default:dirt_with_dry_grass', + recipe = { + {'default:dry_grass_1'}, + {'default:dirt'}, + }, +}) + +minetest.register_craft({ + output = 'default:dirt_with_snow', + recipe = { + {'default:snow'}, + {'default:dirt'}, + }, +}) + +minetest.register_craft({ + output = 'default:dirt_with_snow', + recipe = { + {'trail:snow'}, + {'default:dirt'}, + }, +}) + +minetest.register_craft({ + output = 'default:dry_dirt_with_dry_grass', + recipe = { + {'default:dry_grass_1'}, + {'default:dry_dirt'}, + }, +}) + +minetest.register_craft({ + output = 'default:dirt_with_rainforest_litter', + recipe = { + {'default:junglegrass'}, + {'default:dirt'}, + }, +}) + +minetest.register_craft({ + output = 'moreblocks:super_glow_glass', + recipe = { + {'xdecor:candle', 'default:glass', 'xdecor:candle'}, + }, +}) + +minetest.register_craft({ + output = 'default:clay_lump', + recipe = { + {'darkage:silt_lump', 'darkage:mud_lump'}, + }, +}) + + +minetest.register_craft({ + output = 'epic:3brick_grass 2', + recipe = { + {'default:dirt_with_grass', ''}, + {'', 'default:stonebrick'} + }, +}) + +minetest.register_craft({ + output = 'epic:3grass_brick 2', + recipe = { + {'default:stonebrick', ''}, + {'', 'default:dirt_with_grass'} + }, +}) + +minetest.register_craft({ + output = 'epic:3dirt_cobble 2', + recipe = { + {'default:dirt', ''}, + {'', 'default:cobble'} + }, +}) + +minetest.register_craft({ + output = 'epic:3cobble_dirt 2', + recipe = { + {'default:cobble', ''}, + {'', 'default:dirt'} + }, +}) diff --git a/mods/epic/credits.txt b/mods/epic/credits.txt new file mode 100644 index 0000000..f9a8535 --- /dev/null +++ b/mods/epic/credits.txt @@ -0,0 +1,2 @@ +epic_deed.png from "Free Game Items Pack #1" Olga Bikmullina (http://ahninniah.graphics) Licensed under Creative Commons: By Attribution 3.0 http://creativecommons.org/licenses/by/3.0/ https://opengameart.org/content/free-game-items-pack-1 + diff --git a/mods/epic/death.lua b/mods/epic/death.lua new file mode 100644 index 0000000..de73147 --- /dev/null +++ b/mods/epic/death.lua @@ -0,0 +1,6 @@ +minetest.register_on_dieplayer(function(player) + local player_name = player:get_player_name() + local pos = player:getpos() + local location = minetest.pos_to_string(pos,1) + minetest.chat_send_player(player_name, "Your bones are waiting at "..location) +end) diff --git a/mods/epic/fireextinguisher.lua b/mods/epic/fireextinguisher.lua new file mode 100644 index 0000000..f79f415 --- /dev/null +++ b/mods/epic/fireextinguisher.lua @@ -0,0 +1,89 @@ +function epic.spray_foam(pos) + for z = -4,4 do + for y = -4,4 do + for x = -4,4 do + local p = {x=pos.x+x, y=pos.y+y, z=pos.z+z} + local nn = minetest.get_node(p).name + if nn == 'fire:basic_flame' then + minetest.set_node(p, {name='air'}) + minetest.sound_play('fire_extinguish_flame',{pos = p, max_hear_distance = 16, gain = 0.15}) + minetest.check_for_falling(p) + end + end + end + end +end + +local function throw_anti_fire_bomb(item, player) + local playerpos = player:get_pos() + local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.625,z=playerpos.z}, 'epic:anti_fire_entity') + local dir = player:get_look_dir() + obj:set_velocity({x=dir.x*30, y=dir.y*30, z=dir.z*30}) + obj:set_acceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3}) + item:take_item() + return item +end + +minetest.register_craftitem('epic:anti_fire_bomb', { + description = 'Anti fire bomb', + inventory_image = 'epic_anti_fire.png', + on_use = throw_anti_fire_bomb +}) + +minetest.register_node('epic:fire_extinguishing_powder', { + description = 'Anti fire powder', + drawtype = 'signlike', + tiles = {'epic_anti_fire_powder.png'}, + inventory_image = 'epic_anti_fire_powder.png', + wield_image = 'epic_anti_fire_powder.png', + paramtype = 'light', + paramtype2 = 'wallmounted', + sunlight_propagates = true, + selection_box = { + type = 'fixed', + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + collision_box = { + type = 'fixed', + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + groups = {dig_immediate = 3, attached_node = 1, flammable = 1}, + on_burn = function(pos) + epic.spray_foam(pos) + minetest.remove_node(pos) + end, + on_ignite = function(pos) + epic.spray_foam(pos) + minetest.remove_node(pos) + end, +}) + +minetest.register_craft({ + output = 'epic:anti_fire_bomb', + recipe = { + {'', 'epic:fire_extinguishing_powder', '',}, + {'epic:fire_extinguishing_powder', 'tnt:tnt_stick', 'epic:fire_extinguishing_powder',}, + {'', 'epic:fire_extinguishing_powder', '',} + } +}) + +minetest.register_entity('epic:anti_fire_entity', { + timer=0, + collisionbox = {0,0,0,0,0,0}, + physical = false, + textures = {'epic_anti_fire.png'}, + lastpos={}, + on_step = function(self, dtime) + self.timer = self.timer + dtime + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + if self.lastpos.x~=nil then + if node.name ~= 'air' then + self.object:remove() + epic.spray_foam(self.lastpos) + minetest.sound_play('tnt_explode', {pos = pos, max_hear_distance = 24, gain = 0.5}) + end + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end +}) diff --git a/mods/epic/functions.lua b/mods/epic/functions.lua new file mode 100644 index 0000000..526012a --- /dev/null +++ b/mods/epic/functions.lua @@ -0,0 +1,77 @@ +--Helper function to see if there is open space to place a double wide node. +--All wide nodes should extend to the right. +--Returns true if item should be placeable. + +--[[ +### Use this code on nodes that need to check space to side. + +after_place_node = function(pos, placer, itemstack) + if not epic.space_to_side(pos) then + minetest.remove_node(pos) + return itemstack + end +end, + +### Use this code on nodes that need to remove the empty node. + +after_dig_node = function(pos, oldnode) + epic.remove_side_node(pos, oldnode) +end, + +]] +fdir_table = { + { 1, 0 }, + { 0, -1 }, + { -1, 0 }, + { 0, 1 }, + { 1, 0 }, + { 0, -1 }, + { -1, 0 }, + { 0, 1 }, +} + +function epic.space_to_side(pos) + local node = minetest.get_node(pos) + local fdir = node.param2 % 32 + local pos2 = {x = pos.x + fdir_table[fdir+1][1], y=pos.y, z = pos.z + fdir_table[fdir+1][2]} + local node2 = minetest.get_node(pos2) + local node2def = minetest.registered_nodes[node2.name] or nil + if not node2def.buildable_to then + return false + else + minetest.set_node(pos2,{name = 'epic:empty'}) + return true + end +end + +function epic.remove_side_node(pos, oldnode) + local fdir = oldnode.param2 % 32 + local pos2 = {x = pos.x + fdir_table[fdir+1][1], y=pos.y, z = pos.z + fdir_table[fdir+1][2]} + local node2 = minetest.get_node(pos2) + if node2.name == 'epic:empty' then + minetest.remove_node(pos2) + end +end + +function epic.space_to_front(pos) + local node = minetest.get_node(pos) + local fdir = node.param2 % 32 + local pos2 = {x = pos.x + fdir_table[fdir+4][1], y=pos.y, z = pos.z + fdir_table[fdir+4][2]} + local node2 = minetest.get_node(pos2) + local node2def = minetest.registered_nodes[node2.name] or nil + if not node2def.buildable_to then + return false + else + minetest.set_node(pos2,{name = 'epic:empty'}) + return true + end +end + +function epic.remove_front_node(pos, oldnode) + local fdir = oldnode.param2 % 32 + local pos2 = {x = pos.x + fdir_table[fdir+4][1], y=pos.y, z = pos.z + fdir_table[fdir+4][2]} + local node2 = minetest.get_node(pos2) + if node2.name == 'epic:empty' then + minetest.remove_node(pos2) + end +end diff --git a/mods/epic/init.lua b/mods/epic/init.lua new file mode 100644 index 0000000..4d9f3a9 --- /dev/null +++ b/mods/epic/init.lua @@ -0,0 +1,30 @@ +epic = {} +dofile(minetest.get_modpath('epic')..'/armor.lua') +dofile(minetest.get_modpath('epic')..'/ABMs.lua') +dofile(minetest.get_modpath('epic')..'/awards.lua') +dofile(minetest.get_modpath('epic')..'/crafts.lua') +dofile(minetest.get_modpath('epic')..'/craftitems.lua') +dofile(minetest.get_modpath('epic')..'/death.lua') +dofile(minetest.get_modpath('epic')..'/fireextinguisher.lua') +dofile(minetest.get_modpath('epic')..'/functions.lua') +dofile(minetest.get_modpath('epic')..'/mapgen.lua') +dofile(minetest.get_modpath('epic')..'/nodes.lua') +dofile(minetest.get_modpath('epic')..'/particles.lua') +dofile(minetest.get_modpath('epic')..'/privs.lua') +dofile(minetest.get_modpath('epic')..'/signs.lua') +dofile(minetest.get_modpath('epic')..'/ocean_guard.lua') +dofile(minetest.get_modpath('epic')..'/overrides.lua') +dofile(minetest.get_modpath('epic')..'/snowball.lua') +dofile(minetest.get_modpath('epic')..'/teleport.lua') +dofile(minetest.get_modpath('epic')..'/tools.lua') +dofile(minetest.get_modpath('epic')..'/traps.lua') + + +--[[ +Actinolite(float_crystal), used for teleportation, and lower gravity armor +Bloodstone, used for healing potions/charms +Prismarine, used for underwater breathing +Obsidian, provides fire protection +Garnet, provides a boost of power, used for speed armor +Quartz, also provides power, used for jumping. +--]] diff --git a/mods/epic/license.txt b/mods/epic/license.txt new file mode 100644 index 0000000..5979467 --- /dev/null +++ b/mods/epic/license.txt @@ -0,0 +1,6 @@ +Code is licensed MIT, Textures CC by SA 4.0 +Copyright 2020 Nathan Salapat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/epic/mapgen.lua b/mods/epic/mapgen.lua new file mode 100644 index 0000000..397196f --- /dev/null +++ b/mods/epic/mapgen.lua @@ -0,0 +1,142 @@ +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:float_stone', + wherein = 'epic:stone', + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 2, + clust_size = 3, + y_min = 230, + y_max = 3100, +}) + +minetest.register_ore({ + ore_type = 'sheet', + ore = 'epic:stone_with_salt', + wherein = 'default:stone', + clust_size = 4, + y_min = -1000, + y_max = 300, + noise_params = {offset=0, scale=7, spread={x=250, y=250, z=250}, seed=23, octaves=6, persist=0.70} +}) + +minetest.register_ore({ + ore_type = 'sheet', + ore = 'epic:desert_stone_with_nitre', + wherein = 'default:desert_stone', + clust_size = 2, + y_min = -300, + y_max = 300, + noise_params = {offset=0, scale=7, spread={x=250, y=250, z=250}, seed=12, octaves=6, persist=0.70} +}) + +minetest.register_ore({ + ore_type = 'sheet', + ore = 'epic:mineral_sulfur', + wherein = 'default:stone', + clust_size = 2, + y_min = -6000, + y_max = -5000, + noise_params = {offset=0, scale=7, spread={x=250, y=250, z=250}, seed=5987347, octaves=6, persist=0.70} +}) + + +--Garnet +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:desert_garnet', + wherein = 'default:desert_stone', + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_min = -3000, + y_max = -200, +}) + +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:desert_garnet', + wherein = 'default:desert_stone', + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 5, + clust_size = 3, + y_min = -31000, + y_max = -3001, +}) + +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:stone_garnet', + wherein = 'default:stone', + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_min = -3000, + y_max = -200, +}) + +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:stone_garnet', + wherein = 'default:stone', + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 20, + clust_size = 6, + y_min = -31000, + y_max = -3001, +}) + +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:desert_stone_with_coal', + wherein = 'default:desert_stone', + clust_scarcity = 24 * 24 * 24, + clust_num_ores = 27, + clust_size = 6, + y_max = 0, + y_min = -31000, +}) + +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:desert_stone_with_iron', + wherein = 'default:desert_stone', + clust_scarcity = 7 * 7 * 7, + clust_num_ores = 5, + clust_size = 3, + y_max = 0, + y_min = -31000, +}) + +--Bloodstone +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:bloodstone_ore', + wherein = 'default:stone', + clust_scarcity = 17 * 17 * 17, + clust_num_ores = 4, + clust_size = 3, + y_min = -4000, + y_max = -200, +}) + +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:bloodstone_ore', + wherein = 'default:stone', + clust_scarcity = 12 * 12 * 12, + clust_num_ores = 18, + clust_size = 5, + y_min = -31000, + y_max = -4001, +}) + +minetest.register_ore({ + ore_type = 'scatter', + ore = 'epic:metal_lead', + wherein = 'default:stone', + clust_scarcity = 10 * 10 * 10, + clust_num_ores = 5, + clust_size = 3, + y_max = -100, + y_min = -5000, +}) diff --git a/mods/epic/mod.conf b/mods/epic/mod.conf new file mode 100644 index 0000000..079de90 --- /dev/null +++ b/mods/epic/mod.conf @@ -0,0 +1,2 @@ +name = epic +depends = default, commoditymarket, mobs_monster, farming, 3d_armor, shields, mobs, awards, carts, unified_inventory, bonemeal, moreblocks diff --git a/mods/epic/models/epic_directional_sign.obj b/mods/epic/models/epic_directional_sign.obj new file mode 100644 index 0000000..3f4bfff --- /dev/null +++ b/mods/epic/models/epic_directional_sign.obj @@ -0,0 +1,83 @@ +# Blender v2.82 (sub 7) OBJ File: 'Epic.blend' +# www.blender.org +o Sign_directional_Cube.003 +v -0.312500 0.000000 -0.062500 +v -0.312500 0.312500 -0.062500 +v -0.312500 0.000000 -0.000000 +v -0.312500 0.312500 -0.000000 +v 0.375000 0.000000 -0.062500 +v 0.375000 0.312500 -0.062500 +v 0.375000 0.000000 0.000000 +v 0.375000 0.312500 0.000000 +v -0.437500 0.125000 -0.000000 +v -0.437500 0.125000 -0.062500 +v -0.437500 0.187500 -0.062500 +v -0.437500 0.187500 -0.000000 +v 0.062500 0.375000 0.125000 +v 0.062500 -0.500000 0.125000 +v 0.062500 0.375000 0.000000 +v 0.062500 -0.500000 0.000000 +v -0.062500 -0.500000 0.000000 +v -0.062500 0.375000 0.000000 +v -0.062500 -0.500000 0.125000 +v -0.062500 0.375000 0.125000 +vt 0.562500 0.906250 +vt 0.687500 0.781250 +vt 0.687500 0.718750 +vt 0.562500 0.593750 +vt 0.093750 0.593750 +vt 0.093750 0.906250 +vt 0.031250 0.593750 +vt 0.031250 0.906250 +vt 0.093750 0.593750 +vt 0.562500 0.593750 +vt 0.562500 0.906250 +vt 0.093750 0.906250 +vt 0.562500 0.531250 +vt 0.093750 0.531250 +vt 0.093750 0.968750 +vt 0.562500 0.968750 +vt 0.687500 0.718750 +vt 0.750000 0.718750 +vt 0.750000 0.781250 +vt 0.687500 0.781250 +vt 0.687500 0.968750 +vt 0.687500 0.906250 +vt 0.687500 0.531250 +vt 0.687500 0.593750 +vt 0.999929 0.375018 +vt 0.125053 0.375018 +vt 0.125053 0.250035 +vt 0.999929 0.250036 +vt 0.125053 0.125053 +vt 0.999929 0.125054 +vt 0.125053 0.000071 +vt 0.999929 0.000071 +vt 0.999929 0.500000 +vt 0.125053 0.500000 +vt 0.000071 0.500000 +vt 0.000071 0.375018 +vn -0.0000 0.0000 1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn -0.7071 0.7071 0.0000 +vn -0.7071 -0.7071 0.0000 +s off +f 4/1/1 12/2/1 9/3/1 3/4/1 +f 3/4/1 7/5/1 8/6/1 4/1/1 +f 7/5/2 5/7/2 6/8/2 8/6/2 +f 5/9/3 1/10/3 2/11/3 6/12/3 +f 3/13/4 1/10/4 5/9/4 7/14/4 +f 8/6/5 6/15/5 2/16/5 4/1/5 +f 10/17/6 9/18/6 12/19/6 11/20/6 +f 1/10/3 10/17/3 11/20/3 2/11/3 +f 2/16/7 11/21/7 12/22/7 4/1/7 +f 3/13/8 9/23/8 10/24/8 1/10/8 +f 16/25/2 15/26/2 13/27/2 14/28/2 +f 14/28/1 13/27/1 20/29/1 19/30/1 +f 19/30/6 20/29/6 18/31/6 17/32/6 +f 17/33/3 18/34/3 15/26/3 16/25/3 +f 20/35/5 13/36/5 15/26/5 18/34/5 diff --git a/mods/epic/models/epic_guardians.b3d b/mods/epic/models/epic_guardians.b3d new file mode 100644 index 0000000..3b8419a Binary files /dev/null and b/mods/epic/models/epic_guardians.b3d differ diff --git a/mods/epic/models/epic_hanging_sign.obj b/mods/epic/models/epic_hanging_sign.obj new file mode 100644 index 0000000..5067acf --- /dev/null +++ b/mods/epic/models/epic_hanging_sign.obj @@ -0,0 +1,100 @@ +# Blender v2.82 (sub 7) OBJ File: 'Epic.blend' +# www.blender.org +o Hanging_Sign_Cube +v -0.437500 -0.312500 -0.062500 +v -0.437500 0.375000 -0.062500 +v 0.437500 -0.312500 -0.062500 +v 0.437500 0.375000 -0.062500 +v -0.437500 -0.312500 0.062500 +v -0.437500 0.375000 0.062500 +v 0.437500 -0.312500 0.062500 +v 0.437500 0.375000 0.062500 +v 0.312500 -0.437500 -0.062500 +v -0.312500 -0.437500 -0.062500 +v 0.312500 -0.437500 0.062500 +v -0.312500 -0.437500 0.062500 +v -0.343750 0.375000 -0.031250 +v -0.343750 0.625000 -0.031250 +v -0.281250 0.375000 -0.031250 +v -0.281250 0.625000 -0.031250 +v -0.343750 0.375000 0.031250 +v -0.343750 0.625000 0.031250 +v -0.281250 0.375000 0.031250 +v -0.281250 0.625000 0.031250 +v 0.343750 0.625000 0.031250 +v 0.343750 0.375000 0.031250 +v 0.281250 0.625000 0.031250 +v 0.281250 0.375000 0.031250 +v 0.343750 0.625000 -0.031250 +v 0.343750 0.375000 -0.031250 +v 0.281250 0.625000 -0.031250 +v 0.281250 0.375000 -0.031250 +vt 0.562500 0.515625 +vt 0.562500 0.859375 +vt 1.000000 0.859375 +vt 1.000000 0.515625 +vt 0.000000 0.515625 +vt 0.000000 0.859375 +vt 0.062500 0.859375 +vt 0.062500 0.515625 +vt 0.500000 0.859375 +vt 0.500000 0.515625 +vt 0.937500 0.453125 +vt 0.625000 0.453125 +vt 1.000000 0.921875 +vt 0.562500 0.921875 +vt 0.937500 0.390625 +vt 0.625000 0.390625 +vt 0.437500 0.453125 +vt 0.125000 0.453125 +vt 0.562500 0.453125 +vt 0.500000 0.453125 +vt 0.062500 0.453125 +vt 0.000000 0.453125 +vt 0.125000 0.875000 +vt 0.250000 0.875000 +vt 0.250000 0.906250 +vt 0.125000 0.906250 +vt 0.250000 0.937500 +vt 0.125000 0.937500 +vt 0.250000 0.968750 +vt 0.125000 0.968750 +vt 0.250000 1.000000 +vt 0.125000 1.000000 +vt 0.125000 0.968750 +vt 0.000000 0.968750 +vt 0.000000 0.937500 +vt 0.125000 0.937500 +vt 0.125000 0.906250 +vt 0.000000 0.906250 +vt 0.000000 0.875000 +vt 0.125000 0.875000 +vt 0.125000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn -0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn -0.7071 -0.7071 0.0000 +vn 0.7071 -0.7071 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 7/8/3 8/7/3 6/9/3 5/10/3 +f 5/10/4 6/9/4 2/2/4 1/1/4 +f 1/1/1 3/4/1 9/11/1 10/12/1 +f 8/13/5 4/3/5 2/2/5 6/14/5 +f 9/11/6 11/15/6 12/16/6 10/12/6 +f 7/8/3 5/10/3 12/17/3 11/18/3 +f 5/10/7 1/1/7 10/19/7 12/20/7 +f 3/5/8 7/8/8 11/21/8 9/22/8 +f 13/23/1 14/24/1 16/25/1 15/26/1 +f 15/26/2 16/25/2 20/27/2 19/28/2 +f 19/28/3 20/27/3 18/29/3 17/30/3 +f 17/30/4 18/29/4 14/31/4 13/32/4 +f 26/33/2 25/34/2 21/35/2 22/36/2 +f 24/37/4 23/38/4 27/39/4 28/40/4 +f 28/41/1 27/42/1 25/34/1 26/33/1 +f 22/36/3 21/35/3 23/38/3 24/37/3 diff --git a/mods/epic/models/epic_sign_post.obj b/mods/epic/models/epic_sign_post.obj new file mode 100644 index 0000000..2fc3704 --- /dev/null +++ b/mods/epic/models/epic_sign_post.obj @@ -0,0 +1,80 @@ +# Blender v2.82 (sub 7) OBJ File: 'Epic.blend' +# www.blender.org +o Sign_Post_Cube.002 +v -0.125000 -0.437500 -0.500000 +v -0.125000 -0.250000 -0.500000 +v 0.125000 -0.437500 -0.500000 +v 0.125000 -0.250000 -0.500000 +v -0.125000 -0.437500 0.500000 +v -0.125000 -0.250000 0.500000 +v 0.125000 -0.437500 0.500000 +v 0.125000 -0.250000 0.500000 +v -0.125000 -0.250000 0.437500 +v -0.125000 0.375000 0.437500 +v 0.125000 -0.250000 0.437500 +v 0.125000 0.375000 0.437500 +v -0.125000 -0.250000 0.500000 +v -0.125000 0.375000 0.500000 +v 0.125000 -0.250000 0.500000 +v 0.125000 0.375000 0.500000 +v -0.031250 -0.343750 -0.437500 +v -0.031250 -0.281250 -0.437500 +v 0.031250 -0.343750 -0.437500 +v 0.031250 -0.281250 -0.437500 +v -0.031250 0.218750 0.437500 +v -0.031250 0.281250 0.437500 +v 0.031250 0.218750 0.437500 +v 0.031250 0.281250 0.437500 +vt 0.500000 0.875000 +vt 0.500000 0.968750 +vt 0.375000 0.968750 +vt 0.375000 0.875000 +vt 0.500000 0.750000 +vt 0.500000 0.656250 +vt 1.000000 0.656250 +vt 1.000000 0.750000 +vt 1.000000 0.875000 +vt 1.000000 0.968750 +vt 0.500000 0.531250 +vt 1.000000 0.531250 +vt 0.343750 0.953125 +vt 0.031250 0.953125 +vt 0.031250 0.828125 +vt 0.343750 0.828125 +vt 0.031250 0.796875 +vt 0.343750 0.796875 +vt 0.343750 0.984375 +vt 0.031250 0.984375 +vt 0.000000 0.828125 +vt 0.000000 0.953125 +vt 0.453125 0.687500 +vt 0.453125 0.718750 +vt 0.015625 0.718750 +vt 0.015625 0.687500 +vt 0.015625 0.656250 +vt 0.015625 0.625000 +vt 0.453125 0.625000 +vt 0.453125 0.656250 +vt 0.453125 0.750000 +vt 0.015625 0.750000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn -1.0000 0.0000 -0.0000 +vn 0.0000 -1.0000 -0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -0.8412 0.5408 +vn 0.0000 0.8412 -0.5408 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 5/9/3 6/10/3 2/2/3 1/1/3 +f 3/5/4 7/8/4 5/9/4 1/1/4 +f 8/7/5 4/6/5 2/11/5 6/12/5 +f 9/13/1 10/14/1 12/15/1 11/16/1 +f 11/16/2 12/15/2 16/17/2 15/18/2 +f 13/19/3 14/20/3 10/14/3 9/13/3 +f 16/21/5 12/15/5 10/14/5 14/22/5 +f 19/23/2 20/24/2 24/25/2 23/26/2 +f 21/27/3 22/28/3 18/29/3 17/30/3 +f 19/23/6 23/26/6 21/27/6 17/30/6 +f 24/25/7 20/24/7 18/31/7 22/32/7 diff --git a/mods/epic/models/epic_triangle.obj b/mods/epic/models/epic_triangle.obj new file mode 100644 index 0000000..8014694 --- /dev/null +++ b/mods/epic/models/epic_triangle.obj @@ -0,0 +1,46 @@ +# Blender v2.82 (sub 7) OBJ File: '' +# www.blender.org +o Cube.001_Cube +v -0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.999900 0.000100 +vt 0.999900 0.999900 +vt 0.000100 0.999900 +vt 0.000100 0.000100 +vt 0.999900 0.000100 +vt 0.999900 0.999900 +vt 0.000100 0.999900 +vt 0.000100 0.000100 +vt 0.999900 0.000100 +vt 0.999900 0.999900 +vt 0.000100 0.999900 +vt 0.000100 0.000100 +vt 0.999900 0.000100 +vt 0.999900 0.999900 +vt 0.000100 0.999900 +vt 0.000100 0.000100 +vn 0.0000 1.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +g Cube.001_Cube_Top1 +s off +f 4/1/1 2/2/1 8/3/1 +g Cube.001_Cube_Top2 +f 8/3/1 2/2/1 6/4/1 +g Cube.001_Cube_Sides +f 1/5/2 2/6/2 4/7/2 3/8/2 +f 3/9/3 4/10/3 8/11/3 7/12/3 +f 7/13/4 8/14/4 6/15/4 5/16/4 +f 5/17/5 6/18/5 2/19/5 1/20/5 diff --git a/mods/epic/models/epic_well_bottom.obj b/mods/epic/models/epic_well_bottom.obj new file mode 100644 index 0000000..07007fb --- /dev/null +++ b/mods/epic/models/epic_well_bottom.obj @@ -0,0 +1,125 @@ +# Blender v2.74 (sub 4) OBJ File: '' +# www.blender.org +o Circle_Circle.001 +v 0.000000 0.283161 -0.634972 +v -0.448993 0.283161 -0.448993 +v -0.634972 0.283161 0.000000 +v -0.448993 0.283161 0.448993 +v 0.000000 0.283161 0.634972 +v 0.448993 0.283161 0.448993 +v 0.634972 0.283161 -0.000000 +v 0.448993 0.283161 -0.448993 +v 0.000000 0.283161 -0.468916 +v -0.331573 0.283161 -0.331573 +v -0.468916 0.283161 0.000000 +v -0.331573 0.283161 0.331573 +v 0.000000 0.283161 0.468916 +v 0.331574 0.283161 0.331573 +v 0.468916 0.283161 -0.000000 +v 0.331574 0.283161 -0.331573 +v 0.000000 -0.500000 -0.634972 +v -0.448993 -0.500000 -0.448993 +v -0.634972 -0.500000 0.000000 +v -0.448993 -0.500000 0.448993 +v 0.000000 -0.500000 0.634972 +v 0.448993 -0.500000 0.448993 +v 0.634972 -0.500000 -0.000000 +v 0.448993 -0.500000 -0.448993 +v 0.000000 -0.500000 -0.468916 +v -0.331573 -0.500000 -0.331573 +v -0.468916 -0.500000 0.000000 +v -0.331573 -0.500000 0.331573 +v 0.000000 -0.500000 0.468916 +v 0.331574 -0.500000 0.331573 +v 0.468916 -0.500000 -0.000000 +v 0.331574 -0.500000 -0.331573 +vt -0.608080 0.074124 +vt -0.327469 0.190357 +vt -0.327470 0.846802 +vt -0.608081 0.963035 +vt 0.020474 1.591590 +vt 0.136707 1.310979 +vt 0.793152 1.310979 +vt 0.909385 1.591590 +vt 1.257329 0.846802 +vt 1.537940 0.963035 +vt 1.537940 0.074125 +vt 1.257329 0.190357 +vt 0.793153 -0.273820 +vt 0.909385 -0.554430 +vt 0.020475 -0.554430 +vt 0.136707 -0.273820 +vt 0.515697 1.565113 +vt 0.025118 1.565113 +vt 0.025118 0.494591 +vt 0.515697 0.494591 +vt -0.814013 0.503505 +vt -0.155051 0.503733 +vt -0.155418 1.565641 +vt -0.814379 1.565413 +vt -0.465460 1.565113 +vt -0.465460 0.494591 +vt 1.162871 -0.559966 +vt 1.821833 -0.559966 +vt 1.821833 0.501942 +vt 1.162871 0.501942 +vt 1.496855 0.493016 +vt 1.006276 0.493016 +vt 1.006276 -0.577506 +vt 1.496855 -0.577506 +vt 0.503910 -0.559966 +vt 0.503910 0.501942 +vt 0.515697 0.493016 +vt 0.515697 -0.577506 +vt -0.155051 -0.559966 +vt -0.155051 0.501942 +vt 0.025118 0.493016 +vt 0.025119 -0.577506 +vt -0.814013 -0.559966 +vt -0.814013 0.501942 +vt 1.162872 0.504188 +vt 1.821833 0.504415 +vt 1.821467 1.566324 +vt 1.162505 1.566096 +vt -0.465460 0.493016 +vt -0.465460 -0.577506 +vt 1.496855 1.565113 +vt 1.006276 1.565113 +vt 1.006276 0.494591 +vt 1.496855 0.494591 +vt 0.503910 0.503960 +vt 0.503544 1.565869 +vn 0.000000 1.000000 0.000000 +vn 0.923900 0.000000 -0.382700 +vn -0.382700 0.000000 0.923900 +vn 0.382700 0.000000 -0.923900 +vn 0.382700 0.000000 0.923900 +vn -0.382700 0.000000 -0.923900 +vn 0.923900 0.000000 0.382700 +vn -0.923900 0.000000 -0.382700 +vn -0.923900 0.000000 0.382700 +s off +f 4/1/1 12/2/1 11/3/1 3/4/1 +f 2/5/1 10/6/1 9/7/1 1/8/1 +f 1/8/1 9/7/1 16/9/1 8/10/1 +f 7/11/1 15/12/1 14/13/1 6/14/1 +f 5/15/1 13/16/1 12/2/1 4/1/1 +f 3/4/1 11/3/1 10/6/1 2/5/1 +f 8/10/1 16/9/1 15/12/1 7/11/1 +f 6/14/1 14/13/1 13/16/1 5/15/1 +f 11/17/2 12/18/2 28/19/2 27/20/2 +f 5/21/3 4/22/3 20/23/3 21/24/3 +f 12/18/4 13/25/4 29/26/4 28/19/4 +f 6/27/5 5/28/5 21/29/5 22/30/5 +f 13/31/6 14/32/6 30/33/6 29/34/6 +f 7/35/7 6/27/7 22/30/7 23/36/7 +f 14/32/8 15/37/8 31/38/8 30/33/8 +f 8/39/2 7/35/2 23/36/2 24/40/2 +f 15/37/9 16/41/9 32/42/9 31/38/9 +f 1/43/4 8/39/4 24/40/4 17/44/4 +f 2/45/6 1/46/6 17/47/6 18/48/6 +f 16/41/3 9/49/3 25/50/3 32/42/3 +f 9/51/5 10/52/5 26/53/5 25/54/5 +f 3/55/8 2/45/8 18/48/8 19/56/8 +f 10/52/7 11/17/7 27/20/7 26/53/7 +f 4/22/9 3/55/9 19/56/9 20/23/9 diff --git a/mods/epic/models/epic_well_top.obj b/mods/epic/models/epic_well_top.obj new file mode 100644 index 0000000..222762b --- /dev/null +++ b/mods/epic/models/epic_well_top.obj @@ -0,0 +1,124 @@ +# Blender v2.74 (sub 4) OBJ File: '' +# www.blender.org +o Plane +v -0.594368 -0.025786 0.594368 +v 0.594368 -0.025786 0.594368 +v -0.594368 -0.025786 -0.594368 +v 0.594368 -0.025786 -0.594368 +v -0.594368 0.213800 -0.110024 +v -0.594368 0.213800 0.110024 +v 0.594368 0.213800 0.110024 +v 0.594368 0.213800 -0.110024 +v -0.594368 0.074214 0.594368 +v 0.594368 0.074214 0.594368 +v -0.594368 0.074214 -0.594368 +v 0.594368 0.074214 -0.594368 +v -0.594368 0.395477 -0.037573 +v -0.594368 0.395477 0.037573 +v 0.594368 0.395477 0.037573 +v 0.594368 0.395477 -0.037573 +v 0.580392 -0.716775 -0.100000 +v 0.580392 0.207742 -0.100000 +v 0.580392 -0.716775 0.100000 +v 0.580392 0.207742 0.100000 +v 0.484193 -0.716775 -0.100000 +v 0.484193 0.207742 -0.100000 +v 0.484193 -0.716775 0.100000 +v 0.484193 0.207742 0.100000 +v -0.580392 -0.716775 0.100000 +v -0.580392 0.207742 0.100000 +v -0.580392 -0.716775 -0.100000 +v -0.580392 0.207742 -0.100000 +v -0.484193 -0.716775 0.100000 +v -0.484193 0.207742 0.100000 +v -0.484193 -0.716775 -0.100000 +v -0.484193 0.207742 -0.100000 +vt -2.037692 -0.642955 +vt -2.037691 -1.795974 +vt 0.498825 -1.795974 +vt 0.498825 -0.642955 +vt -2.037692 0.979602 +vt -2.037692 -0.173418 +vt 0.498825 -0.173417 +vt 0.498825 0.979602 +vt -0.828274 0.554469 +vt 1.708243 0.554469 +vt 1.708243 1.926136 +vt -0.828275 1.926135 +vt -0.828275 -0.977544 +vt 1.708243 -0.977544 +vt 1.708243 0.394122 +vt -0.828274 0.394123 +vt 0.533815 0.318514 +vt 0.533815 0.838637 +vt 0.104389 0.667386 +vt 0.104389 0.489764 +vt -2.037692 -2.009354 +vt 0.498825 -2.009355 +vt 0.498825 1.192981 +vt -2.037692 1.192983 +vt -0.160681 2.007526 +vt 0.422098 0.829388 +vt 0.864017 0.653155 +vt 0.082564 2.007526 +vt 1.100118 -0.826317 +vt 0.863751 -0.826317 +vt 0.422098 0.294133 +vt -0.160680 -0.884004 +vt 0.082565 -0.884004 +vt 0.864017 0.470366 +vt 1.100117 1.983467 +vt 0.863749 1.983467 +vt -0.630533 1.126091 +vt -0.630534 0.699332 +vt 1.342194 0.699332 +vt 1.342194 1.126091 +vt -0.630534 0.494062 +vt 1.342194 0.494062 +vt -0.630534 0.067303 +vt 1.342194 0.067302 +vt -0.630534 -0.137967 +vt 1.342194 -0.137967 +vt -0.468279 1.205461 +vt -0.468279 0.778702 +vt 1.504448 0.778702 +vt 1.504449 1.205460 +vt -0.468279 0.573432 +vt 1.504448 0.573432 +vt -0.468279 0.146673 +vt 1.504448 0.146673 +vt -0.468279 -0.058597 +vt 1.504448 -0.058597 +vn 0.000000 -0.896300 0.443400 +vn 0.000000 -0.896300 -0.443400 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 0.866200 -0.499800 +vn 0.000000 0.866200 0.499800 +vn 0.000000 1.000000 0.000000 +vn -1.000000 -0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 0.000000 1.000000 +vn 1.000000 -0.000000 0.000000 +s off +f 5/1/1 3/2/1 4/3/1 8/4/1 +f 1/5/2 6/6/2 7/7/2 2/8/2 +f 6/6/3 5/1/3 8/4/3 7/7/3 +f 13/9/4 16/10/4 12/11/4 11/12/4 +f 9/13/5 10/14/5 15/15/5 14/16/5 +f 14/16/6 15/15/6 16/10/6 13/9/6 +f 5/17/7 6/18/7 14/19/7 13/20/7 +f 4/3/8 3/2/8 11/21/8 12/22/8 +f 1/5/9 2/8/9 10/23/9 9/24/9 +f 2/25/10 7/26/10 15/27/10 10/28/10 +f 3/29/7 5/17/7 13/20/7 11/30/7 +f 8/31/10 4/32/10 12/33/10 16/34/10 +f 6/18/7 1/35/7 9/36/7 14/19/7 +f 7/26/10 8/31/10 16/34/10 15/27/10 +f 18/37/10 20/38/10 19/39/10 17/40/10 +f 20/38/9 24/41/9 23/42/9 19/39/9 +f 24/41/7 22/43/7 21/44/7 23/42/7 +f 22/43/8 18/45/8 17/46/8 21/44/8 +f 26/47/7 28/48/7 27/49/7 25/50/7 +f 28/48/8 32/51/8 31/52/8 27/49/8 +f 32/51/10 30/53/10 29/54/10 31/52/10 +f 30/53/9 26/55/9 25/56/9 29/54/9 diff --git a/mods/epic/nodes.lua b/mods/epic/nodes.lua new file mode 100644 index 0000000..a6f032a --- /dev/null +++ b/mods/epic/nodes.lua @@ -0,0 +1,427 @@ +minetest.register_node('epic:stone', { + description = 'Stone', + tiles = {'default_stone.png'}, + groups = {cracky = 2, stone = 1}, + drop = { + max_items = 2, + items = { + {items = {'epic:float_crystal_shard'}, rarity = 50,}, + {items = {'default:cobble'}}, + } + }, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node('epic:border', { + description = 'Invisible Border', + drawtype = 'airlike', + paramtype = 'light', + pointable = false, + groups = {not_in_creative_inventory=1}, +}) + +minetest.register_node('epic:float_stone', { + description = 'Actinolite', + light_source = 3, + tiles = {'epic_actinolite_top.png', 'default_stone.png', 'epic_actinolite_side.png'}, + groups = {cracky = 2, stone = 1, level = 4}, + drop = 'epic:float_crystal 4', + sounds = default.node_sound_stone_defaults(), + on_timer = function(pos) + local new_pos = ({x=pos.x, y=pos.y+1, z=pos.z}) + local abovenode = minetest.get_node(new_pos).name + if abovenode == 'air' then + minetest.set_node(new_pos, {name='epic:float_stone'}) + minetest.set_node(pos, {name='air'}) + local timer = minetest.get_node_timer(new_pos) + timer:start(1) + end + end, +}) + +minetest.register_node('epic:floating_base', { + description = 'Laputa', + light_source = 1, + tiles = {'epic_laputa.png'}, + groups = {cracky = 2, stone = 1, level = 3, not_in_creative_inventory=1}, + drop = { + max_items = 3, + items = { + {items = {'epic:float_crystal 2'}, rarity = 1}, + {items = {'epic:float_crystal 3'}, rarity = 3}, + {items = {'default:diamond 4'}, rarity = 1}, + {items = {'default:diamond 5'}, rarity = 3}, + {items = {'default:mese_crystal 4'}, rarity = 1}, + {items = {'default:mese_crystal 5'}, rarity = 3}, + }, + }, + sounds = default.node_sound_stone_defaults(), + on_timer = function(pos) + local new_pos = ({x=pos.x, y=pos.y+1, z=pos.z}) + local abovenode = minetest.get_node(new_pos).name + if abovenode == 'air' then + minetest.set_node(new_pos, {name='epic:floating_base'}) + minetest.set_node(pos, {name='air'}) + local timer = minetest.get_node_timer(new_pos) + timer:start(10) + end + end, + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(30) + end, +}) + +minetest.register_node('epic:stone_with_titanium', { + description = 'Nether rack with titanium', + tiles = {'nether_rack.png^epic_titanium_ore.png'}, + groups = {cracky = 1, stone = 1}, + drop = 'epic:titanium_lump', + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node('epic:tree_ash', { + description = 'Burnt tree', + paramtype2 = 'facedir', + tiles = {'epic_tree_ash_top.png', 'epic_tree_ash_top.png', 'epic_tree_ash_side.png'}, + groups = {choppy = 3, oddly_breakable_by_hand = 3}, + on_place = minetest.rotate_node +}) + +minetest.register_node('epic:wood_ash', { + description = 'Burnt wood', + tiles = {'epic_wood_ash.png'}, + groups = {choppy = 3, oddly_breakable_by_hand = 3}, +}) + +minetest.register_node('epic:scorched_dirt', { + description = 'Scorched dirt', + tiles = {{name='epic_scorched_dirt.png', align_style='world', scale=4}}, + inventory_image = '[inventorycube{epic_scorched_dirt.png&[sheet:4x4:1,1{epic_scorched_dirt.png&[sheet:4x4:1,1{epic_scorched_dirt.png&[sheet:4x4:1,1', + groups = {crumbly = 3}, +}) + +minetest.register_node('epic:stone_with_salt', { + description = 'Salt crystals', + tiles = {'default_stone.png^epic_salt_ore.png'}, + is_ground_content = true, + sounds = default.node_sound_stone_defaults(), + drop = 'epic:salt_lump', + groups = {cracky = 3}, +}) + +minetest.register_node('epic:desert_stone_with_nitre', { + description = 'Nitre ore', + tiles = {'default_desert_stone.png^epic_nitre_ore.png'}, + is_ground_content = true, + sounds = default.node_sound_stone_defaults(), + drop = 'epic:potassium_nitrate', + groups = {cracky = 2}, +}) + +minetest.register_node('epic:mineral_sulfur', { + description = 'Sulfur Ore', + tiles = {'default_stone.png^epic_mineral_sulfur.png'}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_stone_defaults(), + drop = 'epic:sulfur_lump', +}) + +minetest.register_node('epic:metal_lead', { + description = 'Lead Ore', + tiles = {'default_stone.png^epic_metal_lead.png'}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_stone_defaults(), + drop = 'epic:lead_lump', +}) + +minetest.register_node('epic:desert_garnet', { + description = 'Garnet crystal', + tiles = {'default_desert_stone.png^epic_garnet_ore.png'}, + is_ground_content = true, + sounds = default.node_sound_stone_defaults(), + drop = 'epic:garnet', + groups = {cracky = 1, level = 2}, +}) + +minetest.register_node('epic:stone_garnet', { + description = 'Garnet crystal', + tiles = {'default_stone.png^epic_garnet_ore.png'}, + is_ground_content = true, + sounds = default.node_sound_stone_defaults(), + drop = 'epic:garnet', + groups = {cracky = 1, level = 2}, +}) + +minetest.register_node('epic:desert_stone_with_coal', { + description = 'Coal Ore', + tiles = {'default_desert_stone.png^default_mineral_coal.png'}, + groups = {cracky = 3}, + drop = 'default:coal_lump', + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node('epic:desert_stone_with_iron', { + description = 'Iron Ore', + tiles = {'default_desert_stone.png^default_mineral_iron.png'}, + groups = {cracky = 2}, + drop = 'default:iron_lump', + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node('epic:bloodstone_ore', { + description = 'Bloodstone Ore', + tiles = {'default_stone.png^epic_bloodstone_ore.png'}, + is_ground_content = true, + sounds = default.node_sound_stone_defaults(), + drop = 'epic:bloodstone', + groups = {cracky = 2, level = 2}, +}) + +minetest.register_node('epic:3grass_brick', { + description = 'Grass with Stone Brick', + drawtype = 'mesh', + mesh = 'epic_triangle.obj', + tiles = {'default_stone_brick.png', 'default_grass.png', 'default_dirt.png^default_grass_side.png'}, + paramtype = 'light', + paramtype2 = 'facedir', + groups = {cracky = 2, crumbly = 2}, +}) + +minetest.register_node('epic:3brick_grass', { + description = 'Stone Brick with Grass', + drawtype = 'mesh', + mesh = 'epic_triangle.obj', + tiles = {'default_grass.png', 'default_stone_brick.png', 'default_dirt.png^default_grass_side.png'}, + paramtype = 'light', + paramtype2 = 'facedir', + groups = {cracky = 2, crumbly = 2}, +}) + +minetest.register_node('epic:3dirt_cobble', { + description = 'Dirt with Cobble', + drawtype = 'mesh', + mesh = 'epic_triangle.obj', + tiles = {'default_dirt.png', 'default_cobble.png', 'default_dirt.png'}, + paramtype = 'light', + paramtype2 = 'facedir', + groups = {cracky = 2, crumbly = 2}, +}) + +minetest.register_node('epic:3cobble_dirt', { + description = 'Cobble with Dirt', + drawtype = 'mesh', + mesh = 'epic_triangle.obj', + tiles = {'default_cobble.png', 'default_dirt.png', 'default_dirt.png'}, + paramtype = 'light', + paramtype2 = 'facedir', + groups = {cracky = 2, crumbly = 2}, +}) + +minetest.register_node('epic:poison', { + description = 'Animal poison', + drawtype = 'signlike', + tiles = {'epic_animal_poison.png'}, + inventory_image = 'epic_animal_poison.png', + wield_image = 'epic_animal_poison.png', + paramtype = 'light', + paramtype2 = 'wallmounted', + sunlight_propagates = true, + selection_box = { + type = 'fixed', + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + collision_box = { + type = 'fixed', + fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2}, + }, + groups = {dig_immediate = 3, attached_node = 1}, +}) + +local function flood_flame(pos, oldnode, newnode) + -- Play flame extinguish sound if liquid is not an 'igniter' + local nodedef = minetest.registered_items[newnode.name] + if not (nodedef and nodedef.groups and + nodedef.groups.igniter and nodedef.groups.igniter > 0) then + minetest.sound_play('fire_extinguish_flame', + {pos = pos, max_hear_distance = 16, gain = 0.15}) + end + -- Remove the flame + return false +end + +minetest.register_node('epic:permanent_flame', { + description = 'Permanent Flame', + drawtype = 'firelike', + tiles = { + { + name = 'fire_basic_flame_animated.png', + animation = { + type = 'vertical_frames', + aspect_w = 16, + aspect_h = 16, + length = 1 + }, + }, + }, + inventory_image = 'fire_basic_flame.png', + paramtype = 'light', + light_source = 13, + walkable = false, + buildable_to = true, + sunlight_propagates = true, + floodable = true, + damage_per_second = 4, + groups = {dig_immediate = 3}, + drop = '', + + on_flood = flood_flame, +}) + +minetest.register_node('epic:empty', { + description = 'empty node :P', + drawtype = 'airlike', + paramtype = 'light', + walkable = true, + pointable = false, + diggable = false, + drop = '', + groups = {not_in_creative_inventory = 1}, + on_blast = function() end, + tiles = {'epic_blank.png'}, + node_box = { + type = 'fixed', + fixed = {-15/32, 13/32, -15/32, -13/32, 1/2, -13/32} + }, +}) + +minetest.register_node('epic:acacia_bark', { + description = 'Acacia bark', + tiles = {'default_acacia_tree.png'}, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node('epic:aspen_bark', { + description = 'Aspen bark', + tiles = {'default_aspen_tree.png'}, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node('epic:jungle_bark', { + description = 'Jungle bark', + tiles = {'default_jungletree.png'}, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node('epic:pine_bark', { + description = 'Pine bark', + tiles = {'default_pine_tree.png'}, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_node('epic:tree_bark', { + description = 'Tree bark', + tiles = {'default_tree.png'}, + groups = {tree = 1, choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), +}) + +stairsplus:register_all('epic', 'burnt_wood', 'epic:wood_ash', { + description='Burnt Wood', + groups = {choppy = 3, oddly_breakable_by_hand = 3, not_in_creative_inventory=1}, + tiles={'epic_wood_ash.png'}, +}) + +stairsplus:register_all('ocean', 'prismarine', 'ocean:prismarine', { + description='Prismarine', + groups={cracky=1, not_in_creative_inventory=1}, + tiles={'prismarine.png'}, +}) + +stairsplus:register_all('epic', 'acacia_bark', 'epic:acacia_bark', { + description='Acacia', + groups={choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory=1}, + tiles={'default_acacia_tree.png'}, +}) + +stairsplus:register_all('epic', 'aspen_bark', 'epic:aspen_bark', { + description='Aspen', + groups={choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory=1}, + tiles={'default_aspen_tree.png'}, +}) + +stairsplus:register_all('epic', 'jungle_bark', 'epic:jungle_bark', { + description='Jungle', + groups={choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory=1}, + tiles={'default_jungletree.png'}, +}) + +stairsplus:register_all('epic', 'pine_bark', 'epic:pine_bark', { + description='Pine', + groups={choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory=1}, + tiles={'default_pine_tree.png'}, +}) + +stairsplus:register_all('epic', 'tree_bark', 'epic:tree_bark', { + description='Tree', + groups={choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory=1}, + tiles={'default_tree.png'}, +}) + +stairsplus:register_all('epic', 'wood_ash', 'epic:wood_ash', { + description='Burnt wood', + groups={choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory=1}, + tiles={'epic_wood_ash.png'}, +}) + +stairsplus:register_all('epic', 'tree_ash', 'epic:tree_ash', { + description='Burnt tree', + groups={choppy = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory=1}, + tiles={'epic_tree_ash_top.png', 'epic_tree_ash_side.png'}, +}) + +stairsplus:register_all('asteroid', 'stone', 'asteroid:stone', { + description='Asteroid Stone', + groups={cracky = 2, not_in_creative_inventory=1}, + tiles={'asteroid_stone.png'}, +}) + +stairsplus:register_all('asteroid', 'stone_brick', 'asteroid:stone_brick', { + description='Asteroid Stone Brick', + groups={cracky = 2, not_in_creative_inventory=1}, + tiles={'asteroid_stone_brick.png'}, +}) + +stairsplus:register_all('caverealms', 'glow_amethyst', 'caverealms:glow_amethyst', { + description='Glow Amethyst', + groups={cracky = 2, not_in_creative_inventory=1}, + tiles={'caverealms_glow_amethyst.png'}, + light_source = 10 +}) + +stairsplus:register_all('caverealms', 'glow_crystal', 'caverealms:glow_crystal', { + description='Glow Crystal', + groups={cracky = 2, not_in_creative_inventory=1}, + tiles={'caverealms_glow_crystal.png'}, + light_source = 10 +}) + +stairsplus:register_all('caverealms', 'glow_emerald', 'caverealms:glow_emerald', { + description='Glow Emerald', + groups={cracky = 2, not_in_creative_inventory=1}, + tiles={'caverealms_glow_emerald.png'}, + light_source = 10 +}) + +stairsplus:register_all('caverealms', 'glow_ruby', 'caverealms:glow_ruby', { + description='Glow Ruby', + groups={cracky = 2, not_in_creative_inventory=1}, + tiles={'caverealms_glow_ruby.png'}, + light_source = 10 +}) diff --git a/mods/epic/ocean_guard.lua b/mods/epic/ocean_guard.lua new file mode 100644 index 0000000..76c6bfb --- /dev/null +++ b/mods/epic/ocean_guard.lua @@ -0,0 +1,66 @@ +mobs:register_mob('epic:ocean_guardian', { + type = 'monster', + passive = false, + attack_type = 'dogfight', + group_attack = true, + reach = 3, + damage = 16, + hp_min = 200, + hp_max = 300, + armor = 20, + view_range = 7, + stepheight = 0.2, + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + visual = 'mesh', + mesh = 'epic_guardians.b3d', + textures = { + {'epic_guardians.png'}, + }, + visual_size = {x=9, y=9}, + walk_velocity = 1, + run_velocity = 3, + fly = true, + stand_chance = 0, + fly_in = 'default:water_source', + stay_near = {'ocean:sea_lantern', 10}, + drops = { + {name = 'ocean:prismarine_crystals', chance = 10, min = 0, max = 3,}, + {name = 'ocean:prismarine_shard', chance = 10, min = 0, max = 4,}, + {name = 'epic:trident', chance = 200, min = 1, max = 1,} + }, + immune_to = {{'epic:trident', 20},}, + lava_damage = 15, + light_damage = 0, + fall_damage = 0, + fear_height = 5, + animation = { + speed_normal = 15, + speed_fly = 10, + stand_start = 0, + stand_end = 60, + fly_start = 0, + fly_end = 60, + punch_start = 65, + punch_end = 105, + }, + do_custom = function(self, dtime) + self.dtime = (self.dtime or 0) + dtime + if self.dtime < 5 then + return + end + if self.standing_in ~= 'default:water_source' then + self.health = self.health - 10 + end + self.dtime = 0 + end, +}) + +mobs:spawn({ + name = 'epic:ocean_guardian', + nodes = {'default:water_source', 'default:water_flowing'}, + neighbors = {'ocean:sea_lantern', 'ocean:prismarine'}, + min_height = -50, + max_height = 0, + interval = 10, + chance = 100, +}) diff --git a/mods/epic/overrides.lua b/mods/epic/overrides.lua new file mode 100644 index 0000000..411577d --- /dev/null +++ b/mods/epic/overrides.lua @@ -0,0 +1,209 @@ +minetest.register_tool(':mobs:pick_lava', { + description = ('Lava Pickaxe'), + inventory_image = 'mobs_pick_lava.png', + tool_capabilities = { + full_punch_interval = 0.4, + max_drop_level=4, + groupcaps={ + cracky = {times={[1]=1.80, [2]=0.80, [3]=0.40}, uses=40, maxlevel=4}, + }, + damage_groups = {fleshy = 6, fire = 1}, + }, + groups = {pickaxe = 1} +}) + +local flour_recipes = { + {'farming:rice_flour', 'farming:rice'}, + {'farming:flour', 'farming:wheat'}, + {'farming:flour', 'farming:rye'}, + {'farming:flour', 'farming:barley'}, +} + +for i in ipairs (flour_recipes) do + local output = flour_recipes[i][1] + local input = flour_recipes[i][2] + + minetest.register_craft({ + type = 'shapeless', + output = output, + recipe = { + input, input, input, + input, + } + }) +end + +minetest.register_craft({ + type = 'shapeless', + output = 'farming:flour_multigrain', + recipe = { + 'farming:wheat', 'farming:barley', 'farming:oat', + 'farming:rye', + } +}) + +minetest.clear_craft({ --TNT recipe + recipe = { + {'default:coal_lump', 'default:gravel', ''}, + } +}) + +minetest.clear_craft({output = 'default:sign_wall_steel'}) +minetest.clear_craft({output = 'mobs:horseshoe_steel'}) +minetest.clear_craft({output = 'mobs:horseshoe_bronze'}) +minetest.clear_craft({output = 'mobs:horseshoe_mese'}) +minetest.clear_craft({output = 'mobs:horseshoe_diamond'}) + +local on_burn = { + {'acacia_tree', 'tree_ash'}, + {'aspen_tree', 'tree_ash'}, + {'jungletree', 'tree_ash'}, + {'tree', 'tree_ash'}, + {'pine_tree', 'tree_ash'}, + {'acacia_wood', 'wood_ash'}, + {'aspen_wood', 'wood_ash'}, + {'junglewood', 'wood_ash'}, + {'pine_wood', 'wood_ash'}, + {'wood', 'wood_ash'}, + {'dirt_with_grass', 'scorched_dirt'}, + {'dirt_with_coniferous_litter', 'scorched_dirt'}, + {'dirt_with_dry_grass', 'scorched_dirt'}, + {'dirt_with_rainforest_litter', 'scorched_dirt'}, + {'dry_dirt_with_dry_grass', 'scorched_dirt'} +} + +for i in ipairs(on_burn) do + local input = on_burn[i][1] + local output = on_burn[i][2] + + minetest.override_item('default:'..input, { + on_burn = function(pos) + local node = minetest.get_node(pos) + minetest.swap_node(pos, {name = 'epic:'..output, param2=node.param2}) + end, + }) +end + +minetest.override_item('default:dirt_with_grass', { + groups = {crumbly=3, soil=1, flammable=1, spreading_dirt_type=1}, + drop = { + max_items = 2, + items = { + {items = {'default:dirt'}}, + {items = {'fishing:bait_worm'}, rarity = 20} + } + } +}) + +minetest.override_item('default:dirt_with_coniferous_litter', { + groups = {crumbly=3, soil=1, not_in_creative_inventory=1, flammable=1, spreading_dirt_type=1}, +}) + +minetest.override_item('default:dirt_with_dry_grass', { + groups = {crumbly=3, soil=1, flammable=1, spreading_dirt_type=1}, +}) + +minetest.override_item('default:dirt_with_rainforest_litter', { + groups = {crumbly=3, soil=1, not_in_creative_inventory=1, flammable=1, spreading_dirt_type=1}, +}) + +minetest.override_item('default:dry_dirt_with_dry_grass', { + groups = {crumbly=3, soil=1, flammable=1, spreading_dirt_type=1}, +}) + +minetest.override_item('carts:cart', { + inventory_image = 'epic_cart.png' +}) + +minetest.override_item('default:marram_grass_1', { + groups = {snappy = 3, flammable = 3, attached_node = 1, flora = 1}, +}) + +local crop_groups = function(node, group_name) + local ndef = minetest.registered_nodes[node] + local groups = ndef.groups + groups[group_name] = 1 + minetest.override_item(node,{ + groups = groups, + }) +end + +crop_groups('farming:wheat_8', 'grain') +crop_groups('farming:wheat_7', 'grain') +crop_groups('farming:wheat_6', 'grain') +crop_groups('farming:oat_8', 'grain') +crop_groups('farming:oat_7', 'grain') +crop_groups('farming:oat_6', 'grain') +crop_groups('farming:rice_8', 'grain') +crop_groups('farming:rice_7', 'grain') +crop_groups('farming:rice_6', 'grain') +crop_groups('farming:rye_8', 'grain') +crop_groups('farming:rye_7', 'grain') +crop_groups('farming:rye_6', 'grain') +crop_groups('farming:barley_7', 'grain') +crop_groups('farming:barley_6', 'grain') +crop_groups('farming:barley_5', 'grain') +crop_groups('farming:beetroot_5', 'veggie') +crop_groups('farming:beetroot_4', 'veggie') +crop_groups('farming:beetroot_3', 'veggie') +crop_groups('farming:beetroot_3', 'veggie') +crop_groups('farming:carrot_8', 'veggie') +crop_groups('farming:carrot_7', 'veggie') +crop_groups('farming:carrot_6', 'veggie') +crop_groups('farming:cucumber_4', 'veggie') +crop_groups('farming:cucumber_3', 'veggie') +crop_groups('farming:pepper_5', 'veggie') +crop_groups('farming:pepper_4', 'veggie') +crop_groups('farming:potato_4', 'veggie') +crop_groups('farming:potato_3', 'veggie') +crop_groups('farming:tomato_8', 'veggie') +crop_groups('farming:tomato_7', 'veggie') +crop_groups('farming:tomato_6', 'veggie') +crop_groups('farming:blueberry_4', 'fruit') +crop_groups('farming:blueberry_3', 'fruit') +crop_groups('farming:raspberry_4', 'fruit') +crop_groups('farming:raspberry_3', 'fruit') +crop_groups('farming:blueberry_4', 'fruit') +crop_groups('farming:pineapple_8', 'fruit') +crop_groups('farming:pineapple_7', 'fruit') +crop_groups('farming:pineapple_6', 'fruit') +crop_groups('farming:rhubarb_3', 'fruit') +crop_groups('farming:rhubarb_2', 'fruit') + +function default.grow_papyrus(pos, node) + pos.y = pos.y - 1 + local name = minetest.get_node(pos).name + if name ~= 'default:dirt_with_grass' and name ~= 'default:dirt' and name ~= 'trail:dirt_with_grass' and name ~= 'trail:dirt' then + return + end + if not minetest.find_node_near(pos, 3, {'group:water'}) then + return + end + pos.y = pos.y + 1 + local height = 0 + while node.name == 'default:papyrus' and height < 4 do + height = height + 1 + pos.y = pos.y + 1 + node = minetest.get_node(pos) + end + 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 + +bonemeal:set_deco({ + { 'farming:soil_wet', {'', '', ''}, {'farming:blueberry_1', 'farming:raspberry_1', '', ''} } +}) + +bonemeal:set_deco({ + { 'farming:soil', {''}, {''} } +}) + +minetest.override_item('default:water_source', { + drowning = 10, +}) diff --git a/mods/epic/particles.lua b/mods/epic/particles.lua new file mode 100644 index 0000000..379625a --- /dev/null +++ b/mods/epic/particles.lua @@ -0,0 +1,48 @@ +function particles_teleport(pos) + minetest.add_particlespawner({ + amount = 50, + time = 0.4, + minpos = {x=pos.x + 0.5, y=pos.y, z=pos.z + 0.5}, + maxpos = {x=pos.x - 0.5, y=pos.y, z=pos.z - 0.5}, + minvel = {x=0, y=5, z=0}, maxvel = {x=0, y=0, z=0}, + minacc = {x=0, y=5, z=0}, maxacc = {x=0, y=0, z=0}, + minexptime = 3, maxexptime = 5, + minsize = 3, maxsize = 5, + collisiondetection = false, + texture = 'epic_poof_arrive.png' + }) +end + +function particles_embers(pos) + minetest.add_particlespawner({ + amount = 1, + time = 2, + minpos = {x=pos.x + .25, y=pos.y, z=pos.z + .25}, + maxpos = {x=pos.x - .25, y=pos.y, z=pos.z - .25}, + minvel = {x=-.15, y=.3, z=-.15}, maxvel = {x=.1, y=.6, z=.1}, + minacc = {x=-.05, y=.02, z=-.05}, maxacc = {x=.1, y=.3, z=.1}, + minexptime = 1, maxexptime = 5, + minsize = 1, maxsize = 2, + collisiondetection = false, + texture = 'epic_embers.png', + vertical = false, + glow = 10, + }) +end + +function particles_healing(pos) + minetest.add_particlespawner({ + amount = 60, + time = 3, + minpos = {x=pos.x - 4, y=pos.y, z=pos.z - 4}, + maxpos = {x=pos.x + 4, y=pos.y + 1, z=pos.z + 4}, + minvel = {x=-.15, y=.3, z=-.15}, maxvel = {x=.1, y=.3, z=.1}, + minacc = {x=-.05, y=.02, z=-.05}, maxacc = {x=.3, y=.1, z=.3}, + minexptime = 1, maxexptime = 5, + minsize = 3, maxsize = 10, + collisiondetection = false, + texture = 'epic_health_mist.png', + vertical = true, + glow = 5, + }) +end diff --git a/mods/epic/privs.lua b/mods/epic/privs.lua new file mode 100644 index 0000000..98bdb78 --- /dev/null +++ b/mods/epic/privs.lua @@ -0,0 +1,9 @@ +minetest.register_privilege('fire', { + description = 'Start fires.', + give_to_singleplayer = false +}) + +minetest.register_privilege('spill', { + description = 'Empty buckets.', + give_to_singleplayer = false +}) diff --git a/mods/epic/signs.lua b/mods/epic/signs.lua new file mode 100644 index 0000000..7d0e71d --- /dev/null +++ b/mods/epic/signs.lua @@ -0,0 +1,272 @@ +local itemsign= {} + +local function remove_item(pos, node) + local objs = minetest.get_objects_inside_radius(pos, 0.5) + if not objs then return end + + for _, obj in pairs(objs) do + if obj and obj:get_luaentity() and + obj:get_luaentity().name == 'epic:sign_item' then + obj:remove() + end + end +end + +local facedir = { + [0] = {x=0, y=0, z=1}, {x=1, y=0, z=0}, {x=0, y=0, z=-1}, {x=-1, y=0, z=0} +} + +-- Works good for the most items, but not for all +local function get_drawtype(itemstring) + local def = minetest.registered_items[itemstring] + + --minetest.debug(string.format('Item: %s dt: %s, wield: %s', itemstring, dump(drawtype),dump(wield_image))) + if not def then + return 'twosided' + elseif def.wield_image ~= '' or def.inventory_image ~= '' then + return 'twosided' + elseif def.drawtype == 'normal' or + def.drawtype == 'mesh' or + def.drawtype == 'nodebox' then + return 'centered' + else + return 'twosided' + end +end + +local PI = math.pi +local function update_item(pos, node) + remove_item(pos, node) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local itemstring = inv:get_stack('item', 1):get_name() + local posad = facedir[node.param2] + if not posad or itemstring == '' then return end + + local yaw = PI*2 - node.param2 * PI/2 + if get_drawtype(itemstring) == 'centered' then + local pos = pos + local obj = minetest.add_entity(pos, 'epic:sign_item') + obj:setyaw(yaw) + obj:get_luaentity():init(itemstring) + elseif get_drawtype(itemstring)=='twosided' then + -- Front + local pos1 = vector.add(pos, vector.multiply(posad, -1/16) ) + local obj1 = minetest.add_entity(pos1, 'epic:sign_item') + obj1:setyaw(yaw) + obj1:get_luaentity():init(itemstring) + + -- Back + local pos2 = vector.add(pos, vector.multiply(posad, 1/16) ) + local obj2 = minetest.add_entity(pos2, 'epic:sign_item') + obj2:setyaw(yaw+PI) --rotate this about 180 Degrees + obj2:get_luaentity():init(itemstring) + else + minetest.log('error', 'Error: Invalid drawtype of '..itemstring) + end + pos = vector.add(pos, vector.multiply(posad, -1/16) ) + + +end + +local formspec = [[ + size[8,6] + list[context;item;0,0;1,1;] + label[0,-0.35;Item to show:] + field[2,0.3;4.1,1;text;Text:;${text}] + button_exit[6,0;2,1;submit;OK] + + list[current_player;main;0,1.85;8,1;] + list[current_player;main;0,3.08;8,3;8] + + listring[context;item] + listring[current_player;main] +]] + +function itemsign.construct(pos) + local meta = minetest.get_meta(pos) + meta:set_string('formspec', formspec) + local inv = meta:get_inventory() + inv:set_size('item', 1) +end + +function itemsign.can_dig(pos, player) + local meta = minetest.get_meta(pos); + local inv = meta:get_inventory() + return inv:is_empty('item') +end + +function itemsign.after_place(pos, placer, itemstack) + local meta = minetest.get_meta(pos) + local name = placer:get_player_name() + meta:set_string('owner', name) + meta:set_string('infotext', 'Item Sign') +end + +function itemsign.on_receive_fields(pos, formname, fields, sender) + local player_name = sender:get_player_name() or '' + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return + end + if fields.text then + local meta = minetest.get_meta(pos) + minetest.log('action', string.format('%s wrote %q to itemsign at %s', player_name, fields.text, minetest.pos_to_string(pos))) + meta:set_string('text', fields.text) + meta:set_string('infotext', fields.text) + end +end + +function itemsign.inventory_modified(pos, listname, index, stack, player) + local node = minetest.get_node(pos) + update_item(pos, node) +end + +function itemsign.allow_inventory(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + local player_name = player:get_player_name() + if meta:get_string('owner') ~= player_name then + return 0 + else + return 1 + end +end + +minetest.register_node('epic:sign', { + drawtype = 'mesh', + mesh = 'epic_hanging_sign.obj', + description = 'Trading sign', + groups = {choppy=3, oddly_breakable_by_hand=2, flammable=3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = 'facedir', + tiles = {'epic_hanging_sign.png'}, + inventory_image = 'epic_hanging_sign_inv.png', + wield_image = 'epic_hanging_sign_inv.png', + selection_box = { + type = 'fixed', + fixed = {-.45, -.45, -.1, .45, .4, .1}, + }, + collision_box = { + type = 'fixed', + fixed = {-.45, -.45, -.1, .45, .4, .1}, + }, + after_place_node = itemsign.after_place, + on_construct = itemsign.construct, + allow_metadata_inventory_put = itemsign.allow_inventory, + allow_metadata_inventory_take = itemsign.allow_inventory, + on_metadata_inventory_put = itemsign.inventory_modified, + on_metadata_inventory_take = itemsign.inventory_modified, + on_receive_fields = itemsign.on_receive_fields, + on_punch = update_item, + can_dig = itemsign.can_dig, + after_destruct = remove_item +}) + +minetest.register_entity('epic:sign_item', { + visual = 'wielditem', + visual_size = {x=0.33, y=0.33}, + collisionbox = {0}, + physical = false, + textures = {'air'}, + -- Init the item with the texture + init = function(self, item) + self.data.item = item + self.object:set_properties({textures={self.data.item}}) + end, + -- Everytime the item gets loaded + on_activate = function(self, staticdata) + local pos = self.object:get_pos() + if minetest.get_node(pos).name ~= 'epic:sign' then + self.object:remove() + end + + self.data = minetest.deserialize(staticdata) or {} + + if self.data.item then + self.object:set_properties({textures={self.data.item}}) + end + end, + -- Data, that shouldnt get loosed + get_staticdata = function(self) + return minetest.serialize(self.data) + end +}) + +minetest.register_node('epic:sign_post', { + drawtype = 'mesh', + mesh = 'epic_sign_post.obj', + description = 'Sign post', + groups = {choppy=3, oddly_breakable_by_hand=2, flammable=3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = 'facedir', + tiles = {'epic_sign_post.png'}, + selection_box = { + type = 'fixed', + fixed = {-.1, -.45, -.5, .1, .35, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.45, -.45, -.1, .45, .4, .1}, + }, +}) + +minetest.register_node('epic:sign_post_metal', { + drawtype = 'mesh', + mesh = 'epic_sign_post.obj', + description = 'Metal Sign Post', + groups = {choppy=3, oddly_breakable_by_hand=2, flammable=3}, + sounds = default.node_sound_metal_defaults(), + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = 'facedir', + tiles = {'epic_sign_post_metal.png'}, + selection_box = { + type = 'fixed', + fixed = {-.1, -.45, -.5, .1, .35, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.45, -.45, -.1, .45, .4, .1}, + }, +}) + +minetest.register_node('epic:directional_sign', { + drawtype = 'mesh', + mesh = 'epic_directional_sign.obj', + description = 'Directional sign post', + groups = {choppy=3, oddly_breakable_by_hand=2, flammable=3}, + sounds = default.node_sound_wood_defaults(), + sunlight_propagates = true, + paramtype = 'light', + paramtype2 = 'facedir', + tiles = {'epic_directional_sign.png'}, + selection_box = { + type = 'fixed', + fixed = {-.4, -.1, -.1, .45, .4, .1}, + }, + collision_box = { + type = 'fixed', + fixed = {-.4, -.3, -.1, .45, .4, .1}, + }, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string('formspec', 'field[text;;${text}]') + meta:set_string('infotext', '') + end, + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string('owner',placer:get_player_name()) + end, + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if sender:get_player_name() == meta:get_string('owner') then + if not fields.text then return end + meta:set_string('text', fields.text) + meta:set_string('infotext', fields.text) + end + end, +}) diff --git a/mods/epic/snowball.lua b/mods/epic/snowball.lua new file mode 100644 index 0000000..40aef93 --- /dev/null +++ b/mods/epic/snowball.lua @@ -0,0 +1,99 @@ +local function throw_snowball(item, player) + local playerpos = player:get_pos() + local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.625,z=playerpos.z}, 'epic:snowball') + local dir = player:get_look_dir() + obj:set_velocity({x=dir.x*30, y=dir.y*30, z=dir.z*30}) + obj:set_acceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3}) + item:take_item() + return item +end + +minetest.register_entity('epic:snowball', { + timer=0, + collisionbox = {0,0,0,0,0,0}, + physical = false, + textures = {'default_snowball.png'}, + lastpos={}, + on_step = function(self, dtime) + self.timer = self.timer + dtime + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + local objs = minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1) + for k, obj in pairs(objs) do + if obj:get_luaentity() ~= nil then + if obj:get_luaentity().name ~= "epic:snowball" and obj:get_luaentity().name ~= "__builtin:item" then + local damage = 1 + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + self.object:remove() + end + else + local damage = 1 + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + self.object:remove() + end + end + if self.lastpos.x~=nil then + if node.name ~= 'air' then + self.object:remove() + minetest.set_node(self.lastpos, {name='epic:snow'}) + minetest.check_for_falling(self.lastpos) + end + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end +}) + +minetest.override_item('default:snow', { + on_use = throw_snowball +}) + +minetest.override_item('trail:snow', { + on_use = throw_snowball +}) + +minetest.register_node("epic:snow", { + description = "Snow", + tiles = {"default_snow.png"}, + inventory_image = "default_snowball.png", + wield_image = "default_snowball.png", + paramtype = "light", + buildable_to = true, + floodable = true, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -0.25, 0.5}, + }, + }, + collision_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, -6 / 16, 0.5}, + }, + }, + groups = {crumbly = 3, falling_node = 1, snowy = 1, not_in_creative_inventory=1}, + sounds = default.node_sound_snow_defaults(), + + on_construct = function(pos) + pos.y = pos.y - 1 + if minetest.get_node(pos).name == "default:dirt_with_grass" then + minetest.set_node(pos, {name = "default:dirt_with_snow"}) + end + end, +}) + +minetest.register_abm({ + nodenames = {'epic:snow'}, + interval = 30, + chance = 15, + action = function(pos) + minetest.set_node(pos, {name = 'air'}) + end +}) diff --git a/mods/epic/teleport.lua b/mods/epic/teleport.lua new file mode 100644 index 0000000..8bb86a1 --- /dev/null +++ b/mods/epic/teleport.lua @@ -0,0 +1,171 @@ +-- Originally Teleport Request by Traxie21 and released with the WTFPL license +-- https://forum.minetest.net/viewtopic.php?id=4457 +-- Updates by Zeno and ChaosWormz + +local timeout_delay = 60 + +local version = '1.5' + +local tpr_list = {} +local tphr_list = {} + +local function find_free_position_near(pos) + local tries = { + {x=1,y=0,z=0}, + {x=-1,y=0,z=0}, + {x=0,y=0,z=1}, + {x=0,y=0,z=-1}, + } + for _,d in pairs(tries) do + local p = vector.add(pos, d) + if not minetest.registered_nodes[minetest.get_node(p).name].walkable then + return p, true + end + end + return pos, false +end + +--Teleport Request System +local function tpr_send(sender, receiver) + local player = minetest.get_player_by_name(sender) + if not player:get_inventory():contains_item('main', 'epic:teleport_powder') then + minetest.chat_send_player(sender, 'You need teleport powder.') + return + end + + if receiver == '' then + minetest.chat_send_player(sender, 'Usage: /tpr ') + return + end + + if not minetest.get_player_by_name(receiver) then + minetest.chat_send_player(sender, 'There is no player by that name. Keep in mind this is case sensitive, and the player must be online.') + return + end + + minetest.chat_send_player(receiver, sender ..' is requesting to teleport to you. /tpy to accept.') + minetest.chat_send_player(sender, 'Teleport request sent! It will time out in '.. timeout_delay ..' seconds.') + + --Write name values to list and clear old values. + tpr_list[receiver] = sender + --Teleport timeout delay + minetest.after(timeout_delay, function(name) + if tpr_list[name] then + tpr_list[name] = nil + end + end, sender) +end + +local function tphr_send(sender, receiver) + local player = minetest.get_player_by_name(sender) + if not player:get_inventory():contains_item('main', 'epic:teleport_powder') then + minetest.chat_send_player(sender, 'You need teleport powder.') + return + end + + if receiver == '' then + minetest.chat_send_player(sender, 'Usage: /tphr ') + return + end + + if not minetest.get_player_by_name(receiver) then + minetest.chat_send_player(sender, 'There is no player by that name. Keep in mind this is case sensitive, and the player must be online.') + return + end + + minetest.chat_send_player(receiver, sender ..' is requesting that you teleport to them. /tpy to accept; /tpn to deny') + minetest.chat_send_player(sender, 'Teleport request sent! It will time out in '.. timeout_delay ..' seconds.') + + --Write name values to list and clear old values. + tphr_list[receiver] = sender + --Teleport timeout delay + minetest.after(timeout_delay, function(name) + if tphr_list[name] then + tphr_list[name] = nil + end + end, sender) +end + +local function tpr_deny(name) + if tpr_list[name] then + minetest.chat_send_player(tpr_list[name], 'Teleport request denied.') + tpr_list[name] = nil + end + if tphr_list[name] then + minetest.chat_send_player(tphr_list[name], 'Teleport request denied.') + tphr_list[name] = nil + end +end + +--Teleport Accept Systems +local function tpr_accept(name, param) + + --Check to prevent constant teleporting. + if not tpr_list[name] + and not tphr_list[name] then + minetest.chat_send_player(name, 'Usage: /tpy allows you to accept teleport requests sent to you by other players.') + return + end + + local chatmsg, source, target, name2 + + if tpr_list[name] then + name2 = tpr_list[name] + source = minetest.get_player_by_name(name) + target = minetest.get_player_by_name(name2) + takepotion = minetest.get_player_by_name(name2) + chatmsg = name2 .. ' is teleporting to you.' + tpr_list[name] = nil + elseif tphr_list[name] then + name2 = tphr_list[name] + source = minetest.get_player_by_name(name2) + target = minetest.get_player_by_name(name) + takepotion = minetest.get_player_by_name(name2) + chatmsg = 'You are teleporting to ' .. name2 .. '.' + tphr_list[name] = nil + else + return + end + + -- Could happen if either player disconnects (or timeout); if so just abort + if not source + or not target then + return + end + + minetest.chat_send_player(name2, 'Request Accepted!') + minetest.chat_send_player(name, chatmsg) + + local target_coords=source:getpos() + target:setpos(find_free_position_near(target_coords)) + takepotion:get_inventory():remove_item('main', 'epic:teleport_powder') + minetest.sound_play('whoosh', {pos = target_coords, gain = 0.5, max_hear_distance = 10}) + particles_teleport(target_coords) +end + +--Chat commands. +minetest.register_chatcommand('tpr', { + description = 'Request teleport to another player', + params = ' | leave playername empty to see help message', + privs = {interact=true}, + func = tpr_send +}) + +minetest.register_chatcommand('tphr', { + description = 'Request player to teleport to you', + params = ' | leave playername empty to see help message', + privs = {interact=true}, + func = tphr_send +}) + +minetest.register_chatcommand('tpy', { + description = 'Accept teleport requests from another player', + privs = {interact=true}, + func = tpr_accept +}) + +minetest.register_chatcommand('tpn', { + description = 'Deny teleport requests from another player', + privs = {interact=true}, + func = tpr_deny +}) diff --git a/mods/epic/textures/3d_armor_boots_bronze.png b/mods/epic/textures/3d_armor_boots_bronze.png new file mode 100644 index 0000000..b36993e Binary files /dev/null and b/mods/epic/textures/3d_armor_boots_bronze.png differ diff --git a/mods/epic/textures/3d_armor_boots_diamond.png b/mods/epic/textures/3d_armor_boots_diamond.png new file mode 100644 index 0000000..96b89ce Binary files /dev/null and b/mods/epic/textures/3d_armor_boots_diamond.png differ diff --git a/mods/epic/textures/3d_armor_boots_gold.png b/mods/epic/textures/3d_armor_boots_gold.png new file mode 100644 index 0000000..94472a0 Binary files /dev/null and b/mods/epic/textures/3d_armor_boots_gold.png differ diff --git a/mods/epic/textures/3d_armor_boots_steel.png b/mods/epic/textures/3d_armor_boots_steel.png new file mode 100644 index 0000000..a0dc845 Binary files /dev/null and b/mods/epic/textures/3d_armor_boots_steel.png differ diff --git a/mods/epic/textures/3d_armor_chestplate_bronze.png b/mods/epic/textures/3d_armor_chestplate_bronze.png new file mode 100644 index 0000000..05a0464 Binary files /dev/null and b/mods/epic/textures/3d_armor_chestplate_bronze.png differ diff --git a/mods/epic/textures/3d_armor_chestplate_diamond.png b/mods/epic/textures/3d_armor_chestplate_diamond.png new file mode 100644 index 0000000..e6c8578 Binary files /dev/null and b/mods/epic/textures/3d_armor_chestplate_diamond.png differ diff --git a/mods/epic/textures/3d_armor_chestplate_gold.png b/mods/epic/textures/3d_armor_chestplate_gold.png new file mode 100644 index 0000000..3788564 Binary files /dev/null and b/mods/epic/textures/3d_armor_chestplate_gold.png differ diff --git a/mods/epic/textures/3d_armor_chestplate_steel.png b/mods/epic/textures/3d_armor_chestplate_steel.png new file mode 100644 index 0000000..c63a881 Binary files /dev/null and b/mods/epic/textures/3d_armor_chestplate_steel.png differ diff --git a/mods/epic/textures/3d_armor_gold.png b/mods/epic/textures/3d_armor_gold.png new file mode 100644 index 0000000..ffe538b Binary files /dev/null and b/mods/epic/textures/3d_armor_gold.png differ diff --git a/mods/epic/textures/3d_armor_helmet_bronze.png b/mods/epic/textures/3d_armor_helmet_bronze.png new file mode 100644 index 0000000..951b9b1 Binary files /dev/null and b/mods/epic/textures/3d_armor_helmet_bronze.png differ diff --git a/mods/epic/textures/3d_armor_helmet_diamond.png b/mods/epic/textures/3d_armor_helmet_diamond.png new file mode 100644 index 0000000..ce73510 Binary files /dev/null and b/mods/epic/textures/3d_armor_helmet_diamond.png differ diff --git a/mods/epic/textures/3d_armor_helmet_gold.png b/mods/epic/textures/3d_armor_helmet_gold.png new file mode 100644 index 0000000..2a0bb99 Binary files /dev/null and b/mods/epic/textures/3d_armor_helmet_gold.png differ diff --git a/mods/epic/textures/3d_armor_helmet_steel.png b/mods/epic/textures/3d_armor_helmet_steel.png new file mode 100644 index 0000000..b93d292 Binary files /dev/null and b/mods/epic/textures/3d_armor_helmet_steel.png differ diff --git a/mods/epic/textures/3d_armor_leggings_bronze.png b/mods/epic/textures/3d_armor_leggings_bronze.png new file mode 100644 index 0000000..3ee57a1 Binary files /dev/null and b/mods/epic/textures/3d_armor_leggings_bronze.png differ diff --git a/mods/epic/textures/3d_armor_leggings_diamond.png b/mods/epic/textures/3d_armor_leggings_diamond.png new file mode 100644 index 0000000..371e9f7 Binary files /dev/null and b/mods/epic/textures/3d_armor_leggings_diamond.png differ diff --git a/mods/epic/textures/3d_armor_leggings_gold.png b/mods/epic/textures/3d_armor_leggings_gold.png new file mode 100644 index 0000000..65bb84d Binary files /dev/null and b/mods/epic/textures/3d_armor_leggings_gold.png differ diff --git a/mods/epic/textures/3d_armor_leggings_steel.png b/mods/epic/textures/3d_armor_leggings_steel.png new file mode 100644 index 0000000..f9a19ec Binary files /dev/null and b/mods/epic/textures/3d_armor_leggings_steel.png differ diff --git a/mods/epic/textures/bags_large.png b/mods/epic/textures/bags_large.png new file mode 100644 index 0000000..095f901 Binary files /dev/null and b/mods/epic/textures/bags_large.png differ diff --git a/mods/epic/textures/bags_medium.png b/mods/epic/textures/bags_medium.png new file mode 100644 index 0000000..a380ee8 Binary files /dev/null and b/mods/epic/textures/bags_medium.png differ diff --git a/mods/epic/textures/bags_small.png b/mods/epic/textures/bags_small.png new file mode 100644 index 0000000..913366e Binary files /dev/null and b/mods/epic/textures/bags_small.png differ diff --git a/mods/epic/textures/carts_rail_crossing.png b/mods/epic/textures/carts_rail_crossing.png new file mode 100644 index 0000000..e4f3894 Binary files /dev/null and b/mods/epic/textures/carts_rail_crossing.png differ diff --git a/mods/epic/textures/carts_rail_crossing_brk.png b/mods/epic/textures/carts_rail_crossing_brk.png new file mode 100644 index 0000000..80c3d73 Binary files /dev/null and b/mods/epic/textures/carts_rail_crossing_brk.png differ diff --git a/mods/epic/textures/carts_rail_crossing_pwr.png b/mods/epic/textures/carts_rail_crossing_pwr.png new file mode 100644 index 0000000..b8a0431 Binary files /dev/null and b/mods/epic/textures/carts_rail_crossing_pwr.png differ diff --git a/mods/epic/textures/carts_rail_curved.png b/mods/epic/textures/carts_rail_curved.png new file mode 100644 index 0000000..5111512 Binary files /dev/null and b/mods/epic/textures/carts_rail_curved.png differ diff --git a/mods/epic/textures/carts_rail_curved_brk.png b/mods/epic/textures/carts_rail_curved_brk.png new file mode 100644 index 0000000..3dcaedf Binary files /dev/null and b/mods/epic/textures/carts_rail_curved_brk.png differ diff --git a/mods/epic/textures/carts_rail_curved_pwr.png b/mods/epic/textures/carts_rail_curved_pwr.png new file mode 100644 index 0000000..4a56de2 Binary files /dev/null and b/mods/epic/textures/carts_rail_curved_pwr.png differ diff --git a/mods/epic/textures/carts_rail_straight.png b/mods/epic/textures/carts_rail_straight.png new file mode 100644 index 0000000..1e0810f Binary files /dev/null and b/mods/epic/textures/carts_rail_straight.png differ diff --git a/mods/epic/textures/carts_rail_straight_brk.png b/mods/epic/textures/carts_rail_straight_brk.png new file mode 100644 index 0000000..8258d9b Binary files /dev/null and b/mods/epic/textures/carts_rail_straight_brk.png differ diff --git a/mods/epic/textures/carts_rail_straight_pwr.png b/mods/epic/textures/carts_rail_straight_pwr.png new file mode 100644 index 0000000..dc5617c Binary files /dev/null and b/mods/epic/textures/carts_rail_straight_pwr.png differ diff --git a/mods/epic/textures/carts_rail_t_junction.png b/mods/epic/textures/carts_rail_t_junction.png new file mode 100644 index 0000000..90f7df1 Binary files /dev/null and b/mods/epic/textures/carts_rail_t_junction.png differ diff --git a/mods/epic/textures/carts_rail_t_junction_brk.png b/mods/epic/textures/carts_rail_t_junction_brk.png new file mode 100644 index 0000000..5e0d0f8 Binary files /dev/null and b/mods/epic/textures/carts_rail_t_junction_brk.png differ diff --git a/mods/epic/textures/carts_rail_t_junction_pwr.png b/mods/epic/textures/carts_rail_t_junction_pwr.png new file mode 100644 index 0000000..6edbc65 Binary files /dev/null and b/mods/epic/textures/carts_rail_t_junction_pwr.png differ diff --git a/mods/epic/textures/commoditymarket_gold_coins.png b/mods/epic/textures/commoditymarket_gold_coins.png new file mode 100644 index 0000000..eedd2ad Binary files /dev/null and b/mods/epic/textures/commoditymarket_gold_coins.png differ diff --git a/mods/epic/textures/epic_actinolite_crystal.png b/mods/epic/textures/epic_actinolite_crystal.png new file mode 100644 index 0000000..2cad42f Binary files /dev/null and b/mods/epic/textures/epic_actinolite_crystal.png differ diff --git a/mods/epic/textures/epic_actinolite_crystal_shard.png b/mods/epic/textures/epic_actinolite_crystal_shard.png new file mode 100644 index 0000000..419a5cc Binary files /dev/null and b/mods/epic/textures/epic_actinolite_crystal_shard.png differ diff --git a/mods/epic/textures/epic_actinolite_side.png b/mods/epic/textures/epic_actinolite_side.png new file mode 100644 index 0000000..f3bfadd Binary files /dev/null and b/mods/epic/textures/epic_actinolite_side.png differ diff --git a/mods/epic/textures/epic_actinolite_top.png b/mods/epic/textures/epic_actinolite_top.png new file mode 100644 index 0000000..7ad199d Binary files /dev/null and b/mods/epic/textures/epic_actinolite_top.png differ diff --git a/mods/epic/textures/epic_animal_poison.png b/mods/epic/textures/epic_animal_poison.png new file mode 100644 index 0000000..95f26e9 Binary files /dev/null and b/mods/epic/textures/epic_animal_poison.png differ diff --git a/mods/epic/textures/epic_anti_fire.png b/mods/epic/textures/epic_anti_fire.png new file mode 100644 index 0000000..daf93f9 Binary files /dev/null and b/mods/epic/textures/epic_anti_fire.png differ diff --git a/mods/epic/textures/epic_anti_fire_powder.png b/mods/epic/textures/epic_anti_fire_powder.png new file mode 100644 index 0000000..ee3cc21 Binary files /dev/null and b/mods/epic/textures/epic_anti_fire_powder.png differ diff --git a/mods/epic/textures/epic_arrow_tip.png b/mods/epic/textures/epic_arrow_tip.png new file mode 100644 index 0000000..c94eabb Binary files /dev/null and b/mods/epic/textures/epic_arrow_tip.png differ diff --git a/mods/epic/textures/epic_ash.png b/mods/epic/textures/epic_ash.png new file mode 100644 index 0000000..6c9096b Binary files /dev/null and b/mods/epic/textures/epic_ash.png differ diff --git a/mods/epic/textures/epic_blank.png b/mods/epic/textures/epic_blank.png new file mode 100644 index 0000000..e6b0d22 Binary files /dev/null and b/mods/epic/textures/epic_blank.png differ diff --git a/mods/epic/textures/epic_bloodstone.png b/mods/epic/textures/epic_bloodstone.png new file mode 100644 index 0000000..bab9898 Binary files /dev/null and b/mods/epic/textures/epic_bloodstone.png differ diff --git a/mods/epic/textures/epic_bloodstone_ore.png b/mods/epic/textures/epic_bloodstone_ore.png new file mode 100644 index 0000000..ba2cb15 Binary files /dev/null and b/mods/epic/textures/epic_bloodstone_ore.png differ diff --git a/mods/epic/textures/epic_bloodstone_powder.png b/mods/epic/textures/epic_bloodstone_powder.png new file mode 100644 index 0000000..2dd4aaf Binary files /dev/null and b/mods/epic/textures/epic_bloodstone_powder.png differ diff --git a/mods/epic/textures/epic_bloodstone_shard.png b/mods/epic/textures/epic_bloodstone_shard.png new file mode 100644 index 0000000..2d0ffeb Binary files /dev/null and b/mods/epic/textures/epic_bloodstone_shard.png differ diff --git a/mods/epic/textures/epic_boots_fire.png b/mods/epic/textures/epic_boots_fire.png new file mode 100644 index 0000000..23c58fe Binary files /dev/null and b/mods/epic/textures/epic_boots_fire.png differ diff --git a/mods/epic/textures/epic_boots_fire_preview.png b/mods/epic/textures/epic_boots_fire_preview.png new file mode 100644 index 0000000..f8000bd Binary files /dev/null and b/mods/epic/textures/epic_boots_fire_preview.png differ diff --git a/mods/epic/textures/epic_boots_gravity.png b/mods/epic/textures/epic_boots_gravity.png new file mode 100644 index 0000000..ec9dd9a Binary files /dev/null and b/mods/epic/textures/epic_boots_gravity.png differ diff --git a/mods/epic/textures/epic_boots_gravity_preview.png b/mods/epic/textures/epic_boots_gravity_preview.png new file mode 100644 index 0000000..0d57b30 Binary files /dev/null and b/mods/epic/textures/epic_boots_gravity_preview.png differ diff --git a/mods/epic/textures/epic_boots_healing.png b/mods/epic/textures/epic_boots_healing.png new file mode 100644 index 0000000..5a885cf Binary files /dev/null and b/mods/epic/textures/epic_boots_healing.png differ diff --git a/mods/epic/textures/epic_boots_healing_preview.png b/mods/epic/textures/epic_boots_healing_preview.png new file mode 100644 index 0000000..a93289c Binary files /dev/null and b/mods/epic/textures/epic_boots_healing_preview.png differ diff --git a/mods/epic/textures/epic_boots_inv.png b/mods/epic/textures/epic_boots_inv.png new file mode 100644 index 0000000..9ddff7d Binary files /dev/null and b/mods/epic/textures/epic_boots_inv.png differ diff --git a/mods/epic/textures/epic_boots_speed.png b/mods/epic/textures/epic_boots_speed.png new file mode 100644 index 0000000..07e37dd Binary files /dev/null and b/mods/epic/textures/epic_boots_speed.png differ diff --git a/mods/epic/textures/epic_boots_speed_preview.png b/mods/epic/textures/epic_boots_speed_preview.png new file mode 100644 index 0000000..6070d89 Binary files /dev/null and b/mods/epic/textures/epic_boots_speed_preview.png differ diff --git a/mods/epic/textures/epic_boots_titanium.png b/mods/epic/textures/epic_boots_titanium.png new file mode 100644 index 0000000..d537d22 Binary files /dev/null and b/mods/epic/textures/epic_boots_titanium.png differ diff --git a/mods/epic/textures/epic_boots_titanium_inv.png b/mods/epic/textures/epic_boots_titanium_inv.png new file mode 100644 index 0000000..588928a Binary files /dev/null and b/mods/epic/textures/epic_boots_titanium_inv.png differ diff --git a/mods/epic/textures/epic_boots_titanium_preview.png b/mods/epic/textures/epic_boots_titanium_preview.png new file mode 100644 index 0000000..3fb6bc2 Binary files /dev/null and b/mods/epic/textures/epic_boots_titanium_preview.png differ diff --git a/mods/epic/textures/epic_boots_water.png b/mods/epic/textures/epic_boots_water.png new file mode 100644 index 0000000..9a4433c Binary files /dev/null and b/mods/epic/textures/epic_boots_water.png differ diff --git a/mods/epic/textures/epic_boots_water_preview.png b/mods/epic/textures/epic_boots_water_preview.png new file mode 100644 index 0000000..c1ada65 Binary files /dev/null and b/mods/epic/textures/epic_boots_water_preview.png differ diff --git a/mods/epic/textures/epic_cap_deception.png b/mods/epic/textures/epic_cap_deception.png new file mode 100644 index 0000000..f085cb0 Binary files /dev/null and b/mods/epic/textures/epic_cap_deception.png differ diff --git a/mods/epic/textures/epic_cap_deception_inv.png b/mods/epic/textures/epic_cap_deception_inv.png new file mode 100644 index 0000000..82e4d31 Binary files /dev/null and b/mods/epic/textures/epic_cap_deception_inv.png differ diff --git a/mods/epic/textures/epic_cap_deception_preview.png b/mods/epic/textures/epic_cap_deception_preview.png new file mode 100644 index 0000000..25b0c79 Binary files /dev/null and b/mods/epic/textures/epic_cap_deception_preview.png differ diff --git a/mods/epic/textures/epic_cart.png b/mods/epic/textures/epic_cart.png new file mode 100644 index 0000000..68f3c4e Binary files /dev/null and b/mods/epic/textures/epic_cart.png differ diff --git a/mods/epic/textures/epic_chestplate_fire.png b/mods/epic/textures/epic_chestplate_fire.png new file mode 100644 index 0000000..ab57777 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_fire.png differ diff --git a/mods/epic/textures/epic_chestplate_fire_preview.png b/mods/epic/textures/epic_chestplate_fire_preview.png new file mode 100644 index 0000000..fd8d353 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_fire_preview.png differ diff --git a/mods/epic/textures/epic_chestplate_gravity.png b/mods/epic/textures/epic_chestplate_gravity.png new file mode 100644 index 0000000..a52e799 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_gravity.png differ diff --git a/mods/epic/textures/epic_chestplate_gravity_preview.png b/mods/epic/textures/epic_chestplate_gravity_preview.png new file mode 100644 index 0000000..a1cef04 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_gravity_preview.png differ diff --git a/mods/epic/textures/epic_chestplate_healing.png b/mods/epic/textures/epic_chestplate_healing.png new file mode 100644 index 0000000..c512518 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_healing.png differ diff --git a/mods/epic/textures/epic_chestplate_healing_preview.png b/mods/epic/textures/epic_chestplate_healing_preview.png new file mode 100644 index 0000000..70dbc05 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_healing_preview.png differ diff --git a/mods/epic/textures/epic_chestplate_inv.png b/mods/epic/textures/epic_chestplate_inv.png new file mode 100644 index 0000000..03273d5 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_inv.png differ diff --git a/mods/epic/textures/epic_chestplate_speed.png b/mods/epic/textures/epic_chestplate_speed.png new file mode 100644 index 0000000..507eb1c Binary files /dev/null and b/mods/epic/textures/epic_chestplate_speed.png differ diff --git a/mods/epic/textures/epic_chestplate_speed_preview.png b/mods/epic/textures/epic_chestplate_speed_preview.png new file mode 100644 index 0000000..c1e4031 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_speed_preview.png differ diff --git a/mods/epic/textures/epic_chestplate_titanium.png b/mods/epic/textures/epic_chestplate_titanium.png new file mode 100644 index 0000000..eb4a688 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_titanium.png differ diff --git a/mods/epic/textures/epic_chestplate_titanium_inv.png b/mods/epic/textures/epic_chestplate_titanium_inv.png new file mode 100644 index 0000000..1ad324f Binary files /dev/null and b/mods/epic/textures/epic_chestplate_titanium_inv.png differ diff --git a/mods/epic/textures/epic_chestplate_titanium_preview.png b/mods/epic/textures/epic_chestplate_titanium_preview.png new file mode 100644 index 0000000..70742e7 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_titanium_preview.png differ diff --git a/mods/epic/textures/epic_chestplate_water.png b/mods/epic/textures/epic_chestplate_water.png new file mode 100644 index 0000000..4a97488 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_water.png differ diff --git a/mods/epic/textures/epic_chestplate_water_preview.png b/mods/epic/textures/epic_chestplate_water_preview.png new file mode 100644 index 0000000..ad95414 Binary files /dev/null and b/mods/epic/textures/epic_chestplate_water_preview.png differ diff --git a/mods/epic/textures/epic_crown.png b/mods/epic/textures/epic_crown.png new file mode 100644 index 0000000..f085cb0 Binary files /dev/null and b/mods/epic/textures/epic_crown.png differ diff --git a/mods/epic/textures/epic_crown_inv.png b/mods/epic/textures/epic_crown_inv.png new file mode 100644 index 0000000..19a7e35 Binary files /dev/null and b/mods/epic/textures/epic_crown_inv.png differ diff --git a/mods/epic/textures/epic_crown_preview.png b/mods/epic/textures/epic_crown_preview.png new file mode 100644 index 0000000..0ced418 Binary files /dev/null and b/mods/epic/textures/epic_crown_preview.png differ diff --git a/mods/epic/textures/epic_deed.png b/mods/epic/textures/epic_deed.png new file mode 100644 index 0000000..9d147a6 Binary files /dev/null and b/mods/epic/textures/epic_deed.png differ diff --git a/mods/epic/textures/epic_diamond_texture.png b/mods/epic/textures/epic_diamond_texture.png new file mode 100644 index 0000000..4db7eb7 Binary files /dev/null and b/mods/epic/textures/epic_diamond_texture.png differ diff --git a/mods/epic/textures/epic_directional_sign.png b/mods/epic/textures/epic_directional_sign.png new file mode 100644 index 0000000..36ee1f9 Binary files /dev/null and b/mods/epic/textures/epic_directional_sign.png differ diff --git a/mods/epic/textures/epic_embers.png b/mods/epic/textures/epic_embers.png new file mode 100644 index 0000000..5ed63aa Binary files /dev/null and b/mods/epic/textures/epic_embers.png differ diff --git a/mods/epic/textures/epic_fire_overlay.png b/mods/epic/textures/epic_fire_overlay.png new file mode 100644 index 0000000..b6961c9 Binary files /dev/null and b/mods/epic/textures/epic_fire_overlay.png differ diff --git a/mods/epic/textures/epic_garnet.png b/mods/epic/textures/epic_garnet.png new file mode 100644 index 0000000..a9f331e Binary files /dev/null and b/mods/epic/textures/epic_garnet.png differ diff --git a/mods/epic/textures/epic_garnet_ore.png b/mods/epic/textures/epic_garnet_ore.png new file mode 100644 index 0000000..4166a47 Binary files /dev/null and b/mods/epic/textures/epic_garnet_ore.png differ diff --git a/mods/epic/textures/epic_glowingdiamond.png b/mods/epic/textures/epic_glowingdiamond.png new file mode 100644 index 0000000..bdf6863 Binary files /dev/null and b/mods/epic/textures/epic_glowingdiamond.png differ diff --git a/mods/epic/textures/epic_glowstone_fragment.png b/mods/epic/textures/epic_glowstone_fragment.png new file mode 100644 index 0000000..596267d Binary files /dev/null and b/mods/epic/textures/epic_glowstone_fragment.png differ diff --git a/mods/epic/textures/epic_gravity_overlay.png b/mods/epic/textures/epic_gravity_overlay.png new file mode 100644 index 0000000..458a6ba Binary files /dev/null and b/mods/epic/textures/epic_gravity_overlay.png differ diff --git a/mods/epic/textures/epic_guardians.png b/mods/epic/textures/epic_guardians.png new file mode 100644 index 0000000..934a9d8 Binary files /dev/null and b/mods/epic/textures/epic_guardians.png differ diff --git a/mods/epic/textures/epic_hanging_sign.png b/mods/epic/textures/epic_hanging_sign.png new file mode 100644 index 0000000..615efde Binary files /dev/null and b/mods/epic/textures/epic_hanging_sign.png differ diff --git a/mods/epic/textures/epic_hanging_sign_inv.png b/mods/epic/textures/epic_hanging_sign_inv.png new file mode 100644 index 0000000..370672a Binary files /dev/null and b/mods/epic/textures/epic_hanging_sign_inv.png differ diff --git a/mods/epic/textures/epic_healing_overlay.png b/mods/epic/textures/epic_healing_overlay.png new file mode 100644 index 0000000..54fbc5e Binary files /dev/null and b/mods/epic/textures/epic_healing_overlay.png differ diff --git a/mods/epic/textures/epic_healing_powder.png b/mods/epic/textures/epic_healing_powder.png new file mode 100644 index 0000000..e652512 Binary files /dev/null and b/mods/epic/textures/epic_healing_powder.png differ diff --git a/mods/epic/textures/epic_health_mist.png b/mods/epic/textures/epic_health_mist.png new file mode 100644 index 0000000..a7d912d Binary files /dev/null and b/mods/epic/textures/epic_health_mist.png differ diff --git a/mods/epic/textures/epic_helmet_fire.png b/mods/epic/textures/epic_helmet_fire.png new file mode 100644 index 0000000..733ad61 Binary files /dev/null and b/mods/epic/textures/epic_helmet_fire.png differ diff --git a/mods/epic/textures/epic_helmet_fire_preview.png b/mods/epic/textures/epic_helmet_fire_preview.png new file mode 100644 index 0000000..84e0f11 Binary files /dev/null and b/mods/epic/textures/epic_helmet_fire_preview.png differ diff --git a/mods/epic/textures/epic_helmet_gravity.png b/mods/epic/textures/epic_helmet_gravity.png new file mode 100644 index 0000000..2a1ab9c Binary files /dev/null and b/mods/epic/textures/epic_helmet_gravity.png differ diff --git a/mods/epic/textures/epic_helmet_gravity_preview.png b/mods/epic/textures/epic_helmet_gravity_preview.png new file mode 100644 index 0000000..e1f2bd3 Binary files /dev/null and b/mods/epic/textures/epic_helmet_gravity_preview.png differ diff --git a/mods/epic/textures/epic_helmet_healing.png b/mods/epic/textures/epic_helmet_healing.png new file mode 100644 index 0000000..f736975 Binary files /dev/null and b/mods/epic/textures/epic_helmet_healing.png differ diff --git a/mods/epic/textures/epic_helmet_healing_preview.png b/mods/epic/textures/epic_helmet_healing_preview.png new file mode 100644 index 0000000..5fec100 Binary files /dev/null and b/mods/epic/textures/epic_helmet_healing_preview.png differ diff --git a/mods/epic/textures/epic_helmet_inv.png b/mods/epic/textures/epic_helmet_inv.png new file mode 100644 index 0000000..19c4be5 Binary files /dev/null and b/mods/epic/textures/epic_helmet_inv.png differ diff --git a/mods/epic/textures/epic_helmet_speed.png b/mods/epic/textures/epic_helmet_speed.png new file mode 100644 index 0000000..e5d468f Binary files /dev/null and b/mods/epic/textures/epic_helmet_speed.png differ diff --git a/mods/epic/textures/epic_helmet_speed_preview.png b/mods/epic/textures/epic_helmet_speed_preview.png new file mode 100644 index 0000000..655c31b Binary files /dev/null and b/mods/epic/textures/epic_helmet_speed_preview.png differ diff --git a/mods/epic/textures/epic_helmet_titanium.png b/mods/epic/textures/epic_helmet_titanium.png new file mode 100644 index 0000000..c6efecd Binary files /dev/null and b/mods/epic/textures/epic_helmet_titanium.png differ diff --git a/mods/epic/textures/epic_helmet_titanium_inv.png b/mods/epic/textures/epic_helmet_titanium_inv.png new file mode 100644 index 0000000..43ee4f5 Binary files /dev/null and b/mods/epic/textures/epic_helmet_titanium_inv.png differ diff --git a/mods/epic/textures/epic_helmet_titanium_preview.png b/mods/epic/textures/epic_helmet_titanium_preview.png new file mode 100644 index 0000000..87847b0 Binary files /dev/null and b/mods/epic/textures/epic_helmet_titanium_preview.png differ diff --git a/mods/epic/textures/epic_helmet_water.png b/mods/epic/textures/epic_helmet_water.png new file mode 100644 index 0000000..8a2355e Binary files /dev/null and b/mods/epic/textures/epic_helmet_water.png differ diff --git a/mods/epic/textures/epic_helmet_water_preview.png b/mods/epic/textures/epic_helmet_water_preview.png new file mode 100644 index 0000000..fe65173 Binary files /dev/null and b/mods/epic/textures/epic_helmet_water_preview.png differ diff --git a/mods/epic/textures/epic_huntite.png b/mods/epic/textures/epic_huntite.png new file mode 100644 index 0000000..076c2ba Binary files /dev/null and b/mods/epic/textures/epic_huntite.png differ diff --git a/mods/epic/textures/epic_inv_shield_titanium.png b/mods/epic/textures/epic_inv_shield_titanium.png new file mode 100644 index 0000000..d30dd20 Binary files /dev/null and b/mods/epic/textures/epic_inv_shield_titanium.png differ diff --git a/mods/epic/textures/epic_laputa.png b/mods/epic/textures/epic_laputa.png new file mode 100644 index 0000000..9327f8c Binary files /dev/null and b/mods/epic/textures/epic_laputa.png differ diff --git a/mods/epic/textures/epic_laputa_inv.png b/mods/epic/textures/epic_laputa_inv.png new file mode 100644 index 0000000..6f5869e Binary files /dev/null and b/mods/epic/textures/epic_laputa_inv.png differ diff --git a/mods/epic/textures/epic_lead_lump.png b/mods/epic/textures/epic_lead_lump.png new file mode 100644 index 0000000..f9966f8 Binary files /dev/null and b/mods/epic/textures/epic_lead_lump.png differ diff --git a/mods/epic/textures/epic_lead_wire.png b/mods/epic/textures/epic_lead_wire.png new file mode 100644 index 0000000..7172f1d Binary files /dev/null and b/mods/epic/textures/epic_lead_wire.png differ diff --git a/mods/epic/textures/epic_leggings_fire.png b/mods/epic/textures/epic_leggings_fire.png new file mode 100644 index 0000000..bf3277a Binary files /dev/null and b/mods/epic/textures/epic_leggings_fire.png differ diff --git a/mods/epic/textures/epic_leggings_fire_preview.png b/mods/epic/textures/epic_leggings_fire_preview.png new file mode 100644 index 0000000..3a2521d Binary files /dev/null and b/mods/epic/textures/epic_leggings_fire_preview.png differ diff --git a/mods/epic/textures/epic_leggings_gravity.png b/mods/epic/textures/epic_leggings_gravity.png new file mode 100644 index 0000000..87fe31a Binary files /dev/null and b/mods/epic/textures/epic_leggings_gravity.png differ diff --git a/mods/epic/textures/epic_leggings_gravity_preview.png b/mods/epic/textures/epic_leggings_gravity_preview.png new file mode 100644 index 0000000..7c297f5 Binary files /dev/null and b/mods/epic/textures/epic_leggings_gravity_preview.png differ diff --git a/mods/epic/textures/epic_leggings_healing.png b/mods/epic/textures/epic_leggings_healing.png new file mode 100644 index 0000000..31783fc Binary files /dev/null and b/mods/epic/textures/epic_leggings_healing.png differ diff --git a/mods/epic/textures/epic_leggings_healing_preview.png b/mods/epic/textures/epic_leggings_healing_preview.png new file mode 100644 index 0000000..90ca715 Binary files /dev/null and b/mods/epic/textures/epic_leggings_healing_preview.png differ diff --git a/mods/epic/textures/epic_leggings_inv.png b/mods/epic/textures/epic_leggings_inv.png new file mode 100644 index 0000000..6e9d094 Binary files /dev/null and b/mods/epic/textures/epic_leggings_inv.png differ diff --git a/mods/epic/textures/epic_leggings_speed.png b/mods/epic/textures/epic_leggings_speed.png new file mode 100644 index 0000000..e5ceaf2 Binary files /dev/null and b/mods/epic/textures/epic_leggings_speed.png differ diff --git a/mods/epic/textures/epic_leggings_speed_preview.png b/mods/epic/textures/epic_leggings_speed_preview.png new file mode 100644 index 0000000..3495e09 Binary files /dev/null and b/mods/epic/textures/epic_leggings_speed_preview.png differ diff --git a/mods/epic/textures/epic_leggings_titanium.png b/mods/epic/textures/epic_leggings_titanium.png new file mode 100644 index 0000000..60092f0 Binary files /dev/null and b/mods/epic/textures/epic_leggings_titanium.png differ diff --git a/mods/epic/textures/epic_leggings_titanium_inv.png b/mods/epic/textures/epic_leggings_titanium_inv.png new file mode 100644 index 0000000..825db72 Binary files /dev/null and b/mods/epic/textures/epic_leggings_titanium_inv.png differ diff --git a/mods/epic/textures/epic_leggings_titanium_preview.png b/mods/epic/textures/epic_leggings_titanium_preview.png new file mode 100644 index 0000000..f7c75a5 Binary files /dev/null and b/mods/epic/textures/epic_leggings_titanium_preview.png differ diff --git a/mods/epic/textures/epic_leggings_water.png b/mods/epic/textures/epic_leggings_water.png new file mode 100644 index 0000000..cf21c92 Binary files /dev/null and b/mods/epic/textures/epic_leggings_water.png differ diff --git a/mods/epic/textures/epic_leggings_water_preview.png b/mods/epic/textures/epic_leggings_water_preview.png new file mode 100644 index 0000000..40abb65 Binary files /dev/null and b/mods/epic/textures/epic_leggings_water_preview.png differ diff --git a/mods/epic/textures/epic_metal_lead.png b/mods/epic/textures/epic_metal_lead.png new file mode 100644 index 0000000..d07ea30 Binary files /dev/null and b/mods/epic/textures/epic_metal_lead.png differ diff --git a/mods/epic/textures/epic_mineral_sulfur.png b/mods/epic/textures/epic_mineral_sulfur.png new file mode 100644 index 0000000..cce7a4d Binary files /dev/null and b/mods/epic/textures/epic_mineral_sulfur.png differ diff --git a/mods/epic/textures/epic_nitre_ore.png b/mods/epic/textures/epic_nitre_ore.png new file mode 100644 index 0000000..48dbb86 Binary files /dev/null and b/mods/epic/textures/epic_nitre_ore.png differ diff --git a/mods/epic/textures/epic_poof_arrive.png b/mods/epic/textures/epic_poof_arrive.png new file mode 100644 index 0000000..d32ab57 Binary files /dev/null and b/mods/epic/textures/epic_poof_arrive.png differ diff --git a/mods/epic/textures/epic_poof_depart.png b/mods/epic/textures/epic_poof_depart.png new file mode 100644 index 0000000..01c3bf6 Binary files /dev/null and b/mods/epic/textures/epic_poof_depart.png differ diff --git a/mods/epic/textures/epic_potassium_nitrate.png b/mods/epic/textures/epic_potassium_nitrate.png new file mode 100644 index 0000000..8f5a3ff Binary files /dev/null and b/mods/epic/textures/epic_potassium_nitrate.png differ diff --git a/mods/epic/textures/epic_reaver.png b/mods/epic/textures/epic_reaver.png new file mode 100644 index 0000000..4f2c0a8 Binary files /dev/null and b/mods/epic/textures/epic_reaver.png differ diff --git a/mods/epic/textures/epic_salt.png b/mods/epic/textures/epic_salt.png new file mode 100644 index 0000000..b51d3dc Binary files /dev/null and b/mods/epic/textures/epic_salt.png differ diff --git a/mods/epic/textures/epic_salt_lump.png b/mods/epic/textures/epic_salt_lump.png new file mode 100644 index 0000000..1d5d2cb Binary files /dev/null and b/mods/epic/textures/epic_salt_lump.png differ diff --git a/mods/epic/textures/epic_salt_ore.png b/mods/epic/textures/epic_salt_ore.png new file mode 100644 index 0000000..debb733 Binary files /dev/null and b/mods/epic/textures/epic_salt_ore.png differ diff --git a/mods/epic/textures/epic_scorched_dirt.png b/mods/epic/textures/epic_scorched_dirt.png new file mode 100644 index 0000000..18d14ca Binary files /dev/null and b/mods/epic/textures/epic_scorched_dirt.png differ diff --git a/mods/epic/textures/epic_shield_titanium.png b/mods/epic/textures/epic_shield_titanium.png new file mode 100644 index 0000000..d3e0182 Binary files /dev/null and b/mods/epic/textures/epic_shield_titanium.png differ diff --git a/mods/epic/textures/epic_shield_titanium_preview.png b/mods/epic/textures/epic_shield_titanium_preview.png new file mode 100644 index 0000000..e8d7326 Binary files /dev/null and b/mods/epic/textures/epic_shield_titanium_preview.png differ diff --git a/mods/epic/textures/epic_sign_post.png b/mods/epic/textures/epic_sign_post.png new file mode 100644 index 0000000..d3ae3e5 Binary files /dev/null and b/mods/epic/textures/epic_sign_post.png differ diff --git a/mods/epic/textures/epic_sign_post_metal.png b/mods/epic/textures/epic_sign_post_metal.png new file mode 100644 index 0000000..2600a31 Binary files /dev/null and b/mods/epic/textures/epic_sign_post_metal.png differ diff --git a/mods/epic/textures/epic_slicer.png b/mods/epic/textures/epic_slicer.png new file mode 100644 index 0000000..a9867fd Binary files /dev/null and b/mods/epic/textures/epic_slicer.png differ diff --git a/mods/epic/textures/epic_speed_overlay.png b/mods/epic/textures/epic_speed_overlay.png new file mode 100644 index 0000000..a3dc342 Binary files /dev/null and b/mods/epic/textures/epic_speed_overlay.png differ diff --git a/mods/epic/textures/epic_sulfur_dust.png b/mods/epic/textures/epic_sulfur_dust.png new file mode 100644 index 0000000..a5f0ca6 Binary files /dev/null and b/mods/epic/textures/epic_sulfur_dust.png differ diff --git a/mods/epic/textures/epic_sulfur_lump.png b/mods/epic/textures/epic_sulfur_lump.png new file mode 100644 index 0000000..be70ed5 Binary files /dev/null and b/mods/epic/textures/epic_sulfur_lump.png differ diff --git a/mods/epic/textures/epic_teleport_powder.png b/mods/epic/textures/epic_teleport_powder.png new file mode 100644 index 0000000..5dce585 Binary files /dev/null and b/mods/epic/textures/epic_teleport_powder.png differ diff --git a/mods/epic/textures/epic_titanium_ingot.png b/mods/epic/textures/epic_titanium_ingot.png new file mode 100644 index 0000000..42e124b Binary files /dev/null and b/mods/epic/textures/epic_titanium_ingot.png differ diff --git a/mods/epic/textures/epic_titanium_lump.png b/mods/epic/textures/epic_titanium_lump.png new file mode 100644 index 0000000..82b86d3 Binary files /dev/null and b/mods/epic/textures/epic_titanium_lump.png differ diff --git a/mods/epic/textures/epic_titanium_ore.png b/mods/epic/textures/epic_titanium_ore.png new file mode 100644 index 0000000..f75a03a Binary files /dev/null and b/mods/epic/textures/epic_titanium_ore.png differ diff --git a/mods/epic/textures/epic_tool_glowingdiamond_axe.png b/mods/epic/textures/epic_tool_glowingdiamond_axe.png new file mode 100644 index 0000000..5149348 Binary files /dev/null and b/mods/epic/textures/epic_tool_glowingdiamond_axe.png differ diff --git a/mods/epic/textures/epic_tool_glowingdiamond_pick.png b/mods/epic/textures/epic_tool_glowingdiamond_pick.png new file mode 100644 index 0000000..cec13b2 Binary files /dev/null and b/mods/epic/textures/epic_tool_glowingdiamond_pick.png differ diff --git a/mods/epic/textures/epic_tool_glowingdiamond_shovel.png b/mods/epic/textures/epic_tool_glowingdiamond_shovel.png new file mode 100644 index 0000000..1f01c3e Binary files /dev/null and b/mods/epic/textures/epic_tool_glowingdiamond_shovel.png differ diff --git a/mods/epic/textures/epic_tool_glowingdiamond_sword.png b/mods/epic/textures/epic_tool_glowingdiamond_sword.png new file mode 100644 index 0000000..ea8faf5 Binary files /dev/null and b/mods/epic/textures/epic_tool_glowingdiamond_sword.png differ diff --git a/mods/epic/textures/epic_tool_shovel_soft.png b/mods/epic/textures/epic_tool_shovel_soft.png new file mode 100644 index 0000000..0a4ce92 Binary files /dev/null and b/mods/epic/textures/epic_tool_shovel_soft.png differ diff --git a/mods/epic/textures/epic_tool_titanium_axe.png b/mods/epic/textures/epic_tool_titanium_axe.png new file mode 100644 index 0000000..a0681da Binary files /dev/null and b/mods/epic/textures/epic_tool_titanium_axe.png differ diff --git a/mods/epic/textures/epic_tool_titanium_pick.png b/mods/epic/textures/epic_tool_titanium_pick.png new file mode 100644 index 0000000..cf02d2e Binary files /dev/null and b/mods/epic/textures/epic_tool_titanium_pick.png differ diff --git a/mods/epic/textures/epic_tool_titanium_shovel.png b/mods/epic/textures/epic_tool_titanium_shovel.png new file mode 100644 index 0000000..471a78a Binary files /dev/null and b/mods/epic/textures/epic_tool_titanium_shovel.png differ diff --git a/mods/epic/textures/epic_tool_titanium_sword.png b/mods/epic/textures/epic_tool_titanium_sword.png new file mode 100644 index 0000000..c79dffa Binary files /dev/null and b/mods/epic/textures/epic_tool_titanium_sword.png differ diff --git a/mods/epic/textures/epic_tree_ash_side.png b/mods/epic/textures/epic_tree_ash_side.png new file mode 100644 index 0000000..5844187 Binary files /dev/null and b/mods/epic/textures/epic_tree_ash_side.png differ diff --git a/mods/epic/textures/epic_tree_ash_top.png b/mods/epic/textures/epic_tree_ash_top.png new file mode 100644 index 0000000..3bd713f Binary files /dev/null and b/mods/epic/textures/epic_tree_ash_top.png differ diff --git a/mods/epic/textures/epic_trident.png b/mods/epic/textures/epic_trident.png new file mode 100644 index 0000000..ae340f4 Binary files /dev/null and b/mods/epic/textures/epic_trident.png differ diff --git a/mods/epic/textures/epic_water_overlay.png b/mods/epic/textures/epic_water_overlay.png new file mode 100644 index 0000000..fdb8c38 Binary files /dev/null and b/mods/epic/textures/epic_water_overlay.png differ diff --git a/mods/epic/textures/epic_wood_ash.png b/mods/epic/textures/epic_wood_ash.png new file mode 100644 index 0000000..ea7b692 Binary files /dev/null and b/mods/epic/textures/epic_wood_ash.png differ diff --git a/mods/epic/textures/shields_shield_diamond.png b/mods/epic/textures/shields_shield_diamond.png new file mode 100644 index 0000000..206b56f Binary files /dev/null and b/mods/epic/textures/shields_shield_diamond.png differ diff --git a/mods/epic/textures/steel_armor_base.png b/mods/epic/textures/steel_armor_base.png new file mode 100644 index 0000000..d0b7c31 Binary files /dev/null and b/mods/epic/textures/steel_armor_base.png differ diff --git a/mods/epic/tools.lua b/mods/epic/tools.lua new file mode 100644 index 0000000..577e1cb --- /dev/null +++ b/mods/epic/tools.lua @@ -0,0 +1,219 @@ +minetest.register_tool('epic:pick_titanium', { + _doc_items_crafting = 'This tool is crafted in the Smithy Station.', + description = 'Titanium Pickaxe', + inventory_image = 'epic_tool_titanium_pick.png', + tool_capabilities = { + full_punch_interval = 0.8, + max_drop_level=3, + groupcaps={ + cracky = {times={[1]=1.9, [2]=0.90, [3]=0.40}, uses=50, maxlevel=4}, + }, + damage_groups = {fleshy=10, knockback=3}, + }, + sound = {breaks = 'default_tool_breaks'}, + groups = {pickaxe = 1} +}) + +minetest.register_tool('epic:shovel_titanium', { + _doc_items_crafting = 'This tool is crafted in the Smithy Station.', + description = 'Titanium Shovel', + inventory_image = 'epic_tool_titanium_shovel.png', + wield_image = 'epic_tool_titanium_shovel.png^[transformR90', + tool_capabilities = { + full_punch_interval = 0.9, + max_drop_level=3, + groupcaps={ + crumbly = {times={[1]=1.0, [2]=0.40, [3]=0.20}, uses=50, maxlevel=4}, + }, + damage_groups = {fleshy=6}, + }, + sound = {breaks = 'default_tool_breaks'}, + groups = {shovel = 1, knockback=2} +}) + +minetest.register_tool('epic:axe_titanium', { + _doc_items_crafting = 'This tool is crafted in the Smithy Station.', + description = 'Titanium Axe', + inventory_image = 'epic_tool_titanium_axe.png', + tool_capabilities = { + full_punch_interval = 0.8, + max_drop_level=3, + groupcaps={ + choppy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=50, maxlevel=4}, + }, + damage_groups = {fleshy=9, knockback=3}, + }, + sound = {breaks = 'default_tool_breaks'}, + groups = {axe = 1} +}) + +minetest.register_tool('epic:sword_titanium', { + _doc_items_crafting = 'This tool is crafted in the Smithy Station.', + description = 'Titanium Sword', + inventory_image = 'epic_tool_titanium_sword.png', + tool_capabilities = { + full_punch_interval = 0.6, + max_drop_level=3, + groupcaps={ + snappy={times={[1]=1.80, [2]=0.80, [3]=0.20}, uses=60, maxlevel=4}, + }, + damage_groups = {fleshy=12, knockback=4}, + }, + sound = {breaks = 'default_tool_breaks'}, + groups = {sword = 1} +}) + +minetest.register_tool('epic:shovel_soft', { + description = 'Soft Touch Shovel', + _doc_items_crafting = 'This tool is crafted in the Smithy Station.', + _doc_items_durability = 111, + _doc_items_longdesc = 'A special shovel that can pick up dirt blocks without disturbing the grass/moss.', + _doc_items_usagehelp = "Punch a dirt block to pick it up.", + inventory_image = 'epic_tool_shovel_soft.png', + wield_image = 'epic_tool_shovel_soft.png^[transformR90', + sound = {breaks = 'default_tool_breaks'}, + groups = {shovel = 1, knockback=2}, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + if not minetest.is_protected(pointed_thing.under, user:get_player_name()) then + local pos = pointed_thing.under + local nn = minetest.get_node(pos).name + local is_crumbly = minetest.get_item_group(nn, "crumbly") + if is_crumbly == 1 or is_crumbly == 2 or is_crumbly == 3 then + local inv = user:get_inventory() + minetest.env:remove_node(pointed_thing.under) + minetest.check_for_falling(pos) + inv:add_item("main", {name = nn}) + itemstack:add_wear(65535/100) -- 111 uses + minetest.sound_play("default_dirt_footstep", {pos = pos, gain = 0.35}) + return itemstack + end + end + end + end, +}) + +minetest.register_tool('epic:pick_glowingdiamond', { + _doc_items_crafting = 'This tool is crafted in the Crystal Workshop.', + description = 'Glowingdiamond Pickaxe', + inventory_image = 'epic_tool_glowingdiamond_pick.png', + light_source = 13, + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=2, + groupcaps={ + cracky = {times={[1]=1.9, [2]=0.90, [3]=0.40}, uses=20, maxlevel=2}, + }, + damage_groups = {fleshy=4, knockback=3}, + }, + sound = {breaks = 'default_tool_breaks'}, + groups = {pickaxe = 1} +}) + +minetest.register_tool('epic:shovel_glowingdiamond', { + _doc_items_crafting = 'This tool is crafted in the Crystal Workshop.', + description = 'Glowingdiamond Shovel', + inventory_image = 'epic_tool_glowingdiamond_shovel.png', + light_source = 13, + wield_image = 'epic_tool_glowingdiamond_shovel.png^[transformR90', + tool_capabilities = { + full_punch_interval = 1.1, + max_drop_level=1, + groupcaps={ + crumbly = {times={[1]=1.0, [2]=0.40, [3]=0.20}, uses=30, maxlevel=2}, + }, + damage_groups = {fleshy=3}, + }, + sound = {breaks = 'default_tool_breaks'}, + groups = {shovel = 1, knockback=2} +}) + +minetest.register_tool('epic:axe_glowingdiamond', { + _doc_items_crafting = 'This tool is crafted in the Crystal Workshop.', + description = 'Glowingdiamond Axe', + inventory_image = 'epic_tool_glowingdiamond_axe.png', + light_source = 13, + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=1, + groupcaps={ + choppy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=20, maxlevel=2}, + }, + damage_groups = {fleshy=4}, + }, + sound = {breaks = 'default_tool_breaks'}, + groups = {axe = 1} +}) + +minetest.register_tool('epic:sword_glowingdiamond', { + _doc_items_crafting = 'This tool is crafted in the Crystal Workshop.', + description = 'Glowingdiamond Sword', + inventory_image = 'epic_tool_glowingdiamond_sword.png', + light_source = 13, + tool_capabilities = { + full_punch_interval = 0.8, + max_drop_level=1, + groupcaps={ + snappy={times={[1]=1.80, [2]=0.80, [3]=0.20}, uses=30, maxlevel=2}, + }, + damage_groups = {fleshy=7, knockback=4}, + }, + sound = {breaks = 'default_tool_breaks'}, + groups = {sword = 1} +}) + +---RARE WEAPONS. +minetest.register_tool('epic:trident', { + _doc_items_durability = 55, + _doc_items_crafting = "This weapon can't be crafted or repaired.", + description = 'Trident', + inventory_image = 'epic_trident.png', + tool_capabilities = { + full_punch_interval = .5, + max_drop_level = 2, + damage_groups = {fleshy = 25, knockback = 2, rare = 1}, + punch_attack_uses = 55, + }, + groups = {not_in_creative_inventory=1} +}) + +minetest.register_tool('epic:slicer', { + _doc_items_durability = 30, + _doc_items_crafting = "This weapon can't be crafted or repaired.", + description = 'Decapitating Obsidian Slicer', + inventory_image = 'epic_slicer.png', + tool_capabilities = { + full_punch_interval = .8, + max_drop_level = 3, + damage_groups = {fleshy = 36, knockback = 4, rare = 1}, + punch_attack_uses = 30, + }, + groups = {not_in_creative_inventory=1} +}) + +minetest.register_tool('epic:reaver', { + _doc_items_durability = 50, + _doc_items_crafting = "This weapon can't be crafted or repaired.", + description = 'Skullforge Reaver', + inventory_image = 'epic_reaver.png', + tool_capabilities = { + full_punch_interval = .2, + max_drop_level = 2, + damage_groups = {fleshy = 16, knockback = 3, rare = 1}, + punch_attack_uses = 50, + }, + groups = {not_in_creative_inventory=1} +}) + +--[[ +-------------------------- +This code needs to be put into mobs_redo to handle the rare weapons wearing faster. +-- toolrank support +local wear = 0 +if tool_capabilities.damage_groups['rare'] then + local uses = tool_capabilities.punch_attack_uses + wear = floor(65535/uses) +else + wear = floor((punch_interval / 75) * 9000) +end +--]] diff --git a/mods/epic/traps.lua b/mods/epic/traps.lua new file mode 100644 index 0000000..9c0f98e --- /dev/null +++ b/mods/epic/traps.lua @@ -0,0 +1,30 @@ +local traps = { + {'desertsandstonebrick', 'Trap Desert Sandstone Brick', 'default_desert_sandstone_brick.png', 'default:desert_sandstone_brick'}, + {'sandstonebrick', 'Trap Sandstone Brick', 'default_sandstone_brick.png', 'default:sandstonebrick'}, + {'stonebrick', 'Trap Stone Brick', 'default_stone_brick.png', 'default:stonebrick'}, + {'cobble', 'Trap Cobblestone', 'default_cobble.png', 'default:cobble'}, + {'mossycobble', 'Trap Mossy Cobblestone', 'default_mossycobble.png', 'default:mossycobble'}, + {'ice', 'Trap Ice', 'default_ice.png', 'default:ice'} +} + +for i in ipairs (traps) do + local name = traps[i][1] + local desc = traps[i][2] + local text = traps[i][3] + local reci = traps[i][4] + + minetest.register_node('epic:'..name, { + description = desc, + drawtype = 'glasslike_framed', + tiles = {text}, + walkable = false, + groups = {cracky = 2, traps=1}, + paramtype = 'light', + }) + + minetest.register_craft({ + output = 'epic:'..name, + recipe = {{'default:mese_crystal_fragment', reci}} + }) + +end diff --git a/mods/extra_doors/README.txt b/mods/extra_doors/README.txt new file mode 100644 index 0000000..1f86dc9 --- /dev/null +++ b/mods/extra_doors/README.txt @@ -0,0 +1,206 @@ +Extra Doors Mod v2.0 +By Leslie Krause + +Repository +---------------------- + +Browse source code: + https://bitbucket.org/sorcerykid/extra_doors + +Download archive: + https://bitbucket.org/sorcerykid/extra_doors/get/master.zip + https://bitbucket.org/sorcerykid/extra_doors/get/master.tar.gz + +Revision History +---------------------- + +Version 1.0b (12-Jan-2018) + - initial version within doors mod + +Version 2.0 (31-Aug-2018) + - separated common routines into standalone mod + - included support files for public release + +Compatability +---------------------- + +Minetest 0.4.15+ required + +Dependencies +---------------------- + +Doors Mod (required) + https://github.com/minetest/minetest_game/doors + +Installation +---------------------- + + 1) Unzip the archive into the mods directory of your game + 2) Rename the extra_doors-master directory to "extra_doors" + + +Source Code License +---------------------- + +GNU Lesser General Public License v3 (LGPL-3.0) + +Copyright (c) 2018, Leslie Krause (leslie@searstower.org) + +This program 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 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details. + +http://www.gnu.org/licenses/lgpl-2.1.html + +License of media (textures, sounds, and models) +---------------------------------------------------------- + +Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) + + /textures/doors_door_cottage1.png + by kilbith (relicensed WTFPL) + modified by sorcerykid + + /textures/doors_door_cottage2.png + by kilbith (relicensed WTFPL) + modified by sorcerykid + + /textures/doors_door_french.png + by kilbith (relicensed WTFPL) + modified by sorcerykid + + /textures/doors_door_japanese.png + by kilbith (relicensed WTFPL) + modified by sorcerykid + + /textures/doors_item_cottage1.png + by kilbith (relicensed WTFPL) + modified by sorcerykid + + /textures/doors_item_cottage2.png + by kilbith (relicensed WTFPL) + modified by sorcerykid + + /textures/doors_item_french.png + by kilbith (relicensed WTFPL) + modified by sorcerykid + + /textures/doors_item_japanese.png + by kilbith (relicensed WTFPL) + modified by sorcerykid + + /textures/default_steel_rod.png + by sorcerykid + + /textures/doors_door_barn1.png + by sorcerykid + + /textures/doors_door_barn2.png + by sorcerykid + + /textures/doors_door_castle1.png + by sorcerykid + + /textures/doors_door_castle2.png + by sorcerykid + + /textures/doors_door_dungeon1.png + by sorcerykid + + /textures/doors_door_dungeon2.png + by sorcerykid + + /textures/doors_door_mansion1.png + by sorcerykid + + /textures/doors_door_mansion2.png + by sorcerykid + + /textures/doors_door_steelglass1.png + by sorcerykid + + /textures/doors_door_steelglass2.png + by sorcerykid + + /textures/doors_door_steelpanel1.png + by sorcerykid + + /textures/doors_door_woodglass1.png + by sorcerykid + + /textures/doors_door_woodglass2.png + by sorcerykid + + /textures/doors_door_woodpanel1.png + by sorcerykid + + /textures/doors_item_barn1.png + by sorcerykid + + /textures/doors_item_barn2.png + by sorcerykid + + /textures/doors_item_castle1.png + by sorcerykid + + /textures/doors_item_castle2.png + by sorcerykid + + /textures/doors_item_dungeon1.png + by sorcerykid + + /textures/doors_item_dungeon2.png + by sorcerykid + + /textures/doors_item_mansion1.png + by sorcerykid + + /textures/doors_item_mansion2.png + by sorcerykid + + /textures/doors_item_steelglass1.png + by sorcerykid + + /textures/doors_item_steelglass2.png + by sorcerykid + + /textures/doors_item_steelpanel1.png + by sorcerykid + + /textures/doors_item_woodglass1.png + by sorcerykid + + /textures/doors_item_woodglass2.png + by sorcerykid + + /textures/doors_item_woodpanel1.png + by sorcerykid + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/extra_doors/depends.txt b/mods/extra_doors/depends.txt new file mode 100644 index 0000000..678b31b --- /dev/null +++ b/mods/extra_doors/depends.txt @@ -0,0 +1 @@ +doors diff --git a/mods/extra_doors/description.txt b/mods/extra_doors/description.txt new file mode 100644 index 0000000..1622783 --- /dev/null +++ b/mods/extra_doors/description.txt @@ -0,0 +1 @@ +Extra Doors adds a set of 18 new doors to Minetest including castle, dungeon, barn, cottage, and multi-panel styles. diff --git a/mods/extra_doors/init.lua b/mods/extra_doors/init.lua new file mode 100644 index 0000000..ea4b1ce --- /dev/null +++ b/mods/extra_doors/init.lua @@ -0,0 +1,272 @@ +-------------------------------------------------------- +-- Minetest :: Extra Doors v2.0 (extra_doors) +-- +-- See README.txt for licensing and release notes. +-- Copyright (c) 2018, Leslie E. Krause +-------------------------------------------------------- + +-- One of the most essential but often overlooked elements of building design is door selection. +-- Doors set the tone and character, and having the wrong style of door can make or break a build. + +doors.register( "door_woodpanel1", { + -- Colonial Style (6 panel) + tiles = { { name = "doors_door_woodpanel1.png", backface_culling = true } }, + description = "Wooden Colonial Door", + inventory_image = "doors_item_woodpanel1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "group:wood", "group:wood", "default:stick" }, + { "group:wood", "group:wood", "default:stick" }, + { "group:wood", "group:wood", "default:stick" }, + } +} ) + +doors.register( "door_woodglass1", { + -- Cambridge Style (2 panel) + tiles = { { name = "doors_door_woodglass1.png", backface_culling = true } }, + description = "Wooden Single-Lite Door", + inventory_image = "doors_item_woodglass1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "default:glass", "default:glass", "default:stick" }, + { "group:wood", "group:wood", "" }, + { "group:wood", "group:wood", "" }, + } +} ) + +doors.register( "door_woodglass2", { + -- Atherton Style (4 panel) + tiles = { { name = "doors_door_woodglass2.png", backface_culling = true } }, + description = "Wooden Double-Lite Door", + inventory_image = "doors_item_woodglass2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "default:glass", "default:glass", "default:stick" }, + { "group:wood", "group:wood", "default:stick" }, + { "group:wood", "group:wood", "" }, + } +} ) + +doors.register( "door_japanese", { + tiles = { { name = "doors_door_japanese.png", backface_culling = true } }, + description = "Japanese Door", + inventory_image = "doors_item_japanese.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "default:paper", "group:wood", "default:stick" }, + { "default:paper", "group:wood", "default:stick" }, + { "default:paper", "group:wood", "default:stick" }, + } +} ) + +doors.register( "door_french", { + tiles = { { name = "doors_door_french.png", backface_culling = true } }, + description = "French Door", + inventory_image = "doors_item_french.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "default:glass", "group:wood", "default:stick" }, + { "default:glass", "group:wood", "default:stick" }, + { "default:glass", "group:wood", "default:stick" }, + } +} ) + +doors.register( "door_cottage1", { + tiles = { { name = "doors_door_cottage1.png", backface_culling = true } }, + description = "Cottage Interior Door", + inventory_image = "doors_item_cottage1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "group:wood", "group:wood" }, + { "default:stick", "default:stick" }, + { "group:wood", "group:wood" }, + } +} ) + +doors.register( "door_cottage2", { + tiles = { { name = "doors_door_cottage2.png", backface_culling = true } }, + description = "Cottage Exterior Door", + inventory_image = "doors_item_cottage2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "default:glass", "default:glass" }, + { "default:stick", "default:stick" }, + { "group:wood", "group:wood" }, + } +} ) + +doors.register( "door_barn1", { + tiles = { { name = "doors_door_barn1.png", backface_culling = true } }, + description = "Barn Interior Door", + inventory_image = "doors_item_barn1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "group:wood", "group:wood", "group:wood" }, + { "default:stick", "default:stick", "default:stick" }, + { "group:wood", "group:wood", "group:wood" }, + } +} ) + +doors.register( "door_barn2", { + tiles = { { name = "doors_door_barn2.png", backface_culling = true } }, + description = "Barn Exterior Door", + inventory_image = "doors_item_barn2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "group:wood", "group:wood", "group:wood" }, + { "darkage:iron_stick", "darkage:iron_stick", "darkage:iron_stick" }, + { "group:wood", "group:wood", "group:wood" }, + } +} ) + +doors.register( "door_castle1", { + tiles = { { name = "doors_door_castle1.png", backface_culling = true } }, + description = "Castle Interior Door", + inventory_image = "doors_item_castle1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "default:stick", "group:wood", "group:wood" }, + { "", "group:wood", "group:wood" }, + { "default:stick", "group:wood", "group:wood" }, + } +} ) + +doors.register( "door_castle2", { + tiles = { { name = "doors_door_castle2.png", backface_culling = true } }, + description = "Castle Exterior Door", + inventory_image = "doors_item_castle2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "darkage:iron_stick", "group:wood", "group:wood" }, + { "", "group:wood", "group:wood" }, + { "darkage:iron_stick", "group:wood", "group:wood" }, + } +} ) + +doors.register( "door_mansion1", { + tiles = { { name = "doors_door_mansion1.png", backface_culling = true } }, + description = "Mansion Interior Door", + inventory_image = "doors_item_mansion1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "group:wood", "group:wood", "dye:white" }, + { "group:wood", "group:wood", "dye:yellow" }, + { "group:wood", "group:wood", "dye:white" }, + } +} ) + +doors.register( "door_mansion2", { + tiles = { { name = "doors_door_mansion2.png", backface_culling = true } }, + description = "Mansion Exterior Door ", + inventory_image = "doors_item_mansion2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, + recipe = { + { "group:wood", "group:wood", "dye:black" }, + { "group:wood", "group:wood", "dye:yellow" }, + { "group:wood", "group:wood", "dye:black" }, + } +} ) + +doors.register("door_dungeon1", { + tiles = { { name = "doors_door_dungeon1.png", backface_culling = true } }, + description = "Dungeon Interior Door", + inventory_image = "doors_item_dungeon1.png", + protected = true, + groups = { cracky = 1, level = 2 }, + sounds = default.node_sound_metal_defaults( ), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + recipe = { + { "default:steel_ingot", "darkage:iron_stick", "default:steel_ingot" }, + { "darkage:iron_stick", "darkage:iron_stick", "darkage:iron_stick" }, + { "default:steel_ingot", "darkage:iron_stick", "default:steel_ingot" }, + } +} ) + +doors.register( "door_dungeon2", { + tiles = { { name = "doors_door_dungeon2.png", backface_culling = true } }, + description = "Dungeon Exterior Door", + inventory_image = "doors_item_dungeon2.png", + protected = true, + groups = { cracky = 1, level = 2 }, + sounds = default.node_sound_metal_defaults( ), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + recipe = { + { "darkage:iron_stick", "darkage:iron_stick", "darkage:iron_stick" }, + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" }, + { "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" }, + } +} ) + +doors.register( "door_steelpanel1", { + tiles = { { name = "doors_door_steelpanel1.png", backface_culling = true } }, + description = "Steel Colonial Door", + inventory_image = "doors_item_steelpanel1.png", + protected = true, + groups = { cracky = 1, level = 2 }, + sounds = default.node_sound_metal_defaults( ), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + recipe = { + { "default:steel_ingot", "default:steel_ingot", "darkage:iron_stick" }, + { "default:steel_ingot", "default:steel_ingot", "darkage:iron_stick" }, + { "default:steel_ingot", "default:steel_ingot", "darkage:iron_stick" }, + } +} ) + +doors.register( "door_steelglass1", { + tiles = { { name = "doors_door_steelglass1.png", backface_culling = true } }, + description = "Steel Single-Lite Door", + inventory_image = "doors_item_steelglass1.png", + protected = true, + groups = { cracky = 1, level = 2 }, + sounds = default.node_sound_metal_defaults( ), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + recipe = { + { "default:glass", "default:glass", "darkage:iron_stick" }, + { "default:steel_ingot", "default:steel_ingot", "" }, + { "default:steel_ingot", "default:steel_ingot", "" }, + } +} ) + +doors.register( "door_steelglass2", { + tiles = { { name = "doors_door_steelglass2.png", backface_culling = true } }, + description = "Steel Double-Lite Door", + inventory_image = "doors_item_steelglass2.png", + protected = true, + groups = { cracky = 1, level = 2 }, + sounds = default.node_sound_metal_defaults( ), + sound_open = "doors_steel_door_open", + sound_close = "doors_steel_door_close", + recipe = { + { "default:glass", "default:glass", "darkage:iron_stick" }, + { "default:steel_ingot", "default:steel_ingot", "darkage:iron_stick" }, + { "default:steel_ingot", "default:steel_ingot", "" }, + } +} ) + +minetest.register_craft( { + type = "fuel", + recipe = "doors:door_barn1", + burntime = 14, +} ) + +minetest.register_craft( { + type = "fuel", + recipe = "doors:door_barn2", + burntime = 16, +} ) + +minetest.register_craft( { + type = "fuel", + recipe = "doors:door_castle1", + burntime = 8, +} ) + +minetest.register_craft( { + type = "fuel", + recipe = "doors:door_castle2", + burntime = 12, +} ) diff --git a/mods/extra_doors/mod.conf b/mods/extra_doors/mod.conf new file mode 100644 index 0000000..5fa5a75 --- /dev/null +++ b/mods/extra_doors/mod.conf @@ -0,0 +1,4 @@ +name = extra_doors +title = Extra Doors +author = sorcerykid +license = LGPL-3.0 diff --git a/mods/extra_doors/textures/default_steel_rod.png b/mods/extra_doors/textures/default_steel_rod.png new file mode 100644 index 0000000..0e692e9 Binary files /dev/null and b/mods/extra_doors/textures/default_steel_rod.png differ diff --git a/mods/extra_doors/textures/doors_door_barn1.png b/mods/extra_doors/textures/doors_door_barn1.png new file mode 100644 index 0000000..0bf0035 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_barn1.png differ diff --git a/mods/extra_doors/textures/doors_door_barn2.png b/mods/extra_doors/textures/doors_door_barn2.png new file mode 100644 index 0000000..83e1497 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_barn2.png differ diff --git a/mods/extra_doors/textures/doors_door_castle1.png b/mods/extra_doors/textures/doors_door_castle1.png new file mode 100644 index 0000000..7ec1017 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_castle1.png differ diff --git a/mods/extra_doors/textures/doors_door_castle2.png b/mods/extra_doors/textures/doors_door_castle2.png new file mode 100644 index 0000000..5e6af94 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_castle2.png differ diff --git a/mods/extra_doors/textures/doors_door_cottage1.png b/mods/extra_doors/textures/doors_door_cottage1.png new file mode 100644 index 0000000..2d9113b Binary files /dev/null and b/mods/extra_doors/textures/doors_door_cottage1.png differ diff --git a/mods/extra_doors/textures/doors_door_cottage2.png b/mods/extra_doors/textures/doors_door_cottage2.png new file mode 100644 index 0000000..e7ce435 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_cottage2.png differ diff --git a/mods/extra_doors/textures/doors_door_dungeon1.png b/mods/extra_doors/textures/doors_door_dungeon1.png new file mode 100644 index 0000000..0537f5d Binary files /dev/null and b/mods/extra_doors/textures/doors_door_dungeon1.png differ diff --git a/mods/extra_doors/textures/doors_door_dungeon2.png b/mods/extra_doors/textures/doors_door_dungeon2.png new file mode 100644 index 0000000..956bff0 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_dungeon2.png differ diff --git a/mods/extra_doors/textures/doors_door_french.png b/mods/extra_doors/textures/doors_door_french.png new file mode 100644 index 0000000..58b17e6 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_french.png differ diff --git a/mods/extra_doors/textures/doors_door_japanese.png b/mods/extra_doors/textures/doors_door_japanese.png new file mode 100644 index 0000000..64d6119 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_japanese.png differ diff --git a/mods/extra_doors/textures/doors_door_mansion1.png b/mods/extra_doors/textures/doors_door_mansion1.png new file mode 100644 index 0000000..d4991de Binary files /dev/null and b/mods/extra_doors/textures/doors_door_mansion1.png differ diff --git a/mods/extra_doors/textures/doors_door_mansion2.png b/mods/extra_doors/textures/doors_door_mansion2.png new file mode 100644 index 0000000..8f73430 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_mansion2.png differ diff --git a/mods/extra_doors/textures/doors_door_steelglass1.png b/mods/extra_doors/textures/doors_door_steelglass1.png new file mode 100644 index 0000000..0168cd6 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_steelglass1.png differ diff --git a/mods/extra_doors/textures/doors_door_steelglass2.png b/mods/extra_doors/textures/doors_door_steelglass2.png new file mode 100644 index 0000000..8a990c5 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_steelglass2.png differ diff --git a/mods/extra_doors/textures/doors_door_steelpanel1.png b/mods/extra_doors/textures/doors_door_steelpanel1.png new file mode 100644 index 0000000..fdcec01 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_steelpanel1.png differ diff --git a/mods/extra_doors/textures/doors_door_woodglass1.png b/mods/extra_doors/textures/doors_door_woodglass1.png new file mode 100644 index 0000000..7d9232a Binary files /dev/null and b/mods/extra_doors/textures/doors_door_woodglass1.png differ diff --git a/mods/extra_doors/textures/doors_door_woodglass2.png b/mods/extra_doors/textures/doors_door_woodglass2.png new file mode 100644 index 0000000..ca527ce Binary files /dev/null and b/mods/extra_doors/textures/doors_door_woodglass2.png differ diff --git a/mods/extra_doors/textures/doors_door_woodpanel1.png b/mods/extra_doors/textures/doors_door_woodpanel1.png new file mode 100644 index 0000000..745a723 Binary files /dev/null and b/mods/extra_doors/textures/doors_door_woodpanel1.png differ diff --git a/mods/extra_doors/textures/doors_item_barn1.png b/mods/extra_doors/textures/doors_item_barn1.png new file mode 100644 index 0000000..c63859d Binary files /dev/null and b/mods/extra_doors/textures/doors_item_barn1.png differ diff --git a/mods/extra_doors/textures/doors_item_barn2.png b/mods/extra_doors/textures/doors_item_barn2.png new file mode 100644 index 0000000..6ece2a6 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_barn2.png differ diff --git a/mods/extra_doors/textures/doors_item_castle1.png b/mods/extra_doors/textures/doors_item_castle1.png new file mode 100644 index 0000000..9cd6317 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_castle1.png differ diff --git a/mods/extra_doors/textures/doors_item_castle2.png b/mods/extra_doors/textures/doors_item_castle2.png new file mode 100644 index 0000000..0aebe4e Binary files /dev/null and b/mods/extra_doors/textures/doors_item_castle2.png differ diff --git a/mods/extra_doors/textures/doors_item_cottage1.png b/mods/extra_doors/textures/doors_item_cottage1.png new file mode 100644 index 0000000..2f57ec9 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_cottage1.png differ diff --git a/mods/extra_doors/textures/doors_item_cottage2.png b/mods/extra_doors/textures/doors_item_cottage2.png new file mode 100644 index 0000000..f657466 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_cottage2.png differ diff --git a/mods/extra_doors/textures/doors_item_dungeon1.png b/mods/extra_doors/textures/doors_item_dungeon1.png new file mode 100644 index 0000000..087e338 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_dungeon1.png differ diff --git a/mods/extra_doors/textures/doors_item_dungeon2.png b/mods/extra_doors/textures/doors_item_dungeon2.png new file mode 100644 index 0000000..bd203b8 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_dungeon2.png differ diff --git a/mods/extra_doors/textures/doors_item_french.png b/mods/extra_doors/textures/doors_item_french.png new file mode 100644 index 0000000..5ef5a73 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_french.png differ diff --git a/mods/extra_doors/textures/doors_item_japanese.png b/mods/extra_doors/textures/doors_item_japanese.png new file mode 100644 index 0000000..67c5aa0 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_japanese.png differ diff --git a/mods/extra_doors/textures/doors_item_mansion1.png b/mods/extra_doors/textures/doors_item_mansion1.png new file mode 100644 index 0000000..5921c99 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_mansion1.png differ diff --git a/mods/extra_doors/textures/doors_item_mansion2.png b/mods/extra_doors/textures/doors_item_mansion2.png new file mode 100644 index 0000000..c55b618 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_mansion2.png differ diff --git a/mods/extra_doors/textures/doors_item_steelglass1.png b/mods/extra_doors/textures/doors_item_steelglass1.png new file mode 100644 index 0000000..87f2085 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_steelglass1.png differ diff --git a/mods/extra_doors/textures/doors_item_steelglass2.png b/mods/extra_doors/textures/doors_item_steelglass2.png new file mode 100644 index 0000000..b2059f3 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_steelglass2.png differ diff --git a/mods/extra_doors/textures/doors_item_steelpanel1.png b/mods/extra_doors/textures/doors_item_steelpanel1.png new file mode 100644 index 0000000..1593407 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_steelpanel1.png differ diff --git a/mods/extra_doors/textures/doors_item_woodglass1.png b/mods/extra_doors/textures/doors_item_woodglass1.png new file mode 100644 index 0000000..8ef8eca Binary files /dev/null and b/mods/extra_doors/textures/doors_item_woodglass1.png differ diff --git a/mods/extra_doors/textures/doors_item_woodglass2.png b/mods/extra_doors/textures/doors_item_woodglass2.png new file mode 100644 index 0000000..4f9b8a8 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_woodglass2.png differ diff --git a/mods/extra_doors/textures/doors_item_woodpanel1.png b/mods/extra_doors/textures/doors_item_woodpanel1.png new file mode 100644 index 0000000..accfc01 Binary files /dev/null and b/mods/extra_doors/textures/doors_item_woodpanel1.png differ diff --git a/mods/fantasy_mobs/cavefreak.lua b/mods/fantasy_mobs/cavefreak.lua new file mode 100644 index 0000000..f876c1d --- /dev/null +++ b/mods/fantasy_mobs/cavefreak.lua @@ -0,0 +1,177 @@ +local cavefreak_sounds = { +-- random = 'goblins_goblin_ambient', +-- warcry = 'goblins_goblin_attack', + attack = 'fantasy_cavefreak_punch', +-- damage = 'goblins_goblin_damage', + death = 'fantasy_cavefreak_die', + distance = 7, +} + +function fire_splash(pos) + minetest.sound_play('fantasy_fire_start',{pos = pos, max_hear_distance = 10, gain = 0.5}) + for z = -1,1 do + for y = -1,0 do + for x = -1,1 do + local p = {x=pos.x+x, y=pos.y+y, z=pos.z+z} + local nn = minetest.get_node(p).name + if nn == 'air' then + minetest.set_node(p, {name='fire:basic_flame'}) + end + end + end + end +end + +mobs:register_mob('fantasy_mobs:cavefreak_fire', { + description = 'Cavefreak', + type = 'monster', + damage = 15, + attack_type = 'shoot', + shoot_interval = 2, + arrow = 'fantasy_mobs:cavefreak_fire_arrow', + shoot_offset = 1, + hp_min = 100, + hp_max = 200, + armor = 75, + collisionbox = {-0.4, -0.5, -0.4, 0.4, .5, 0.4}, + visual = 'mesh', + mesh = 'fantasy_cavefreak.b3d', + textures = { + {'fantasy_cavefreak1.png^fantasy_cavefreak_fire.png'}, + {'fantasy_cavefreak2.png^fantasy_cavefreak_fire.png'}, + {'fantasy_cavefreak3.png^fantasy_cavefreak_fire.png'}, + }, + rotate = 180, + visual_size = {x = 9, y = 9}, + sounds = cavefreak_sounds, + walk_velocity = 2, + run_velocity = 4, + immune_to = {{'castle_weapons:crossbow_bolt_entity', 30},}, + jump = true, + water_damage = 5, + lava_damage = -5, + light_damage = 1, + reach = 2, + view_range = 8, + drops = { + {name = 'scorpion:shell', chance = 2, min = 1, max = 6}, + {name = 'epic:huntite', chance = 10, min = 0, max = 15}, + {name = 'tnt:gunpowder', chance = 3, min = 4, max = 20} + }, + animation = { + die_start = 140, + die_end = 180, + die_loop = false, + stand_start = 0, + stand_end = 60, + walk_start = 65, + walk_end = 135, + punch_start = 185, + punch_end = 240, + shoot_start = 245, + shoot_end = 290, + }, + makes_footstep_sound = true, +}) + +mobs:register_mob('fantasy_mobs:cavefreak_slash', { + description = 'Cavefreak', + type = 'monster', + damage = 20, + attack_type = 'dogfight', + hp_min = 100, + hp_max = 200, + armor = 75, + collisionbox = {-0.4, -0.5, -0.4, 0.4, .5, 0.4}, + visual = 'mesh', + mesh = 'fantasy_cavefreak.b3d', + textures = { + {'fantasy_cavefreak1.png'}, + {'fantasy_cavefreak2.png'}, + {'fantasy_cavefreak3.png'}, + }, + rotate = 180, + visual_size = {x = 9, y = 9}, + sounds = cavefreak_sounds, + walk_velocity = 2, + run_velocity = 4, + immune_to = {{'castle_weapons:crossbow_bolt_entity', 30},}, + jump = true, + water_damage = 5, + lava_damage = -5, + light_damage = 1, + reach = 3, + view_range = 8, + drops = { + {name = 'scorpion:shell', chance = 2, min = 1, max = 6}, + {name = 'epic:huntite', chance = 2, min = 0 , max = 1} + }, + animation = { + die_start = 140, + die_end = 180, + die_loop = false, + stand_start = 0, + stand_end = 60, + walk_start = 65, + walk_end = 135, + punch_start = 185, + punch_end = 240, + shoot_start = 245, + shoot_end = 290, + }, + makes_footstep_sound = true, +}) + +mobs:register_arrow('fantasy_mobs:cavefreak_fire_arrow', { + visual = 'sprite', + visual_size = {x = .5, y = .5}, + textures = {'fantasy_goblins_blood.png'}, + collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1}, + velocity = 7, + on_activate = function(self, staticdata, dtime_s) + self.object:set_armor_groups({immortal = 1, fleshy = 100}) + end, + hit_player = function(self, player) + local pos = player:get_pos() + local current_player_pos = { + x = math.floor(pos.x + 0.5), + y = math.floor(pos.y + 1.2), + z = math.floor(pos.z + 0.5) + } + fire_splash(current_player_pos) + end, + hit_mob = function(self, player) + local pos = player:get_pos() + local current_player_pos = { + x = math.floor(pos.x + 0.5), + y = math.floor(pos.y + 1.2), + z = math.floor(pos.z + 0.5) + } + fire_splash(current_player_pos) + end, + hit_node = function(self, pos, node) + fire_splash(pos) + end +}) + +mobs:spawn({ + name = 'fantasy_mobs:cavefreak_fire', + nodes = {'caverealms:stone_with_lichen', 'caverealms:stone_with_moss', 'caverealms:stone_with_algae'}, + max_light = 10, + min_height = -21900, + max_height = -500, + interval = 213, + chance = 3200, + active_object_count = 1, +}) + +mobs:spawn({ + name = 'fantasy_mobs:cavefreak_slash', + nodes = {'caverealms:stone_with_lichen', 'caverealms:stone_with_moss', 'caverealms:stone_with_algae'}, + max_light = 10, + min_height = -21900, + max_height = -500, + interval = 132, + chance = 1000, + active_object_count = 4, +}) diff --git a/mods/fantasy_mobs/cloudpuff.lua b/mods/fantasy_mobs/cloudpuff.lua new file mode 100644 index 0000000..2e50fcd --- /dev/null +++ b/mods/fantasy_mobs/cloudpuff.lua @@ -0,0 +1,117 @@ +-- Green Slimes by TomasJLuis & TenPlus1 + +-- sounds +local green_sounds = { + damage = 'slimes_damage', + death = 'slimes_death', + jump = 'slimes_jump', + attack = 'slimes_attack', +} + +local cloud_textures = {'fantasy_cloud_puff_sides.png', 'fantasy_cloud_puff_sides.png', 'fantasy_cloud_puff_sides.png', 'fantasy_cloud_puff_sides.png', 'fantasy_cloud_puff_front.png', 'fantasy_cloud_puff_sides.png'} + +mobs:register_mob('fantasy_mobs:cloudsmall', { + type = 'monster', + hp_min = 1, hp_max = 2, + collisionbox = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, + visual = 'cube', + visual_size = {x = 0.5, y = 0.5}, + textures = { cloud_textures }, + blood_texture = 'fantasy_cloud_puff_blood.png', + makes_footstep_sound = false, + sounds = green_sounds, + attack_type = 'dogfight', + damage = 4, + passive = false, + walk_velocity = 2, + run_velocity = 2, + walk_chance = 0, + jump_chance = 30, + jump_height = 6, + armor = 100, + view_range = 15, + drops = { + {name = 'epic:float_crystal', chance = 16, min = 0, max = 1}, + {name = 'illuminati:cone_off', chance = 100, min = 0, max = 1}, + {name = 'illuminati:core_off', chance = 100, min = 0, max = 1}, + }, + drawtype = 'front', + water_damage = 0, + lava_damage = 10, + light_damage = 0, +}) + +mobs:register_mob('fantasy_mobs:cloudmedium', { + type = 'monster', + hp_min = 3, hp_max = 4, + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + visual = 'cube', + visual_size = {x = 1, y = 1}, + textures = { cloud_textures }, + blood_texture = 'fantasy_cloud_puff_blood.png', + makes_footstep_sound = false, + sounds = green_sounds, + attack_type = 'dogfight', + damage = 10, + passive = false, + walk_velocity = 2, + run_velocity = 2, + walk_chance = 0, + jump_chance = 30, + jump_height = 6, + armor = 100, + view_range = 15, + on_die = function(self, pos) + local num = math.random(2, 4) + for i=1,num do + minetest.add_entity({x=pos.x + math.random(-2, 2), y=pos.y + 1, z=pos.z + (math.random(-2, 2))}, 'fantasy_mobs:cloudsmall') + end + end, + drawtype = 'front', + water_damage = 0, + lava_damage = 10, + light_damage = 0, +}) + +mobs:register_mob('fantasy_mobs:cloudbig', { + type = 'monster', + hp_min = 5, hp_max = 6, + collisionbox = {-1, -1, -1, 1, 1, 1}, + visual = 'cube', + visual_size = {x = 2, y = 2}, + textures = { cloud_textures }, + blood_texture = 'fantasy_cloud_puff_blood.png', + makes_footstep_sound = false, + sounds = green_sounds, + attack_type = 'dogfight', + attacks_monsters = true, + damage = 15, + passive = false, + walk_velocity = 2, + run_velocity = 2, + walk_chance = 0, + jump_chance = 30, + jump_height = 6, + armor = 100, + view_range = 15, + on_die = function(self, pos) + local num = math.random(1, 2) + for i=1,num do + minetest.add_entity({x=pos.x + math.random(-2, 2), y=pos.y + 1, z=pos.z + (math.random(-2, 2))}, 'fantasy_mobs:cloudmedium') + end + end, + drawtype = 'front', + water_damage = 0, + lava_damage = 10, + light_damage = 0, +}) + +mobs:spawn({ + name = 'fantasy_mobs:cloudbig', + nodes = {'default:water_source', 'default:water_flowing'}, + min_height = 300, + max_height = 1000, + interval = 60, + chance = 2500, + active_object_count = 4, +}) diff --git a/mods/fantasy_mobs/fairy.lua b/mods/fantasy_mobs/fairy.lua new file mode 100644 index 0000000..deea37d --- /dev/null +++ b/mods/fantasy_mobs/fairy.lua @@ -0,0 +1,101 @@ +drops = { + 'stations:scroll_teleport', 'stations:scroll_healing', 'stations:scroll_bloodstone_powder', + 'stations:scroll_anti_fire', 'stations:scroll_chitin', 'stations:scroll_sulfur_dust', + 'stations:scroll_gunpowder', 'stations:scroll_poison', 'epic:deed', +} + +mobs:register_mob('fantasy_mobs:fairy', { + description = 'Fairy', + type = 'npc', + passive = false, + damage = 200, + attack_monsters = true, + attack_type = 'dogfight', + hp_min = 400, + hp_max = 500, + armor = 5, + collisionbox = {-.2,.7,-.2, .2,1.1,.2}, + visual = 'mesh', + mesh = 'fantasy_fairy.b3d', + textures = { + {'fantasy_fairy.png'}, + }, + visual_size = {x = 4, y = 4}, + glow = 14, + fly = true, + fly_in = 'air', + stand_chance = 0, + stay_near = 'group:flower', + replace_rate = 1, + replace_what = {'group:flower'}, + replace_with = 'fantasy_mobs:fairy_mushroom', + walk_velocity = .25, + run_velocity = .5, + water_damage = 100, + lava_damage = 200, + light_damage = 200, + view_range = 5, + animation = { + fly_start = 0, + fly_end = 60, + stand_start = 0, + stand_end = 60, + punch_start = 0, + punch_end = 60, + }, + on_rightclick = function(self, clicker) + local item = clicker:get_wielded_item() + local pos = self.object:get_pos() + local player_name = clicker:get_player_name() + if item:get_name() == 'fantasy_mobs:fairy_mushroom' then + minetest.add_item(pos, {name = drops[math.random(1, #drops)]}) + item:take_item(1) + clicker:set_wielded_item(item) + else + minetest.chat_send_player(player_name, 'you fool, die!') + clicker:set_hp(-50) + end + end, +}) + +mobs:spawn({ + name = 'fantasy_mobs:fairy', + nodes = {'group:flower'}, + neighbors = 'default:dirt_with_grass', + max_light = 8, + min_height = -3, + max_height = 150, + interval = 30, + chance = 200, + active_object_count = 1, +}) + +--nodes +minetest.register_node('fantasy_mobs:fairy_mushroom', { + description = 'Fairy mushroom', + drawtype = 'plantlike', + tiles = {'fantasy_mushrooms.png'}, + groups = { snappy=3, flammable=2, flower=1, flora=1, attached_node=1, not_in_creative_inventory=1}, + sunlight_propagates = true, + waving = 1, + walkable = false, + pointable = true, + diggable = true, + buildable_to = true, + paramtype = 'light', + light_source = 4, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = 'fixed', + fixed = { -0.4, -0.5, -0.4, 0.4, 0.0, 0.4 }, + }, +}) + +minetest.register_abm({ + nodenames = {'fantasy_mobs:fairy_mushroom'}, + interval = 100, + chance = 10, + action = function(pos, node) + minetest.remove_node(pos) + end, +}) diff --git a/mods/fantasy_mobs/gnomes.lua b/mods/fantasy_mobs/gnomes.lua new file mode 100644 index 0000000..347df98 --- /dev/null +++ b/mods/fantasy_mobs/gnomes.lua @@ -0,0 +1,86 @@ +mobs:register_mob('fantasy_mobs:gnome', { + description = 'Gnome', + type = 'npc', + passive = false, + damage = 2, + attack_monsters = false, + attack_type = 'dogfight', + hp_min = 40, + hp_max = 50, + armor = 100, + light_damage = 3, + light_damage_min = 0, + light_damage_max = 8, + collisionbox = {-.2,-.3,-.2, .2,.6,.2}, + visual = 'mesh', + mesh = 'fantasy_gnome.b3d', + textures = { + {'fantasy_gnome_blue.png'}, + {'fantasy_gnome_green.png'}, + {'fantasy_gnome_orange.png'}, + {'fantasy_gnome_purple.png'}, + {'fantasy_gnome_red.png'}, + }, + visual_size = {x = 5, y = 5}, + stay_near = 'group:flower', + follow = {'mobs:honey', 'xdecor:honey'}, + replace_rate = 10, + replace_what = { + {'epic:scorched_dirt', 'default:dirt', 0}, + {'group:fruit', 'air', 0}, + }, + walk_velocity = .5, + run_velocity = 1, + water_damage = 1, + lava_damage = 2, + view_range = 5, + animation = { + stand_start = 0, + stand_end = 1, + walk_start = 0, + walk_end = 50, + punch_start = 0, + punch_end = 60, + }, + sounds = { + random = "gnome_happy", + attack = "gnome_angry", + damage = "gnome_confused", + distance = 5, + }, + drops = { + {name = 'bonemeal:bonemeal', chance = 40, min = 1, max = 3}, + {name = 'default:grass_1', chance = 10, min = 1, max = 7}, + {name = 'stations:scroll_coffee_grounds', chance = 20, min = 1, max = 1}, + {name = 'illuminati:cone_off', chance = 250, min = 0, max = 1}, + {name = 'illuminati:core_off', chance = 250, min = 0, max = 1}, + }, + runaway_from = {'mobs_animal:kitten'}, + do_custom = function(self, dtime) + self.dtime = (self.dtime or 0) + dtime + if self.dtime < 60 then + return + end + self.dtime = 0 + local gnome_pos = self.object:get_pos() + local pos = {x=gnome_pos.x, y=gnome_pos.y - 1, z=gnome_pos.z} + bonemeal:on_use(pos, 1) + bonemeal:on_use(gnome_pos, 3) + end, + on_rightclick = function(self, clicker) + if mobs:feed_tame(self, clicker, 12, false, false) then return end + if mobs:capture_mob(self, clicker, 1, 95, 0, false, 'fantasy_mobs:gnome') then return end + end, +}) + +mobs:spawn({ + name = 'fantasy_mobs:gnome', + nodes = {'epic:scorched_dirt', 'default:dirt_with_grass'}, + min_height = -3, + max_height = 150, + interval = 93, + chance = 5000, + active_object_count = 4, +}) + +mobs:register_egg('fantasy_mobs:gnome', 'Gnome', 'fantasy_gnome_inv.png', 0, true) diff --git a/mods/fantasy_mobs/goblins.lua b/mods/fantasy_mobs/goblins.lua new file mode 100644 index 0000000..b254183 --- /dev/null +++ b/mods/fantasy_mobs/goblins.lua @@ -0,0 +1,146 @@ +local search_replace2 = function( + self, + search_rate, + search_rate_above, + search_rate_below, + search_offset, + search_offset_above, + search_offset_below, + replace_rate, + replace_what, + replace_with) + + if math.random(1, search_rate) == 1 then + local pos = self.object:get_pos() -- + local pos1 = self.object:get_pos() + local pos2 = self.object:get_pos() + + -- if we are looking, will we look below and by how much? + if math.random(1, search_rate_below) == 1 then + pos1.y = pos1.y - search_offset_below + end + + -- if we are looking, will we look above and by how much? + if math.random(1, search_rate_above) == 1 then + pos2.y = pos2.y + search_offset_above + end + + pos1.x = pos1.x - search_offset + pos1.z = pos1.z - search_offset + pos2.x = pos2.x + search_offset + pos2.z = pos2.z + search_offset + + local nodelist = minetest.find_nodes_in_area(pos1, pos2, replace_what) + if #nodelist > 0 then + for key,value in pairs(nodelist) do + -- ok we see some nodes around us, are we going to replace them? + if math.random(1, replace_rate) == 1 then + minetest.set_node(value, {name = replace_with}) + end + minetest.sound_play(self.sounds.replace, { + object = self.object, + max_hear_distance = self.sounds.distance + }) + end + end + end +end + +local goblin_sounds = { + random = "goblins_goblin_ambient", + warcry = "goblins_goblin_attack", + attack = "goblins_goblin_attack", + damage = "goblins_goblin_damage", + death = "goblins_goblin_death", + distance = 7, +} + +mobs:register_mob('fantasy_mobs:goblin', { + description = 'Goblin', + type = 'monster', + passive = false, + damage = 8, + attack_type = 'dogfight', + hp_min = 20, + hp_max = 50, + armor = 100, + collisionbox = {-0.35,-1,-0.35, 0.35,-.1,0.35}, + visual = 'mesh', + mesh = 'fantasy_goblin.b3d', + textures = { + {'fantasy_goblin_1.png'}, + {'fantasy_goblin_2.png'}, + {'fantasy_goblin_3.png'}, + {'fantasy_goblin_4.png'}, + {'fantasy_goblin_5.png'}, + {'fantasy_goblin_6.png'}, + {'fantasy_goblin_7.png'}, + {'fantasy_goblin_8.png'}, + {'fantasy_goblin_9.png'}, + {'fantasy_goblin_10.png'}, + {'fantasy_goblin_11.png'}, + {'fantasy_goblin_12.png'}, + }, + makes_footstep_sound = true, + sounds = goblin_sounds, + walk_velocity = 2, + run_velocity = 3, + jump = true, + drops = { + {name = 'default:mossycobble', chance = 1, min = 1, max = 3}, + {name = 'default:apple', chance = 2, min = 1, max = 2}, + {name = 'default:torch', chance = 3, min = 1, max = 10}, + {name = 'default:coal_lump', chance = 10, min = 1, max = 15}, + {name = 'stations:scroll_anti_fire', chance = 30, min = 1, max = 1}, + {name = 'stations:scroll_sulfur_dust', chance = 30, min = 1, max = 1}, + {name = 'stations:scroll_gunpowder', chance = 30, min = 1, max = 1}, + {name = 'default:diamond', chance = 500, min = 0, max = 20}, + {name = 'farming:coffee_beans', chance = 300, min = 0, max = 5}, + {name = 'stations:scroll_ash', chance = 1, min = 0, max = 1}, + {name = 'epic:reaver', chance = 150, min = 0, max = 1}, + {name = 'illuminati:cone_off', chance = 150, min = 0, max = 1}, + {name = 'illuminati:core_off', chance = 150, min = 0, max = 1}, + }, + water_damage = 0, + lava_damage = 2, + light_damage = 0, + follow = {'default:diamond', 'default:apple', 'farming:bread'}, + view_range = 10, + animation = { + speed_normal = 30, + speed_run = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 168, + run_end = 187, + punch_start = 200, + punch_end = 219, + }, + replace_what = {'default:torch', 'default:torch_wall', 'default:torch_ceiling'}, + do_custom = function(self) + search_replace2( + self, + 10, --search_rate + 1, --search_rate_above + 1, --search_rate_below + 1, --search_offset + 2, --search_offset_above + 1, --search_offset_below + 5, --replace_rate + {'default:torch', 'default:torch_wall', 'default:torch_ceiling'}, --replace_what + 'air') --replace_with + end, +}) + +mobs:spawn({ + name = 'fantasy_mobs:goblin', + nodes = {'default:mossycobble'}, + max_light = 13, + min_height = -31000, + max_height = -10, + interval = 30, + chance = 250, + active_object_count = 10, +}) diff --git a/mods/fantasy_mobs/init.lua b/mods/fantasy_mobs/init.lua new file mode 100644 index 0000000..aa2243d --- /dev/null +++ b/mods/fantasy_mobs/init.lua @@ -0,0 +1,7 @@ +dofile(minetest.get_modpath('fantasy_mobs')..'/cloudpuff.lua') +dofile(minetest.get_modpath('fantasy_mobs')..'/goblins.lua') +dofile(minetest.get_modpath('fantasy_mobs')..'/fairy.lua') +dofile(minetest.get_modpath('fantasy_mobs')..'/mummy.lua') +dofile(minetest.get_modpath('fantasy_mobs')..'/larva.lua') +dofile(minetest.get_modpath('fantasy_mobs')..'/gnomes.lua') +dofile(minetest.get_modpath('fantasy_mobs')..'/cavefreak.lua') diff --git a/mods/fantasy_mobs/larva.lua b/mods/fantasy_mobs/larva.lua new file mode 100644 index 0000000..0f74dac --- /dev/null +++ b/mods/fantasy_mobs/larva.lua @@ -0,0 +1,147 @@ +mobs:register_mob('fantasy_mobs:larva', { + description = 'Larva', + type = 'monster', + damage = 30, + attack_type = 'dogfight', + hp_min = 40, + hp_max = 100, + armor = 75, + collisionbox = {-.35,-.05,-.35,.35,.3,.35}, + visual = 'mesh', + mesh = 'fantasy_larva.b3d', + textures = { + {'fantasy_larva.png'}, + }, + visual_size = {x = 10, y = 10}, + walk_velocity = 1, + run_velocity = 3, + water_damage = 0, + lava_damage = 10, + view_range = 5, + reach = 2, + replace_rate = 1, + replace_what = { + {'default:obsidian', 'fantasy_mobs:larva_egg', 0}, + }, + drops = { + {name = 'fantasy_mobs:larva_egg', chance = 100, min = 0, max = 1}, + }, + runaway_from = {'fantasy_mobs:larva_pet'}, + animation = { + walk_start = 1, + walk_end = 59, + punch_start = 61, + punch_end = 100, + }, +}) + +mobs:register_mob('fantasy_mobs:larva_pet', { + description = 'Larva pet', + type = 'npc', + passive = false, + attack_type = 'dogfight', + owner_loyal = true, + pathfinding = true, + damage = 7, + hp_min = 20, + hp_max = 60, + armor = 75, + collisionbox = {-.35,-.05,-.35,.35,.3,.35}, + visual = 'mesh', + mesh = 'fantasy_larva.b3d', + textures = { + {'fantasy_larva.png'}, + }, + visual_size = {x = 10, y = 10}, + walk_velocity = 1, + run_velocity = 3, + water_damage = 0, + lava_damage = 10, + light_damage = 1, + view_range = 5, + fear_height = 2, + follow = 'default:obsidian_shard', + owner = '', + order = 'follow', + reach = 2, + animation = { + walk_start = 1, + walk_end = 59, + punch_start = 61, + punch_end = 100, + }, + on_spawn = function(self) + local pos = self.object:get_pos() + local objs = minetest.get_objects_inside_radius(pos, 4) + for _, obj in pairs(objs) do + if obj:is_player() then + local owner = obj:get_player_name() + self.owner = owner + minetest.chat_send_player(owner, "Eww, a nether larva think you're its parent, gross.") + end + end + return true + end, + + on_rightclick = function(self, clicker) + local name = clicker:get_player_name() + if mobs:feed_tame(self, clicker, 10, false, true) then + return + end + if self.owner and self.owner == name then + if self.order == 'follow' then + self.order = 'stand' + minetest.chat_send_player(name, ('Larva holding ground.')) + else + self.order = 'follow' + minetest.chat_send_player(name, ('Larva following you.')) + end + mobs:capture_mob(self, clicker, 20, 0, 100, false, nil) + end + end, +}) + +mobs:spawn({ + name = 'fantasy_mobs:larva', + nodes = {'nether:rack'}, + min_height = -31000, + max_height = -5000, + interval = 31, + chance = 2000, + active_object_count = 15, +}) + +minetest.register_node('fantasy_mobs:larva_egg', { + description = 'Larva egg', + drawtype = 'mesh', + mesh = 'fantasy_mobs_larva_egg.obj', + tiles = {'fantasy_larva.png'}, + paramtype = 'light', + groups = {oddly_breakable_by_hand=1}, + selection_box = { + type = 'fixed', + fixed = {-.2, -.5, -.2, .2, -.1, .2}, -- Right, Bottom, Back, Left, Top, Front + }, + collision_box = { + type = 'fixed', + fixed = {-.2, -.5, -.2, .2, -.1, .2}, -- Right, Bottom, Back, Left, Top, Front + }, + on_construct = function(pos) + local fpos, num = minetest.find_nodes_in_area( + {x = pos.x+2, y = pos.y, z = pos.z+2}, + {x = pos.x-2, y = pos.y-1, z = pos.z-2}, + 'nether:sand') + if #fpos >= 9 then + if pos.y > 0 then + local timer = minetest.get_node_timer(pos) + timer:start(300) + end + end + end, + on_timer = function(pos) + minetest.add_entity(pos, 'fantasy_mobs:larva_pet') + minetest.remove_node(pos) + end, +}) + +mobs:register_egg('fantasy_mobs:larva_pet', 'Nether Larva', 'fantasy_mobs_larva_pet.png', 0, true) diff --git a/mods/fantasy_mobs/license.txt b/mods/fantasy_mobs/license.txt new file mode 100644 index 0000000..b741422 --- /dev/null +++ b/mods/fantasy_mobs/license.txt @@ -0,0 +1,20 @@ +GOBLINS pulled from: +https://forum.minetest.net/viewtopic.php?f=9&t=13004 +https://github.com/FreeLikeGNU/mobs_goblins +License of Media Files: +--------------------------------------- +* fantasy_goblin.b3d and goblins_goblin.blend +Copyright 2015 by Francisco "FreeLikeGNU" Athens Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + + * above meshes based on character from minetest_game +by MirceaKitsune (WTFPL) +https://github.com/minetest/minetest_game/blob/master/mods/default/README.txt#L71 + +* fantasy_goblins*.png files +Copyright 2015 by Francisco "FreeLikeGNU" Athens Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +* Sound files by: + * artisticdude http://opengameart.org/content/goblins-sound-pack CC0-license + * Ogrebane http://opengameart.org/content/monster-sound-pack-volume-1 CC0-license diff --git a/mods/fantasy_mobs/mod.conf b/mods/fantasy_mobs/mod.conf new file mode 100644 index 0000000..5e22fdf --- /dev/null +++ b/mods/fantasy_mobs/mod.conf @@ -0,0 +1,2 @@ +name = fantasy_mobs +depends = mobs diff --git a/mods/fantasy_mobs/models/fantasy_cavefreak.b3d b/mods/fantasy_mobs/models/fantasy_cavefreak.b3d new file mode 100644 index 0000000..8c67012 Binary files /dev/null and b/mods/fantasy_mobs/models/fantasy_cavefreak.b3d differ diff --git a/mods/fantasy_mobs/models/fantasy_fairy.b3d b/mods/fantasy_mobs/models/fantasy_fairy.b3d new file mode 100644 index 0000000..5c60aa7 Binary files /dev/null and b/mods/fantasy_mobs/models/fantasy_fairy.b3d differ diff --git a/mods/fantasy_mobs/models/fantasy_gnome.b3d b/mods/fantasy_mobs/models/fantasy_gnome.b3d new file mode 100644 index 0000000..e2c03b5 Binary files /dev/null and b/mods/fantasy_mobs/models/fantasy_gnome.b3d differ diff --git a/mods/fantasy_mobs/models/fantasy_goblin.b3d b/mods/fantasy_mobs/models/fantasy_goblin.b3d new file mode 100644 index 0000000..62ec56f Binary files /dev/null and b/mods/fantasy_mobs/models/fantasy_goblin.b3d differ diff --git a/mods/fantasy_mobs/models/fantasy_larva.b3d b/mods/fantasy_mobs/models/fantasy_larva.b3d new file mode 100644 index 0000000..edcab62 Binary files /dev/null and b/mods/fantasy_mobs/models/fantasy_larva.b3d differ diff --git a/mods/fantasy_mobs/models/fantasy_mobs_larva_egg.obj b/mods/fantasy_mobs/models/fantasy_mobs_larva_egg.obj new file mode 100644 index 0000000..aed1ce4 --- /dev/null +++ b/mods/fantasy_mobs/models/fantasy_mobs_larva_egg.obj @@ -0,0 +1,105 @@ +# Blender v2.80 (sub 75) OBJ File: 'Nether_larva.blend' +# www.blender.org +o Egg_Sphere +v -0.000000 -0.194516 -0.118695 +v 0.000000 -0.335938 -0.200000 +v 0.000000 -0.477359 -0.141421 +v 0.102793 -0.194516 -0.059348 +v 0.173205 -0.335938 -0.100000 +v 0.122475 -0.477359 -0.070711 +v 0.102793 -0.194516 0.059348 +v 0.173205 -0.335938 0.100000 +v 0.122475 -0.477359 0.070711 +v -0.000000 -0.194516 0.118695 +v -0.000000 -0.335938 0.200000 +v -0.000000 -0.477359 0.141421 +v 0.000000 -0.507432 0.000000 +v -0.000000 -0.135937 0.000000 +v -0.102793 -0.194516 0.059348 +v -0.173205 -0.335938 0.100000 +v -0.122475 -0.477359 0.070711 +v -0.102793 -0.194516 -0.059348 +v -0.173205 -0.335938 -0.100000 +v -0.122475 -0.477359 -0.070711 +vt 0.220689 0.596268 +vt 0.228165 0.645021 +vt 0.213214 0.645021 +vt 0.228165 0.693775 +vt 0.228165 0.742528 +vt 0.213214 0.742528 +vt 0.213214 0.693775 +vt 0.220689 0.791281 +vt 0.205738 0.596268 +vt 0.198263 0.645021 +vt 0.198263 0.742528 +vt 0.198263 0.693775 +vt 0.205738 0.791281 +vt 0.190787 0.596268 +vt 0.183312 0.645021 +vt 0.183312 0.742528 +vt 0.183312 0.693775 +vt 0.190787 0.791281 +vt 0.175836 0.596268 +vt 0.168361 0.645021 +vt 0.168361 0.742528 +vt 0.168361 0.693775 +vt 0.175836 0.791281 +vt 0.258067 0.742528 +vt 0.250591 0.791281 +vt 0.243116 0.742528 +vt 0.250591 0.596268 +vt 0.258067 0.645021 +vt 0.243116 0.645021 +vt 0.258067 0.693775 +vt 0.243116 0.693775 +vt 0.235640 0.791281 +vt 0.235640 0.596268 +vn 0.1192 -0.9712 -0.2065 +vn 0.4476 0.4457 -0.7753 +vn 0.4706 -0.3377 -0.8152 +vn 0.2476 0.8688 -0.4288 +vn 0.2385 -0.9712 0.0000 +vn 0.8952 0.4457 0.0000 +vn 0.9413 -0.3377 0.0000 +vn 0.4951 0.8688 0.0000 +vn 0.1192 -0.9712 0.2065 +vn 0.4476 0.4457 0.7753 +vn 0.4706 -0.3377 0.8152 +vn 0.2476 0.8688 0.4288 +vn -0.1192 -0.9712 0.2065 +vn -0.4476 0.4457 0.7753 +vn -0.4706 -0.3377 0.8152 +vn -0.2476 0.8688 0.4288 +vn -0.4951 0.8688 0.0000 +vn -0.2385 -0.9712 -0.0000 +vn -0.8952 0.4457 -0.0000 +vn -0.9413 -0.3377 -0.0000 +vn -0.4706 -0.3377 -0.8152 +vn -0.2476 0.8688 -0.4288 +vn -0.1192 -0.9712 -0.2065 +vn -0.4476 0.4457 -0.7753 +s off +f 13/1/1 3/2/1 6/3/1 +f 2/4/2 1/5/2 4/6/2 5/7/2 +f 3/2/3 2/4/3 5/7/3 6/3/3 +f 1/5/4 14/8/4 4/6/4 +f 13/9/5 6/3/5 9/10/5 +f 5/7/6 4/6/6 7/11/6 8/12/6 +f 6/3/7 5/7/7 8/12/7 9/10/7 +f 4/6/8 14/13/8 7/11/8 +f 13/14/9 9/10/9 12/15/9 +f 8/12/10 7/11/10 10/16/10 11/17/10 +f 9/10/11 8/12/11 11/17/11 12/15/11 +f 7/11/12 14/18/12 10/16/12 +f 13/19/13 12/15/13 17/20/13 +f 11/17/14 10/16/14 15/21/14 16/22/14 +f 12/15/15 11/17/15 16/22/15 17/20/15 +f 10/16/16 14/23/16 15/21/16 +f 15/24/17 14/25/17 18/26/17 +f 13/27/18 17/28/18 20/29/18 +f 16/30/19 15/24/19 18/26/19 19/31/19 +f 17/28/20 16/30/20 19/31/20 20/29/20 +f 20/29/21 19/31/21 2/4/21 3/2/21 +f 18/26/22 14/32/22 1/5/22 +f 13/33/23 20/29/23 3/2/23 +f 19/31/24 18/26/24 1/5/24 2/4/24 diff --git a/mods/fantasy_mobs/models/fantasy_mummy.x b/mods/fantasy_mobs/models/fantasy_mummy.x new file mode 100644 index 0000000..b38c335 --- /dev/null +++ b/mods/fantasy_mobs/models/fantasy_mummy.x @@ -0,0 +1,8573 @@ +xof 0303txt 0032 + +template XSkinMeshHeader { + <3cf169ce-ff7c-44ab-93c0-f78f62d172e2> + WORD nMaxSkinWeightsPerVertex; + WORD nMaxSkinWeightsPerFace; + WORD nBones; +} + +template SkinWeights { + <6f0d123b-bad2-4167-a0d0-80224f25fabb> + STRING transformNodeName; + DWORD nWeights; + array DWORD vertexIndices[nWeights]; + array float weights[nWeights]; + Matrix4x4 matrixOffset; +} + +Frame Root { + FrameTransformMatrix { + 1.000000, 0.000000, 0.000000, 0.000000, + 0.000000, 0.000000, 1.000000, 0.000000, + 0.000000, 1.000000,-0.000000, 0.000000, + 0.000000, 0.000000, 0.000000, 1.000000;; + } + Frame Armature { + FrameTransformMatrix { + 1.000000, 0.000000, 0.000000, 0.000000, + 0.000000, 1.000000, 0.000000, 0.000000, + 0.000000, 0.000000, 1.000000, 0.000000, + 0.000000, 0.000000, 0.000000, 1.000000;; + } + Frame Armature_Root { + FrameTransformMatrix { + 1.000000, 0.000000, 0.000000, 0.000000, + 0.000000, 0.000000, 1.000000, 0.000000, + 0.000000,-1.000000, 0.000000, 0.000000, + 0.000000, 0.000000, 0.001246, 1.000000;; + } + Frame Armature_Body { + FrameTransformMatrix { + 1.000000, 0.000000, 0.000000, 0.000000, + 0.000000, 1.000000, 0.000000, 0.000000, + 0.000000, 0.000000, 1.000000, 0.000000, + 0.000000, 0.855036, 0.000000, 1.000000;; + } + Frame Armature_Bone_001 { + FrameTransformMatrix { + 0.995733, 0.092285,-0.000000, 0.000000, + 0.092285,-0.995732,-0.000000, 0.000000, + -0.000000, 0.000000,-1.000000, 0.000000, + 0.225856, 0.800000, 0.000000, 1.000000;; + } + } //End of Armature_Bone_001 + Frame Armature_Bone_002 { + FrameTransformMatrix { + 0.995624,-0.093449,-0.000000, 0.000000, + -0.093449,-0.995624,-0.000000, 0.000000, + -0.000000, 0.000000,-1.000000, 0.000000, + -0.238835, 0.800000, 0.000000, 1.000000;; + } + } //End of Armature_Bone_002 + Frame Armature_Bone_003 { + FrameTransformMatrix { + 1.000000,-0.000000,-0.000000, 0.000000, + -0.000000,-1.000000,-0.000001, 0.000000, + -0.000000, 0.000001,-1.000000, 0.000000, + -0.144872, 0.061513, 0.000000, 1.000000;; + } + } //End of Armature_Bone_003 + Frame Armature_Bone_004 { + FrameTransformMatrix { + 1.000000,-0.000000,-0.000000, 0.000000, + -0.000000,-1.000000,-0.000001, 0.000000, + -0.000000, 0.000001,-1.000000, 0.000000, + 0.135398, 0.070410, 0.000000, 1.000000;; + } + } //End of Armature_Bone_004 + Frame Armature_Bone_005 { + FrameTransformMatrix { + 1.000000,-0.000000,-0.000000, 0.000000, + 0.000000, 0.999976,-0.006964, 0.000000, + 0.000000, 0.006964, 0.999976, 0.000000, + -0.002513, 0.866015, 0.122502, 1.000000;; + } + Frame Armature_Bone_006 { + FrameTransformMatrix { + 0.101367,-0.994825,-0.006928, 0.000000, + 0.000001, 0.006964,-0.999976, 0.000000, + 0.994849, 0.101365, 0.000707, 0.000000, + -0.000000, 0.306782, 0.000000, 1.000000;; + } + Frame Armature_Bone_007 { + FrameTransformMatrix { + 0.101366, 0.000001, 0.994849, 0.000000, + 0.570623, 0.819152,-0.058142, 0.000000, + -0.814932, 0.573577, 0.083034, 0.000000, + 0.078315, 0.084604,-0.007980, 1.000000;; + } + } //End of Armature_Bone_007 + } //End of Armature_Bone_006 + } //End of Armature_Bone_005 + Frame Armature_Body_001 { + FrameTransformMatrix { + 1.000000, 0.000000,-0.000000, 0.000000, + -0.000000,-1.000000,-0.000000, 0.000000, + -0.000000, 0.000000,-1.000000, 0.000000, + 0.000000, 0.187946,-0.206990, 1.000000;; + } + } //End of Armature_Body_001 + Frame Armature_Body_002 { + FrameTransformMatrix { + 1.000000,-0.000000, 0.000000, 0.000000, + 0.000000,-1.000000,-0.000000, 0.000000, + 0.000000, 0.000000,-1.000000, 0.000000, + 0.000000, 0.185728, 0.203380, 1.000000;; + } + } //End of Armature_Body_002 + } //End of Armature_Body + Frame Armature_IK_Right_Leg { + FrameTransformMatrix { + 1.000000, 0.000000,-0.000000, 0.000000, + -0.000000,-1.000000,-0.000001, 0.000000, + -0.000000, 0.000001,-1.000000, 0.000000, + 0.135398, 0.015523, 0.000000, 1.000000;; + } + } //End of Armature_IK_Right_Leg + Frame Armature_IK_Left_Leg { + FrameTransformMatrix { + 1.000000, 0.000000,-0.000000, 0.000000, + -0.000000,-1.000000,-0.000001, 0.000000, + -0.000000, 0.000001,-1.000000, 0.000000, + -0.148583, 0.015523, 0.000000, 1.000000;; + } + } //End of Armature_IK_Left_Leg + Frame Armature_IK_Left_Hand { + FrameTransformMatrix { + 1.000000, 0.000000,-0.000000, 0.000000, + -0.000000,-1.000000,-0.000001, 0.000000, + -0.000000, 0.000001,-1.000000, 0.000000, + -0.316097, 0.754556, 0.000000, 1.000000;; + } + } //End of Armature_IK_Left_Hand + Frame Armature_IK_Right_hand { + FrameTransformMatrix { + 1.000000, 0.000000,-0.000000, 0.000000, + -0.000000,-1.000000,-0.000001, 0.000000, + -0.000000, 0.000001,-1.000000, 0.000000, + 0.304691, 0.744702, 0.000000, 1.000000;; + } + } //End of Armature_IK_Right_hand + Frame Armature_IK_head { + FrameTransformMatrix { + 1.000000,-0.000000,-0.000000, 0.000000, + 0.000000, 0.999976,-0.006964, 0.000000, + 0.000000, 0.006964, 0.999976, 0.000000, + -0.002513, 2.032632,-0.710142, 1.000000;; + } + } //End of Armature_IK_head + } //End of Armature_Root + Frame Sand_monster { + FrameTransformMatrix { + 0.746845, 0.000000, 0.000000, 0.000000, + 0.000000, 0.740784, 0.000000, 0.000000, + 0.000000, 0.000000, 0.740784, 0.000000, + -0.000000, 0.000000, 0.000000, 1.000000;; + } + Mesh { //Cube_000 Mesh + 332; + -0.320902;-0.288770; 0.936493;, + -0.317184;-0.213477; 0.936493;, + -0.317184;-0.213477; 1.431149;, + -0.320902;-0.288770; 1.431149;, + -0.317184;-0.213477; 0.936493;, + -0.106107;-0.213477; 0.936493;, + -0.106107;-0.213477; 1.431149;, + -0.317184;-0.213477; 1.431149;, + -0.106107;-0.213477; 0.936493;, + -0.109825;-0.288770; 0.936493;, + -0.109825;-0.288770; 1.431149;, + -0.106107;-0.213477; 1.431149;, + -0.109825;-0.288770; 0.936493;, + -0.320902;-0.288770; 0.936493;, + -0.320902;-0.288770; 1.431149;, + -0.109825;-0.288770; 1.431149;, + -0.109825;-0.288770; 0.936493;, + -0.106107;-0.213477; 0.936493;, + -0.317184;-0.213477; 0.936493;, + -0.320902;-0.288770; 0.936493;, + -0.320902;-0.288770; 1.431149;, + -0.317184;-0.213477; 1.431149;, + -0.106107;-0.213477; 1.431149;, + -0.109825;-0.288770; 1.431149;, + 0.083499;-0.288770; 0.936493;, + 0.081037;-0.213477; 0.936493;, + 0.081037;-0.213477; 1.431149;, + 0.083499;-0.288770; 1.431149;, + 0.081037;-0.213477; 0.936493;, + 0.297651;-0.213477; 0.936493;, + 0.297651;-0.213477; 1.431149;, + 0.081037;-0.213477; 1.431149;, + 0.297651;-0.213477; 0.936493;, + 0.300113;-0.288770; 0.936493;, + 0.300113;-0.288770; 1.431149;, + 0.297651;-0.213477; 1.431149;, + 0.300113;-0.288770; 0.936493;, + 0.083499;-0.288770; 0.936493;, + 0.083499;-0.288770; 1.431149;, + 0.300113;-0.288770; 1.431149;, + 0.300113;-0.288770; 0.936493;, + 0.297651;-0.213477; 0.936493;, + 0.081037;-0.213477; 0.936493;, + 0.083499;-0.288770; 0.936493;, + 0.083499;-0.288770; 1.431149;, + 0.081037;-0.213477; 1.431149;, + 0.297651;-0.213477; 1.431149;, + 0.300113;-0.288770; 1.431149;, + -0.167631;-0.323303; 0.771836;, + -0.168232;-0.248010; 0.771836;, + -0.168232;-0.248010; 1.438394;, + -0.167631;-0.323303; 1.438394;, + -0.168232;-0.248010; 0.771836;, + 0.149701;-0.248010; 0.771836;, + 0.149701;-0.248010; 1.438394;, + -0.168232;-0.248010; 1.438394;, + 0.149701;-0.248010; 0.771836;, + 0.150301;-0.323303; 0.771836;, + 0.150301;-0.323303; 1.438394;, + 0.149701;-0.248010; 1.438394;, + 0.150301;-0.323303; 0.771836;, + -0.167631;-0.323303; 0.771836;, + -0.167631;-0.323303; 1.438394;, + 0.150301;-0.323303; 1.438394;, + 0.150301;-0.323303; 0.771836;, + 0.149701;-0.248010; 0.771836;, + -0.168232;-0.248010; 0.771836;, + -0.167631;-0.323303; 0.771836;, + -0.167631;-0.323303; 1.438394;, + -0.168232;-0.248010; 1.438394;, + 0.149701;-0.248010; 1.438394;, + 0.150301;-0.323303; 1.438394;, + 0.299315;-0.086578; 0.978290;, + 0.299315; 0.101043; 0.978290;, + 0.299315; 0.101043; 2.336183;, + 0.299315;-0.086578; 2.336183;, + 0.299315; 0.101043; 0.978290;, + 0.485414; 0.101043; 0.978290;, + 0.485414; 0.101043; 2.336183;, + 0.299315; 0.101043; 2.336183;, + 0.485414; 0.101043; 0.978290;, + 0.485414;-0.086578; 0.978290;, + 0.485414;-0.086578; 2.336183;, + 0.485414; 0.101043; 2.336183;, + 0.485414;-0.086578; 0.978290;, + 0.299315;-0.086578; 0.978290;, + 0.299315;-0.086578; 2.336183;, + 0.485414;-0.086578; 2.336183;, + 0.485414;-0.086578; 0.978290;, + 0.485414; 0.101043; 0.978290;, + 0.299315; 0.101043; 0.978290;, + 0.299315;-0.086578; 0.978290;, + 0.299315;-0.086578; 2.336183;, + 0.299315; 0.101043; 2.336183;, + 0.485414; 0.101043; 2.336183;, + 0.485414;-0.086578; 2.336183;, + 0.299346; 0.342641; 3.011453;, + 0.299346;-0.285110; 3.011453;, + -0.323311;-0.285110; 3.011453;, + -0.323311; 0.342641; 3.011453;, + 0.299346; 0.342641; 2.590401;, + 0.299346;-0.285110; 2.590401;, + 0.299346;-0.285110; 3.011453;, + 0.299346; 0.342641; 3.011453;, + 0.299346;-0.285110; 2.590401;, + -0.323311;-0.285110; 2.590401;, + -0.323311;-0.285110; 3.011453;, + 0.299346;-0.285110; 3.011453;, + -0.323311;-0.285110; 2.590401;, + -0.323311; 0.342641; 2.590401;, + -0.323311; 0.342641; 3.011453;, + -0.323311;-0.285110; 3.011453;, + -0.323311; 0.342641; 2.590401;, + 0.299346; 0.342641; 2.590401;, + 0.299346; 0.342641; 3.011453;, + -0.323311; 0.342641; 3.011453;, + 0.299346; 0.342641; 2.590401;, + -0.323311; 0.342641; 2.590401;, + -0.323311;-0.285110; 2.590401;, + 0.299346;-0.285110; 2.590401;, + 0.222447; 0.335658; 2.376415;, + 0.222447;-0.063423; 2.376415;, + 0.222447;-0.063423; 2.583114;, + 0.222447; 0.335658; 2.583114;, + 0.222447;-0.063423; 2.376415;, + -0.245101;-0.063423; 2.376415;, + -0.245101;-0.063423; 2.583114;, + 0.222447;-0.063423; 2.583114;, + -0.245101;-0.063423; 2.376415;, + -0.245101; 0.335658; 2.376415;, + -0.245101; 0.335658; 2.583114;, + -0.245101;-0.063423; 2.583114;, + -0.245101; 0.335658; 2.376415;, + 0.222447; 0.335658; 2.376415;, + 0.222447; 0.335658; 2.583114;, + -0.245101; 0.335658; 2.583114;, + -0.245101; 0.335658; 2.376415;, + -0.245101;-0.063423; 2.376415;, + 0.222447;-0.063423; 2.376415;, + 0.222447; 0.335658; 2.376415;, + -0.322044; 0.107436; 0.978290;, + -0.322043;-0.080185; 0.978290;, + -0.322043;-0.080185; 2.336183;, + -0.322044; 0.107436; 2.336183;, + -0.322043;-0.080185; 0.978290;, + -0.508142;-0.080185; 0.978290;, + -0.508142;-0.080185; 2.336183;, + -0.322043;-0.080185; 2.336183;, + -0.508142;-0.080185; 0.978290;, + -0.508142; 0.107436; 0.978290;, + -0.508142; 0.107436; 2.336183;, + -0.508142;-0.080185; 2.336183;, + -0.508142; 0.107436; 0.978290;, + -0.322044; 0.107436; 0.978290;, + -0.322044; 0.107436; 2.336183;, + -0.508142; 0.107436; 2.336183;, + -0.508142; 0.107436; 0.978290;, + -0.508142;-0.080185; 0.978290;, + -0.322043;-0.080185; 0.978290;, + -0.322044; 0.107436; 0.978290;, + -0.322044; 0.107436; 2.336183;, + -0.322043;-0.080185; 2.336183;, + -0.508142;-0.080185; 2.336183;, + -0.508142; 0.107436; 2.336183;, + 0.292988; 0.271646; 1.259217;, + 0.292988;-0.244395; 1.259217;, + 0.292988;-0.244395; 2.334600;, + 0.292988; 0.271646; 2.334600;, + 0.292988;-0.244395; 1.259217;, + -0.316111;-0.244395; 1.259217;, + -0.316111;-0.244395; 2.334600;, + 0.292988;-0.244395; 2.334600;, + -0.316111;-0.244395; 1.259217;, + -0.316111; 0.271646; 1.259217;, + -0.316111; 0.271646; 2.334600;, + -0.316111;-0.244395; 2.334600;, + -0.316111; 0.271646; 1.259217;, + 0.292988; 0.271646; 1.259217;, + 0.292988; 0.271646; 2.334600;, + -0.316111; 0.271646; 2.334600;, + -0.316111; 0.271646; 1.259217;, + -0.316111;-0.244395; 1.259217;, + 0.292988;-0.244395; 1.259217;, + 0.292988; 0.271646; 1.259217;, + 0.292988; 0.271646; 2.334600;, + 0.292988;-0.244395; 2.334600;, + -0.316111;-0.244395; 2.334600;, + -0.316111; 0.271646; 2.334600;, + 0.302371; 0.292906; 0.936493;, + 0.298653; 0.217613; 0.936493;, + 0.298653; 0.217613; 1.431149;, + 0.302371; 0.292906; 1.431149;, + 0.298653; 0.217613; 0.936493;, + 0.087576; 0.217613; 0.936493;, + 0.087576; 0.217613; 1.431149;, + 0.298653; 0.217613; 1.431149;, + 0.087576; 0.217613; 0.936493;, + 0.091294; 0.292906; 0.936493;, + 0.091294; 0.292906; 1.431149;, + 0.087576; 0.217613; 1.431149;, + 0.091294; 0.292906; 0.936493;, + 0.302371; 0.292906; 0.936493;, + 0.302371; 0.292906; 1.431149;, + 0.091294; 0.292906; 1.431149;, + 0.091294; 0.292906; 0.936493;, + 0.087576; 0.217613; 0.936493;, + 0.298653; 0.217613; 0.936493;, + 0.302371; 0.292906; 0.936493;, + 0.302371; 0.292906; 1.431149;, + 0.298653; 0.217613; 1.431149;, + 0.087576; 0.217613; 1.431149;, + 0.091294; 0.292906; 1.431149;, + -0.102030; 0.292906; 0.936493;, + -0.099568; 0.217613; 0.936493;, + -0.099568; 0.217613; 1.431149;, + -0.102030; 0.292906; 1.431149;, + -0.099568; 0.217613; 0.936493;, + -0.316183; 0.217613; 0.936493;, + -0.316183; 0.217613; 1.431149;, + -0.099568; 0.217613; 1.431149;, + -0.316183; 0.217613; 0.936493;, + -0.318644; 0.292906; 0.936493;, + -0.318644; 0.292906; 1.431149;, + -0.316183; 0.217613; 1.431149;, + -0.318644; 0.292906; 0.936493;, + -0.102030; 0.292906; 0.936493;, + -0.102030; 0.292906; 1.431149;, + -0.318644; 0.292906; 1.431149;, + -0.318644; 0.292906; 0.936493;, + -0.316183; 0.217613; 0.936493;, + -0.099568; 0.217613; 0.936493;, + -0.102030; 0.292906; 0.936493;, + -0.102030; 0.292906; 1.431149;, + -0.099568; 0.217613; 1.431149;, + -0.316183; 0.217613; 1.431149;, + -0.318644; 0.292906; 1.431149;, + 0.149100; 0.327439; 0.771836;, + 0.149701; 0.252146; 0.771836;, + 0.149701; 0.252146; 1.438394;, + 0.149100; 0.327439; 1.438394;, + 0.149701; 0.252146; 0.771836;, + -0.168232; 0.252146; 0.771836;, + -0.168232; 0.252146; 1.438394;, + 0.149701; 0.252146; 1.438394;, + -0.168232; 0.252146; 0.771836;, + -0.168833; 0.327439; 0.771836;, + -0.168833; 0.327439; 1.438394;, + -0.168232; 0.252146; 1.438394;, + -0.168833; 0.327439; 0.771836;, + 0.149100; 0.327439; 0.771836;, + 0.149100; 0.327439; 1.438394;, + -0.168833; 0.327439; 1.438394;, + -0.168833; 0.327439; 0.771836;, + -0.168232; 0.252146; 0.771836;, + 0.149701; 0.252146; 0.771836;, + 0.149100; 0.327439; 0.771836;, + 0.149100; 0.327439; 1.438394;, + 0.149701; 0.252146; 1.438394;, + -0.168232; 0.252146; 1.438394;, + -0.168833; 0.327439; 1.438394;, + 0.103285;-0.086578;-0.135133;, + 0.103285; 0.101043;-0.135133;, + 0.103285; 0.101043; 1.222760;, + 0.103285;-0.086578; 1.222760;, + 0.103285; 0.101043;-0.135133;, + 0.289383; 0.101043;-0.135133;, + 0.289383; 0.101043; 1.222760;, + 0.103285; 0.101043; 1.222760;, + 0.289383; 0.101043;-0.135133;, + 0.289383;-0.086578;-0.135133;, + 0.289383;-0.086578; 1.222760;, + 0.289383; 0.101043; 1.222760;, + 0.289383;-0.086578;-0.135133;, + 0.103285;-0.086578;-0.135133;, + 0.103285;-0.086578; 1.222760;, + 0.289383;-0.086578; 1.222760;, + 0.289383;-0.086578;-0.135133;, + 0.289383; 0.101043;-0.135133;, + 0.103285; 0.101043;-0.135133;, + 0.103285;-0.086578;-0.135133;, + 0.103285;-0.086578; 1.222760;, + 0.103285; 0.101043; 1.222760;, + 0.289383; 0.101043; 1.222760;, + 0.289383;-0.086578; 1.222760;, + -0.095249; 0.107436;-0.115250;, + -0.095249;-0.080185;-0.115250;, + -0.095249;-0.080185; 1.242642;, + -0.095249; 0.107436; 1.242642;, + -0.095249;-0.080185;-0.115250;, + -0.281348;-0.080185;-0.115250;, + -0.281348;-0.080185; 1.242642;, + -0.095249;-0.080185; 1.242642;, + -0.281348;-0.080185;-0.115250;, + -0.281348; 0.107436;-0.115250;, + -0.281348; 0.107436; 1.242642;, + -0.281348;-0.080185; 1.242642;, + -0.281348; 0.107436;-0.115250;, + -0.095249; 0.107436;-0.115250;, + -0.095249; 0.107436; 1.242642;, + -0.281348; 0.107436; 1.242642;, + -0.281348; 0.107436;-0.115250;, + -0.281348;-0.080185;-0.115250;, + -0.095249;-0.080185;-0.115250;, + -0.095249; 0.107436;-0.115250;, + -0.095249; 0.107436; 1.242642;, + -0.095249;-0.080185; 1.242642;, + -0.281348;-0.080185; 1.242642;, + -0.281348; 0.107436; 1.242642;, + 0.038491;-0.113120; 2.301639;, + 0.038491;-0.214044; 2.301639;, + 0.038491;-0.214044; 2.635183;, + 0.038491;-0.113120; 2.635183;, + 0.038491;-0.214044; 2.301639;, + -0.061613;-0.214044; 2.301639;, + -0.061613;-0.214044; 2.635183;, + 0.038491;-0.214044; 2.635183;, + -0.061613;-0.214044; 2.301639;, + -0.061614;-0.113120; 2.301639;, + -0.061614;-0.113120; 2.635183;, + -0.061613;-0.214044; 2.635183;, + -0.061614;-0.113120; 2.301639;, + 0.038491;-0.113120; 2.301639;, + 0.038491;-0.113120; 2.635183;, + -0.061614;-0.113120; 2.635183;, + -0.061614;-0.113120; 2.301639;, + -0.061613;-0.214044; 2.301639;, + 0.038491;-0.214044; 2.301639;, + 0.038491;-0.113120; 2.301639;, + 0.038491;-0.113120; 2.635183;, + 0.038491;-0.214044; 2.635183;, + -0.061613;-0.214044; 2.635183;, + -0.061614;-0.113120; 2.635183;; + 83; + 4;0;1;2;3;, + 4;4;5;6;7;, + 4;8;9;10;11;, + 4;12;13;14;15;, + 4;16;17;18;19;, + 4;20;21;22;23;, + 4;24;25;26;27;, + 4;28;29;30;31;, + 4;32;33;34;35;, + 4;36;37;38;39;, + 4;40;41;42;43;, + 4;44;45;46;47;, + 4;48;49;50;51;, + 4;52;53;54;55;, + 4;56;57;58;59;, + 4;60;61;62;63;, + 4;64;65;66;67;, + 4;68;69;70;71;, + 4;72;73;74;75;, + 4;76;77;78;79;, + 4;80;81;82;83;, + 4;84;85;86;87;, + 4;88;89;90;91;, + 4;92;93;94;95;, + 4;96;97;98;99;, + 4;100;101;102;103;, + 4;104;105;106;107;, + 4;108;109;110;111;, + 4;112;113;114;115;, + 4;116;117;118;119;, + 4;120;121;122;123;, + 4;124;125;126;127;, + 4;128;129;130;131;, + 4;132;133;134;135;, + 4;136;137;138;139;, + 4;140;141;142;143;, + 4;144;145;146;147;, + 4;148;149;150;151;, + 4;152;153;154;155;, + 4;156;157;158;159;, + 4;160;161;162;163;, + 4;164;165;166;167;, + 4;168;169;170;171;, + 4;172;173;174;175;, + 4;176;177;178;179;, + 4;180;181;182;183;, + 4;184;185;186;187;, + 4;188;189;190;191;, + 4;192;193;194;195;, + 4;196;197;198;199;, + 4;200;201;202;203;, + 4;204;205;206;207;, + 4;208;209;210;211;, + 4;212;213;214;215;, + 4;216;217;218;219;, + 4;220;221;222;223;, + 4;224;225;226;227;, + 4;228;229;230;231;, + 4;232;233;234;235;, + 4;236;237;238;239;, + 4;240;241;242;243;, + 4;244;245;246;247;, + 4;248;249;250;251;, + 4;252;253;254;255;, + 4;256;257;258;259;, + 4;260;261;262;263;, + 4;264;265;266;267;, + 4;268;269;270;271;, + 4;272;273;274;275;, + 4;276;277;278;279;, + 4;280;281;282;283;, + 4;284;285;286;287;, + 4;288;289;290;291;, + 4;292;293;294;295;, + 4;296;297;298;299;, + 4;300;301;302;303;, + 4;304;305;306;307;, + 4;308;309;310;311;, + 4;312;313;314;315;, + 4;316;317;318;319;, + 4;320;321;322;323;, + 4;324;325;326;327;, + 4;328;329;330;331;; + MeshNormals { //Cube_000 Normals + 332; + -0.998783; 0.049315;-0.000000;, + -0.998783; 0.049315;-0.000000;, + -0.998783; 0.049315;-0.000000;, + -0.998783; 0.049315;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.998783;-0.049314; 0.000000;, + 0.998783;-0.049314; 0.000000;, + 0.998783;-0.049314; 0.000000;, + 0.998783;-0.049314; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.999466;-0.032675; 0.000000;, + -0.999466;-0.032675; 0.000000;, + -0.999466;-0.032675; 0.000000;, + -0.999466;-0.032675; 0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.999466; 0.032675; 0.000000;, + 0.999466; 0.032675; 0.000000;, + 0.999466; 0.032675; 0.000000;, + 0.999466; 0.032675; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.999968;-0.007979; 0.000000;, + -0.999968;-0.007979; 0.000000;, + -0.999968;-0.007979; 0.000000;, + -0.999968;-0.007979; 0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.999968; 0.007979; 0.000000;, + 0.999968; 0.007979; 0.000000;, + 0.999968; 0.007979; 0.000000;, + 0.999968; 0.007979; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -1.000000; 0.000000; 0.000000;, + -1.000000; 0.000000; 0.000000;, + -1.000000; 0.000000; 0.000000;, + -1.000000; 0.000000; 0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + -0.000000;-1.000000; 0.000000;, + -0.000000;-1.000000; 0.000000;, + -0.000000;-1.000000; 0.000000;, + -0.000000;-1.000000; 0.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 1.000000; 0.000000; 0.000000;, + 1.000000; 0.000000; 0.000000;, + 1.000000; 0.000000; 0.000000;, + 1.000000; 0.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + 0.000000;-0.000000;-1.000000;, + 0.000000;-0.000000;-1.000000;, + 0.000000;-0.000000;-1.000000;, + 0.000000;-0.000000;-1.000000;, + 1.000000; 0.000000; 0.000000;, + 1.000000; 0.000000; 0.000000;, + 1.000000; 0.000000; 0.000000;, + 1.000000; 0.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.998783;-0.049314;-0.000000;, + 0.998783;-0.049314;-0.000000;, + 0.998783;-0.049314;-0.000000;, + 0.998783;-0.049314;-0.000000;, + 0.000000;-1.000000;-0.000000;, + 0.000000;-1.000000;-0.000000;, + 0.000000;-1.000000;-0.000000;, + 0.000000;-1.000000;-0.000000;, + -0.998783; 0.049314; 0.000000;, + -0.998783; 0.049314; 0.000000;, + -0.998783; 0.049314; 0.000000;, + -0.998783; 0.049314; 0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.999466; 0.032676; 0.000000;, + 0.999466; 0.032676; 0.000000;, + 0.999466; 0.032676; 0.000000;, + 0.999466; 0.032676; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -0.999466;-0.032675; 0.000000;, + -0.999466;-0.032675; 0.000000;, + -0.999466;-0.032675; 0.000000;, + -0.999466;-0.032675; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + -0.000000; 1.000000; 0.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.999968; 0.007979;-0.000000;, + 0.999968; 0.007979;-0.000000;, + 0.999968; 0.007979;-0.000000;, + 0.999968; 0.007979;-0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -0.999968;-0.007979; 0.000000;, + -0.999968;-0.007979; 0.000000;, + -0.999968;-0.007979; 0.000000;, + -0.999968;-0.007979; 0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + -1.000000; 0.000000;-0.000000;, + -1.000000; 0.000000;-0.000000;, + -1.000000; 0.000000;-0.000000;, + -1.000000; 0.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 0.000000; 1.000000;-0.000000;, + 1.000000;-0.000000; 0.000000;, + 1.000000;-0.000000; 0.000000;, + 1.000000;-0.000000; 0.000000;, + 1.000000;-0.000000; 0.000000;, + -0.000000;-1.000000; 0.000000;, + -0.000000;-1.000000; 0.000000;, + -0.000000;-1.000000; 0.000000;, + -0.000000;-1.000000; 0.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000;-1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + -0.000000; 0.000000; 1.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 1.000000; 0.000000;-0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + 0.000000;-1.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -1.000000;-0.000000; 0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + -0.000000; 1.000000;-0.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000;-1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;, + 0.000000; 0.000000; 1.000000;; + 83; + 4;0;1;2;3;, + 4;4;5;6;7;, + 4;8;9;10;11;, + 4;12;13;14;15;, + 4;16;17;18;19;, + 4;20;21;22;23;, + 4;24;25;26;27;, + 4;28;29;30;31;, + 4;32;33;34;35;, + 4;36;37;38;39;, + 4;40;41;42;43;, + 4;44;45;46;47;, + 4;48;49;50;51;, + 4;52;53;54;55;, + 4;56;57;58;59;, + 4;60;61;62;63;, + 4;64;65;66;67;, + 4;68;69;70;71;, + 4;72;73;74;75;, + 4;76;77;78;79;, + 4;80;81;82;83;, + 4;84;85;86;87;, + 4;88;89;90;91;, + 4;92;93;94;95;, + 4;96;97;98;99;, + 4;100;101;102;103;, + 4;104;105;106;107;, + 4;108;109;110;111;, + 4;112;113;114;115;, + 4;116;117;118;119;, + 4;120;121;122;123;, + 4;124;125;126;127;, + 4;128;129;130;131;, + 4;132;133;134;135;, + 4;136;137;138;139;, + 4;140;141;142;143;, + 4;144;145;146;147;, + 4;148;149;150;151;, + 4;152;153;154;155;, + 4;156;157;158;159;, + 4;160;161;162;163;, + 4;164;165;166;167;, + 4;168;169;170;171;, + 4;172;173;174;175;, + 4;176;177;178;179;, + 4;180;181;182;183;, + 4;184;185;186;187;, + 4;188;189;190;191;, + 4;192;193;194;195;, + 4;196;197;198;199;, + 4;200;201;202;203;, + 4;204;205;206;207;, + 4;208;209;210;211;, + 4;212;213;214;215;, + 4;216;217;218;219;, + 4;220;221;222;223;, + 4;224;225;226;227;, + 4;228;229;230;231;, + 4;232;233;234;235;, + 4;236;237;238;239;, + 4;240;241;242;243;, + 4;244;245;246;247;, + 4;248;249;250;251;, + 4;252;253;254;255;, + 4;256;257;258;259;, + 4;260;261;262;263;, + 4;264;265;266;267;, + 4;268;269;270;271;, + 4;272;273;274;275;, + 4;276;277;278;279;, + 4;280;281;282;283;, + 4;284;285;286;287;, + 4;288;289;290;291;, + 4;292;293;294;295;, + 4;296;297;298;299;, + 4;300;301;302;303;, + 4;304;305;306;307;, + 4;308;309;310;311;, + 4;312;313;314;315;, + 4;316;317;318;319;, + 4;320;321;322;323;, + 4;324;325;326;327;, + 4;328;329;330;331;; + } //End of Cube_000 Normals + MeshMaterialList { //Cube_000 Material List + 1; + 1; + 0;; + Material Default_Material { + 0.800000; 0.800000; 0.800000; 0.800000;; + 96.078431; + 0.500000; 0.500000; 0.500000;; + 0.000000; 0.000000; 0.000000;; + } + } //End of Cube_000 Material List + MeshTextureCoords { //Cube_000 UV Coordinates + 332; + 0.750000; 0.812500;, + 0.734375; 0.812500;, + 0.734375; 0.625000;, + 0.750000; 0.625000;, + 0.750000; 0.812500;, + 0.796875; 0.812500;, + 0.796875; 0.625000;, + 0.750000; 0.625000;, + 0.812500; 0.812500;, + 0.796875; 0.812500;, + 0.796875; 0.625000;, + 0.812500; 0.625000;, + 0.796875; 0.812500;, + 0.750000; 0.812500;, + 0.750000; 0.625000;, + 0.796875; 0.625000;, + 0.796875; 0.812500;, + 0.796875; 0.843750;, + 0.750000; 0.843750;, + 0.750000; 0.812500;, + 0.750000; 0.593750;, + 0.750000; 0.625000;, + 0.796875; 0.625000;, + 0.796875; 0.593750;, + 0.921875; 0.812500;, + 0.906250; 0.812500;, + 0.906250; 0.625000;, + 0.921875; 0.625000;, + 0.921875; 0.812500;, + 0.968750; 0.812500;, + 0.968750; 0.625000;, + 0.921875; 0.625000;, + 0.984375; 0.812500;, + 0.968750; 0.812500;, + 0.968750; 0.625000;, + 0.984375; 0.625000;, + 0.968750; 0.812500;, + 0.921875; 0.812500;, + 0.921875; 0.625000;, + 0.968750; 0.625000;, + 0.968750; 0.812500;, + 0.968750; 0.843750;, + 0.921875; 0.843750;, + 0.921875; 0.812500;, + 0.921875; 0.593750;, + 0.921875; 0.625000;, + 0.968750; 0.625000;, + 0.968750; 0.593750;, + 0.828125; 0.812500;, + 0.812500; 0.812500;, + 0.812500; 0.562500;, + 0.828125; 0.562500;, + 0.890625; 0.812500;, + 0.828125; 0.812500;, + 0.828125; 0.562500;, + 0.890625; 0.562500;, + 0.906250; 0.812500;, + 0.890625; 0.812500;, + 0.890625; 0.562500;, + 0.906250; 0.562500;, + 0.890625; 0.812500;, + 0.828125; 0.812500;, + 0.828125; 0.562500;, + 0.890625; 0.562500;, + 0.890625; 0.812500;, + 0.890625; 0.843750;, + 0.828125; 0.843750;, + 0.828125; 0.812500;, + 0.828125; 0.531250;, + 0.828125; 0.562500;, + 0.890625; 0.562500;, + 0.890625; 0.531250;, + 0.703125; 0.187500;, + 0.703125; 0.250000;, + 0.515625; 0.250000;, + 0.515625; 0.187500;, + 0.703125; 0.125000;, + 0.703125; 0.187500;, + 0.515625; 0.187500;, + 0.515625; 0.125000;, + 0.703125; 0.062500;, + 0.703125; 0.125000;, + 0.515625; 0.125000;, + 0.515625; 0.062500;, + 0.703125; 0.000000;, + 0.703125; 0.062500;, + 0.515625; 0.062500;, + 0.515625; 0.000000;, + 0.703125; 0.125000;, + 0.734375; 0.125000;, + 0.734375; 0.187500;, + 0.703125; 0.187500;, + 0.734375; 0.250000;, + 0.703125; 0.250000;, + 0.703125; 0.187500;, + 0.734375; 0.187500;, + 0.250000; 0.437500;, + 0.250000; 0.187500;, + 0.375000; 0.187500;, + 0.375000; 0.437500;, + 0.375000; 0.000000;, + 0.500000; 0.000000;, + 0.500000; 0.187500;, + 0.375000; 0.187500;, + 0.250000; 0.000000;, + 0.375000; 0.000000;, + 0.375000; 0.187500;, + 0.250000; 0.187500;, + 0.250000; 0.187500;, + 0.125000; 0.187500;, + 0.125000; 0.000000;, + 0.250000; 0.000000;, + 0.125000; 0.187500;, + 0.000000; 0.187500;, + 0.000000; 0.000000;, + 0.125000; 0.000000;, + 0.375000; 0.437500;, + 0.375000; 0.187500;, + 0.500000; 0.187500;, + 0.500000; 0.437500;, + 0.078125; 0.250000;, + 0.000000; 0.250000;, + 0.000000; 0.187500;, + 0.078125; 0.187500;, + 0.078125; 0.375000;, + 0.171875; 0.375000;, + 0.171875; 0.437500;, + 0.078125; 0.437500;, + 0.250000; 0.250000;, + 0.171875; 0.250000;, + 0.171875; 0.187500;, + 0.250000; 0.187500;, + 0.171875; 0.250000;, + 0.078125; 0.250000;, + 0.078125; 0.187500;, + 0.171875; 0.187500;, + 0.078125; 0.250000;, + 0.171875; 0.250000;, + 0.171875; 0.375000;, + 0.078125; 0.375000;, + 0.734375; 0.250000;, + 0.734375; 0.187500;, + 0.921875; 0.187500;, + 0.921875; 0.250000;, + 0.734375; 0.062500;, + 0.734375; 0.000000;, + 0.921875; 0.000000;, + 0.921875; 0.062500;, + 0.734375; 0.125000;, + 0.734375; 0.062500;, + 0.921875; 0.062500;, + 0.921875; 0.125000;, + 0.734375; 0.187500;, + 0.734375; 0.125000;, + 0.921875; 0.125000;, + 0.921875; 0.187500;, + 0.734375; 0.062500;, + 0.703125; 0.062500;, + 0.703125; 0.000000;, + 0.734375; 0.000000;, + 0.703125; 0.062500;, + 0.734375; 0.062500;, + 0.734375; 0.125000;, + 0.703125; 0.125000;, + 0.109375; 1.000000;, + 0.000000; 1.000000;, + 0.000000; 0.625000;, + 0.109375; 0.625000;, + 0.234375; 1.000000;, + 0.109375; 1.000000;, + 0.109375; 0.625000;, + 0.234375; 0.625000;, + 0.234375; 1.000000;, + 0.343750; 1.000000;, + 0.343750; 0.625000;, + 0.234375; 0.625000;, + 0.468750; 1.000000;, + 0.343750; 1.000000;, + 0.343750; 0.625000;, + 0.468750; 0.625000;, + 0.468750; 0.437500;, + 0.468750; 0.625000;, + 0.343750; 0.625000;, + 0.343750; 0.437500;, + 0.109375; 0.625000;, + 0.109375; 0.437500;, + 0.234375; 0.437500;, + 0.234375; 0.625000;, + 0.500000; 0.812500;, + 0.484375; 0.812500;, + 0.484375; 0.625000;, + 0.500000; 0.625000;, + 0.500000; 0.812500;, + 0.546875; 0.812500;, + 0.546875; 0.625000;, + 0.500000; 0.625000;, + 0.562500; 0.812500;, + 0.546875; 0.812500;, + 0.546875; 0.625000;, + 0.562500; 0.625000;, + 0.546875; 0.812500;, + 0.500000; 0.812500;, + 0.500000; 0.625000;, + 0.546875; 0.625000;, + 0.546875; 0.843750;, + 0.546875; 0.812500;, + 0.500000; 0.812500;, + 0.500000; 0.843750;, + 0.500000; 0.625000;, + 0.500000; 0.593750;, + 0.546875; 0.593750;, + 0.546875; 0.625000;, + 0.671875; 0.812500;, + 0.656250; 0.812500;, + 0.656250; 0.625000;, + 0.671875; 0.625000;, + 0.671875; 0.812500;, + 0.718750; 0.812500;, + 0.718750; 0.625000;, + 0.671875; 0.625000;, + 0.734375; 0.812500;, + 0.718750; 0.812500;, + 0.718750; 0.625000;, + 0.734375; 0.625000;, + 0.718750; 0.812500;, + 0.671875; 0.812500;, + 0.671875; 0.625000;, + 0.718750; 0.625000;, + 0.718750; 0.843750;, + 0.718750; 0.812500;, + 0.671875; 0.812500;, + 0.671875; 0.843750;, + 0.671875; 0.625000;, + 0.671875; 0.593750;, + 0.718750; 0.593750;, + 0.718750; 0.625000;, + 0.578125; 0.812500;, + 0.562500; 0.812500;, + 0.562500; 0.562500;, + 0.578125; 0.562500;, + 0.640625; 0.812500;, + 0.578125; 0.812500;, + 0.578125; 0.562500;, + 0.640625; 0.562500;, + 0.656250; 0.812500;, + 0.640625; 0.812500;, + 0.640625; 0.562500;, + 0.656250; 0.562500;, + 0.640625; 0.812500;, + 0.578125; 0.812500;, + 0.578125; 0.562500;, + 0.640625; 0.562500;, + 0.640625; 0.843750;, + 0.640625; 0.812500;, + 0.578125; 0.812500;, + 0.578125; 0.843750;, + 0.578125; 0.562500;, + 0.578125; 0.531250;, + 0.640625; 0.531250;, + 0.640625; 0.562500;, + 0.703125; 0.437500;, + 0.703125; 0.500000;, + 0.515625; 0.500000;, + 0.515625; 0.437500;, + 0.703125; 0.375000;, + 0.703125; 0.437500;, + 0.515625; 0.437500;, + 0.515625; 0.375000;, + 0.703125; 0.312500;, + 0.703125; 0.375000;, + 0.515625; 0.375000;, + 0.515625; 0.312500;, + 0.703125; 0.250000;, + 0.703125; 0.312500;, + 0.515625; 0.312500;, + 0.515625; 0.250000;, + 0.734375; 0.312500;, + 0.734375; 0.375000;, + 0.703125; 0.375000;, + 0.703125; 0.312500;, + 0.703125; 0.312500;, + 0.703125; 0.250000;, + 0.734375; 0.250000;, + 0.734375; 0.312500;, + 0.734375; 0.312500;, + 0.734375; 0.250000;, + 0.921875; 0.250000;, + 0.921875; 0.312500;, + 0.734375; 0.500000;, + 0.734375; 0.437500;, + 0.921875; 0.437500;, + 0.921875; 0.500000;, + 0.734375; 0.437500;, + 0.734375; 0.375000;, + 0.921875; 0.375000;, + 0.921875; 0.437500;, + 0.734375; 0.375000;, + 0.734375; 0.312500;, + 0.921875; 0.312500;, + 0.921875; 0.375000;, + 0.734375; 0.437500;, + 0.734375; 0.500000;, + 0.703125; 0.500000;, + 0.703125; 0.437500;, + 0.703125; 0.437500;, + 0.703125; 0.375000;, + 0.734375; 0.375000;, + 0.734375; 0.437500;, + 0.046875; 0.250000;, + 0.062500; 0.250000;, + 0.062500; 0.375000;, + 0.046875; 0.375000;, + 0.031250; 0.250000;, + 0.046875; 0.250000;, + 0.046875; 0.375000;, + 0.031250; 0.375000;, + 0.015625; 0.250000;, + 0.031250; 0.250000;, + 0.031250; 0.375000;, + 0.015625; 0.375000;, + 0.000000; 0.250000;, + 0.015625; 0.250000;, + 0.015625; 0.375000;, + 0.000000; 0.375000;, + 0.062500; 0.281250;, + 0.062500; 0.250000;, + 0.078125; 0.250000;, + 0.078125; 0.281250;, + 0.078125; 0.281250;, + 0.078125; 0.312500;, + 0.062500; 0.312500;, + 0.062500; 0.281250;; + } //End of Cube_000 UV Coordinates + XSkinMeshHeader { + 2; + 6; + 10; + } + SkinWeights { + "Armature_Body"; + 168; + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259; + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000001, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000001, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000001, + 0.000000, + 0.000000, + 0.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.000001, + 0.000000, + 0.000134, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000134, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000001, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000001, + 0.000000, + 0.000134, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000; + 0.746845, 0.000000, 0.000000, 0.000000, + 0.000000, 0.000000,-0.740784, 0.000000, + 0.000000, 0.740784, 0.000000, 0.000000, + -0.000000,-0.856282,-0.000000, 1.000000;; + } //End of Armature_Body Skin Weights + SkinWeights { + "Armature_Bone_001"; + 24; + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95; + 1.000000, + 0.999144, + 0.999987, + 1.000000, + 0.999144, + 1.000000, + 1.000000, + 0.999987, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999144, + 1.000000, + 1.000000, + 0.999987, + 1.000000, + 1.000000; + 0.743658, 0.068922,-0.000000, 0.000000, + 0.000000, 0.000000, 0.740784, 0.000000, + 0.068363,-0.737623, 0.000000, 0.000000, + -0.377741, 1.628371,-0.000000, 1.000000;; + } //End of Armature_Bone_001 Skin Weights + SkinWeights { + "Armature_Bone_002"; + 48; + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163; + 0.000000, + 0.000856, + 0.000013, + 0.000000, + 0.000856, + 0.000000, + 0.000000, + 0.000013, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000000, + 0.000856, + 0.000000, + 0.000000, + 0.000013, + 0.000000, + 0.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.743577,-0.069792,-0.000000, 0.000000, + 0.000000, 0.000000, 0.740784, 0.000000, + -0.069226,-0.737543, 0.000000, 0.000000, + 0.392568, 1.626715,-0.000001, 1.000000;; + } //End of Armature_Bone_002 Skin Weights + SkinWeights { + "Armature_Bone_003"; + 24; + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307; + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.746845,-0.000000,-0.000000, 0.000000, + 0.000000, 0.000000, 0.740784, 0.000000, + -0.000000,-0.740784, 0.000000, 0.000000, + 0.144872, 0.917795,-0.000000, 1.000000;; + } //End of Armature_Bone_003 Skin Weights + SkinWeights { + "Armature_Bone_004"; + 24; + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283; + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.746845,-0.000000,-0.000000, 0.000000, + 0.000000, 0.000000, 0.740784, 0.000000, + -0.000000,-0.740784, 0.000000, 0.000000, + -0.135397, 0.926692,-0.000000, 1.000000;; + } //End of Armature_Bone_004 Skin Weights + SkinWeights { + "Armature_Bone_005"; + 39; + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 131, + 133, + 134, + 137, + 138, + 139, + 308, + 309, + 310, + 311, + 312, + 313, + 314, + 315, + 316, + 317, + 318, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 327, + 328, + 329, + 330, + 331; + 0.088015, + 0.374496, + 0.207032, + 0.066484, + 0.374496, + 0.074593, + 0.049815, + 0.207032, + 0.074593, + 0.049815, + 0.088015, + 0.066484, + 0.074593, + 0.374496, + 0.088015, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.746845, 0.000000, 0.000000, 0.000000, + 0.000000, 0.005159,-0.740766, 0.000000, + -0.000000, 0.740766, 0.005159, 0.000000, + 0.002514,-1.721402,-0.134493, 1.000000;; + } //End of Armature_Bone_005 Skin Weights + SkinWeights { + "Armature_Body_001"; + 72; + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259; + 0.999999, + 1.000000, + 0.999866, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999866, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999999, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999999, + 1.000000, + 0.999866, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.746845,-0.000000,-0.000000, 0.000000, + 0.000000, 0.000000, 0.740784, 0.000000, + 0.000000,-0.740784, 0.000000, 0.000000, + -0.000000, 1.044227,-0.206990, 1.000000;; + } //End of Armature_Body_001 Skin Weights + SkinWeights { + "Armature_Body_002"; + 72; + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71; + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999999, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999999, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 0.999999, + 1.000000, + 1.000000, + 1.000000; + 0.746845, 0.000000, 0.000000, 0.000000, + -0.000000, 0.000000, 0.740784, 0.000000, + -0.000000,-0.740784, 0.000000, 0.000000, + -0.000000, 1.042009, 0.203380, 1.000000;; + } //End of Armature_Body_002 Skin Weights + SkinWeights { + "Armature_Bone_006"; + 24; + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119; + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000, + 1.000000; + 0.075705, 0.000000, 0.742998, 0.000000, + -0.000000, 0.740784,-0.000000, 0.000000, + -0.736968, 0.000000, 0.075091, 0.000000, + 2.018875, 0.120365,-0.203181, 1.000000;; + } //End of Armature_Bone_006 Skin Weights + SkinWeights { + "Armature_Bone_007"; + 20; + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139; + 0.911985, + 0.625504, + 0.792968, + 0.933516, + 0.625504, + 0.925407, + 0.950185, + 0.792968, + 0.925407, + 1.000000, + 1.000000, + 0.950185, + 1.000000, + 0.911985, + 0.933516, + 1.000000, + 1.000000, + 0.925407, + 0.625504, + 0.911985; + 0.746845, 0.000000,-0.000001, 0.000000, + -0.000000, 0.606815, 0.424897, 0.000000, + 0.000001,-0.424897, 0.606815, 0.000000, + 0.002511, 1.147970,-1.577121, 1.000000;; + } //End of Armature_Bone_007 Skin Weights + } //End of Cube_000 Mesh + } //End of Sand_monster + } //End of Armature +} //End of Root Frame +AnimationSet { + Animation { + {Armature} + AnimationKey { //Position + 2; + 108; + 0;3; 0.000000, 0.000000, 0.000000;;, + 1;3; 0.000000, 0.000000, 0.000000;;, + 2;3; 0.000000, 0.000000, 0.000000;;, + 3;3; 0.000000, 0.000000, 0.000000;;, + 4;3; 0.000000, 0.000000, 0.000000;;, + 5;3; 0.000000, 0.000000, 0.000000;;, + 6;3; 0.000000, 0.000000, 0.000000;;, + 7;3; 0.000000, 0.000000, 0.000000;;, + 8;3; 0.000000, 0.000000, 0.000000;;, + 9;3; 0.000000, 0.000000, 0.000000;;, + 10;3; 0.000000, 0.000000, 0.000000;;, + 11;3; 0.000000, 0.000000, 0.000000;;, + 12;3; 0.000000, 0.000000, 0.000000;;, + 13;3; 0.000000, 0.000000, 0.000000;;, + 14;3; 0.000000, 0.000000, 0.000000;;, + 15;3; 0.000000, 0.000000, 0.000000;;, + 16;3; 0.000000, 0.000000, 0.000000;;, + 17;3; 0.000000, 0.000000, 0.000000;;, + 18;3; 0.000000, 0.000000, 0.000000;;, + 19;3; 0.000000, 0.000000, 0.000000;;, + 20;3; 0.000000, 0.000000, 0.000000;;, + 21;3; 0.000000, 0.000000, 0.000000;;, + 22;3; 0.000000, 0.000000, 0.000000;;, + 23;3; 0.000000, 0.000000, 0.000000;;, + 24;3; 0.000000, 0.000000, 0.000000;;, + 25;3; 0.000000, 0.000000, 0.000000;;, + 26;3; 0.000000, 0.000000, 0.000000;;, + 27;3; 0.000000, 0.000000, 0.000000;;, + 28;3; 0.000000, 0.000000, 0.000000;;, + 29;3; 0.000000, 0.000000, 0.000000;;, + 30;3; 0.000000, 0.000000, 0.000000;;, + 31;3; 0.000000, 0.000000, 0.000000;;, + 32;3; 0.000000, 0.000000, 0.000000;;, + 33;3; 0.000000, 0.000000, 0.000000;;, + 34;3; 0.000000, 0.000000, 0.000000;;, + 35;3; 0.000000, 0.000000, 0.000000;;, + 36;3; 0.000000, 0.000000, 0.000000;;, + 37;3; 0.000000, 0.000000, 0.000000;;, + 38;3; 0.000000, 0.000000, 0.000000;;, + 39;3; 0.000000, 0.000000, 0.000000;;, + 40;3; 0.000000, 0.000000, 0.000000;;, + 41;3; 0.000000, 0.000000, 0.000000;;, + 42;3; 0.000000, 0.000000, 0.000000;;, + 43;3; 0.000000, 0.000000, 0.000000;;, + 44;3; 0.000000, 0.000000, 0.000000;;, + 45;3; 0.000000, 0.000000, 0.000000;;, + 46;3; 0.000000, 0.000000, 0.000000;;, + 47;3; 0.000000, 0.000000, 0.000000;;, + 48;3; 0.000000, 0.000000, 0.000000;;, + 49;3; 0.000000, 0.000000, 0.000000;;, + 50;3; 0.000000, 0.000000, 0.000000;;, + 51;3; 0.000000, 0.000000, 0.000000;;, + 52;3; 0.000000, 0.000000, 0.000000;;, + 53;3; 0.000000, 0.000000, 0.000000;;, + 54;3; 0.000000, 0.000000, 0.000000;;, + 55;3; 0.000000, 0.000000, 0.000000;;, + 56;3; 0.000000, 0.000000, 0.000000;;, + 57;3; 0.000000, 0.000000, 0.000000;;, + 58;3; 0.000000, 0.000000, 0.000000;;, + 59;3; 0.000000, 0.000000, 0.000000;;, + 60;3; 0.000000, 0.000000, 0.000000;;, + 61;3; 0.000000, 0.000000, 0.000000;;, + 62;3; 0.000000, 0.000000, 0.000000;;, + 63;3; 0.000000, 0.000000, 0.000000;;, + 64;3; 0.000000, 0.000000, 0.000000;;, + 65;3; 0.000000, 0.000000, 0.000000;;, + 66;3; 0.000000, 0.000000, 0.000000;;, + 67;3; 0.000000, 0.000000, 0.000000;;, + 68;3; 0.000000, 0.000000, 0.000000;;, + 69;3; 0.000000, 0.000000, 0.000000;;, + 70;3; 0.000000, 0.000000, 0.000000;;, + 71;3; 0.000000, 0.000000, 0.000000;;, + 72;3; 0.000000, 0.000000, 0.000000;;, + 73;3; 0.000000, 0.000000, 0.000000;;, + 74;3; 0.000000, 0.000000, 0.000000;;, + 75;3; 0.000000, 0.000000, 0.000000;;, + 76;3; 0.000000, 0.000000, 0.000000;;, + 77;3; 0.000000, 0.000000, 0.000000;;, + 78;3; 0.000000, 0.000000, 0.000000;;, + 79;3; 0.000000, 0.000000, 0.000000;;, + 80;3; 0.000000, 0.000000, 0.000000;;, + 81;3; 0.000000, 0.000000, 0.000000;;, + 82;3; 0.000000, 0.000000, 0.000000;;, + 83;3; 0.000000, 0.000000, 0.000000;;, + 84;3; 0.000000, 0.000000, 0.000000;;, + 85;3; 0.000000, 0.000000, 0.000000;;, + 86;3; 0.000000, 0.000000, 0.000000;;, + 87;3; 0.000000, 0.000000, 0.000000;;, + 88;3; 0.000000, 0.000000, 0.000000;;, + 89;3; 0.000000, 0.000000, 0.000000;;, + 90;3; 0.000000, 0.000000, 0.000000;;, + 91;3; 0.000000, 0.000000, 0.000000;;, + 92;3; 0.000000, 0.000000, 0.000000;;, + 93;3; 0.000000, 0.000000, 0.000000;;, + 94;3; 0.000000, 0.000000, 0.000000;;, + 95;3; 0.000000, 0.000000, 0.000000;;, + 96;3; 0.000000, 0.000000, 0.000000;;, + 97;3; 0.000000, 0.000000, 0.000000;;, + 98;3; 0.000000, 0.000000, 0.000000;;, + 99;3; 0.000000, 0.000000, 0.000000;;, + 100;3; 0.000000, 0.000000, 0.000000;;, + 101;3; 0.000000, 0.000000, 0.000000;;, + 102;3; 0.000000, 0.000000, 0.000000;;, + 103;3; 0.000000, 0.000000, 0.000000;;, + 104;3; 0.000000, 0.000000, 0.000000;;, + 105;3; 0.000000, 0.000000, 0.000000;;, + 106;3; 0.000000, 0.000000, 0.000000;;, + 107;3; 0.000000, 0.000000, 0.000000;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 1;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 2;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 3;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 4;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 5;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 6;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 7;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 8;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 9;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 10;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 11;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 12;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 13;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 14;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 15;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 16;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 17;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 18;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 19;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 20;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 21;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 22;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 23;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 24;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 25;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 26;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 27;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 28;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 29;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 30;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 31;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 32;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 33;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 34;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 35;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 36;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 37;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 38;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 39;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 40;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 41;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 42;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 43;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 44;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 45;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 46;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 47;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 48;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 49;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 50;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 51;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 52;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 53;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 54;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 55;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 56;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 57;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 58;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 59;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 60;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 61;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 62;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 63;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 64;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 65;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 66;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 67;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 68;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 69;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 70;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 71;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 72;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 73;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 74;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 75;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 76;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 77;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 78;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 79;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 80;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 81;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 82;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 83;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 84;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 85;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 86;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 87;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 88;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 89;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 90;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 91;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 92;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 93;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 94;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 95;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 96;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 97;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 98;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 99;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 100;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 101;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 102;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 103;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 104;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 105;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 106;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 107;4; -1.000000, 0.000000, 0.000000, 0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Root} + AnimationKey { //Position + 2; + 108; + 0;3; 0.000000, 0.000000, 0.001246;;, + 1;3; 0.000000, 0.000000, 0.001246;;, + 2;3; 0.000000, 0.000000, 0.001246;;, + 3;3; 0.000000, 0.000000, 0.001246;;, + 4;3; 0.000000, 0.000000, 0.001246;;, + 5;3; 0.000000, 0.000000, 0.001246;;, + 6;3; 0.000000, 0.000000, 0.001246;;, + 7;3; 0.000000, 0.000000, 0.001246;;, + 8;3; 0.000000, 0.000000, 0.001246;;, + 9;3; 0.000000, 0.000000, 0.001246;;, + 10;3; 0.000000, 0.000000, 0.001246;;, + 11;3; 0.000000, 0.000000, 0.001246;;, + 12;3; 0.000000, 0.000000, 0.001246;;, + 13;3; 0.000000, 0.000000, 0.001246;;, + 14;3; 0.000000, 0.000000, 0.001246;;, + 15;3; 0.000000, 0.000000, 0.001246;;, + 16;3; 0.000000, 0.000000, 0.001246;;, + 17;3; 0.000000, 0.000000, 0.001246;;, + 18;3; 0.000000, 0.000000, 0.001246;;, + 19;3; 0.000000, 0.000000, 0.001246;;, + 20;3; 0.000000, 0.000000, 0.001246;;, + 21;3; 0.000000, 0.000000, 0.001246;;, + 22;3; 0.000000, 0.000000, 0.001246;;, + 23;3; 0.000000, 0.000000, 0.001246;;, + 24;3; 0.000000, 0.000000, 0.001246;;, + 25;3; 0.000000, 0.000000, 0.001246;;, + 26;3; 0.000000, 0.000000, 0.001246;;, + 27;3; 0.000000, 0.000000, 0.001246;;, + 28;3; 0.000000, 0.000000, 0.001246;;, + 29;3; 0.000000, 0.000000, 0.001246;;, + 30;3; 0.000000, 0.000000, 0.001246;;, + 31;3; 0.000000, 0.000000, 0.001246;;, + 32;3; 0.000000, 0.000000, 0.001246;;, + 33;3; 0.000000, 0.000000, 0.001246;;, + 34;3; 0.000000, 0.000000, 0.001246;;, + 35;3; 0.000000, 0.000000, 0.001246;;, + 36;3; 0.000000, 0.000000, 0.001246;;, + 37;3; 0.000000, 0.000000, 0.001246;;, + 38;3; 0.000000, 0.000000, 0.001246;;, + 39;3; 0.000000, 0.000000, 0.001246;;, + 40;3; 0.000000, 0.000000, 0.001246;;, + 41;3; 0.000000, 0.000000, 0.001246;;, + 42;3; 0.000000, 0.000000, 0.001246;;, + 43;3; 0.000000, 0.000000, 0.001246;;, + 44;3; 0.000000, 0.000000, 0.001246;;, + 45;3; 0.000000, 0.000000, 0.001246;;, + 46;3; 0.000000, 0.000000, 0.001246;;, + 47;3; 0.000000, 0.000000, 0.001246;;, + 48;3; 0.000000, 0.000000, 0.001246;;, + 49;3; 0.000000, 0.000000, 0.001246;;, + 50;3; 0.000000, 0.000000, 0.001246;;, + 51;3; 0.000000, 0.000000, 0.001246;;, + 52;3; 0.000000, 0.000000, 0.001246;;, + 53;3; 0.000000, 0.000000, 0.001246;;, + 54;3; 0.000000, 0.000000, 0.001246;;, + 55;3; 0.000000, 0.000000, 0.001246;;, + 56;3; 0.000000, 0.000000, 0.001246;;, + 57;3; 0.000000, 0.000000, 0.001246;;, + 58;3; 0.000000, 0.000000, 0.001246;;, + 59;3; 0.000000, 0.000000, 0.001246;;, + 60;3; 0.000000, 0.000000, 0.001246;;, + 61;3; 0.000000, 0.000000, 0.001246;;, + 62;3; 0.000000, 0.000000, 0.001246;;, + 63;3; 0.000000, 0.000000, 0.001246;;, + 64;3; 0.000000, 0.000000, 0.001246;;, + 65;3; 0.000000, 0.000000, 0.001246;;, + 66;3; 0.000000, 0.000000, 0.001246;;, + 67;3; 0.000000, 0.000000, 0.001246;;, + 68;3; 0.000000, 0.000000, 0.001246;;, + 69;3; 0.000000, 0.000000, 0.001246;;, + 70;3; 0.000000, 0.000000, 0.001246;;, + 71;3; 0.000000, 0.000000, 0.001246;;, + 72;3; 0.000000, 0.000000, 0.001246;;, + 73;3; 0.000000, 0.000000, 0.001246;;, + 74;3; 0.000000, 0.000000, 0.001246;;, + 75;3; 0.000000,-0.000000,-0.008573;;, + 76;3; 0.000000,-0.000000,-0.037880;;, + 77;3; 0.000000,-0.000000,-0.084018;;, + 78;3; 0.000000,-0.000000,-0.140222;;, + 79;3; 0.000000,-0.000000,-0.196425;;, + 80;3; 0.000000,-0.000000,-0.242563;;, + 81;3; 0.000000,-0.000000,-0.271870;;, + 82;3; 0.000000,-0.000000,-0.281689;;, + 83;3; 0.000000,-0.000000,-0.271870;;, + 84;3; 0.000000,-0.000000,-0.242563;;, + 85;3; 0.000000,-0.000000,-0.196425;;, + 86;3; 0.000000,-0.000000,-0.140222;;, + 87;3; 0.000000,-0.000000,-0.084018;;, + 88;3; 0.000000,-0.000000,-0.037880;;, + 89;3; 0.000000,-0.000000,-0.008573;;, + 90;3; 0.000000,-0.000000, 0.001246;;, + 91;3; 0.000000,-0.000000,-0.008567;;, + 92;3; 0.000000,-0.000000,-0.037842;;, + 93;3; 0.000000,-0.000000,-0.083914;;, + 94;3; 0.000000,-0.000000,-0.140052;;, + 95;3; 0.000000,-0.000000,-0.196244;;, + 96;3; 0.000000,-0.000000,-0.242440;;, + 97;3; 0.000000,-0.000000,-0.271830;;, + 98;3; 0.000000,-0.000000,-0.281689;;, + 99;3; 0.000000,-0.000000,-0.271755;;, + 100;3; 0.000000,-0.000000,-0.241887;;, + 101;3; 0.000000,-0.000000,-0.194722;;, + 102;3; 0.000000,-0.000000,-0.137587;;, + 103;3; 0.000000,-0.000000,-0.081320;;, + 104;3; 0.000000,-0.000000,-0.036105;;, + 105;3; 0.000000,-0.000000,-0.008005;;, + 106;3; 0.000000, 0.000000, 0.001246;;, + 107;3; 0.000000, 0.000000, 0.001246;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 1;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 2;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 3;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 4;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 5;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 6;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 7;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 8;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 9;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 10;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 11;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 12;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 13;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 14;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 15;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 16;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 17;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 18;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 19;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 20;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 21;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 22;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 23;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 24;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 25;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 26;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 27;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 28;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 29;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 30;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 31;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 32;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 33;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 34;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 35;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 36;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 37;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 38;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 39;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 40;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 41;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 42;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 43;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 44;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 45;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 46;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 47;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 48;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 49;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 50;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 51;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 52;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 53;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 54;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 55;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 56;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 57;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 58;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 59;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 60;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 61;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 62;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 63;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 64;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 65;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 66;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 67;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 68;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 69;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 70;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 71;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 72;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 73;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 74;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 75;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 76;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 77;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 78;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 79;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 80;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 81;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 82;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 83;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 84;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 85;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 86;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 87;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 88;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 89;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 90;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 91;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 92;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 93;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 94;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 95;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 96;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 97;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 98;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 99;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 100;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 101;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 102;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 103;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 104;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 105;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 106;4; -0.707107, 0.707107, 0.000000, 0.000000;;, + 107;4; -0.707107, 0.707107, 0.000000, 0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_IK_Right_Leg} + AnimationKey { //Position + 2; + 108; + 0;3; 0.135398, 0.015523, 0.000000;;, + 1;3; 0.135398, 0.015523, 0.000000;;, + 2;3; 0.135398, 0.015523, 0.000000;;, + 3;3; 0.135398, 0.015523, 0.000000;;, + 4;3; 0.135398, 0.015523, 0.000000;;, + 5;3; 0.135398, 0.015523, 0.000000;;, + 6;3; 0.135398, 0.015523, 0.000000;;, + 7;3; 0.135398, 0.015523, 0.000000;;, + 8;3; 0.135398, 0.015523, 0.000000;;, + 9;3; 0.135398, 0.015523, 0.000000;;, + 10;3; 0.135398, 0.015523, 0.000000;;, + 11;3; 0.135398, 0.015523, 0.000000;;, + 12;3; 0.135398, 0.015523, 0.000000;;, + 13;3; 0.135398, 0.015523, 0.000000;;, + 14;3; 0.135398, 0.015523, 0.000000;;, + 15;3; 0.135398, 0.015523, 0.000000;;, + 16;3; 0.135398, 0.015523, 0.000000;;, + 17;3; 0.135398, 0.015523, 0.000000;;, + 18;3; 0.135398, 0.015523, 0.000000;;, + 19;3; 0.135398, 0.015523, 0.000000;;, + 20;3; 0.135398, 0.015523, 0.000000;;, + 21;3; 0.135398, 0.015523, 0.000000;;, + 22;3; 0.135398, 0.015523, 0.000000;;, + 23;3; 0.135398, 0.015523, 0.000000;;, + 24;3; 0.135398, 0.015523, 0.000000;;, + 25;3; 0.135398, 0.015523, 0.000000;;, + 26;3; 0.135398, 0.015523, 0.000000;;, + 27;3; 0.135398, 0.015523, 0.000000;;, + 28;3; 0.135398, 0.015523, 0.000000;;, + 29;3; 0.135398, 0.015523, 0.000000;;, + 30;3; 0.135398, 0.015523, 0.000000;;, + 31;3; 0.135398, 0.015523, 0.000000;;, + 32;3; 0.135398, 0.015523, 0.000000;;, + 33;3; 0.135398, 0.015523, 0.000000;;, + 34;3; 0.135398, 0.015523, 0.000000;;, + 35;3; 0.135398, 0.015523, 0.000000;;, + 36;3; 0.135398, 0.015523, 0.000000;;, + 37;3; 0.135398, 0.015523, 0.000000;;, + 38;3; 0.135398, 0.015523, 0.000000;;, + 39;3; 0.135398, 0.015523, 0.000000;;, + 40;3; 0.135398, 0.015523, 0.000000;;, + 41;3; 0.135398, 0.015523, 0.000000;;, + 42;3; 0.135398, 0.015523, 0.087189;;, + 43;3; 0.135398, 0.015523, 0.162188;;, + 44;3; 0.135398, 0.015523, 0.222434;;, + 45;3; 0.135398, 0.015523, 0.266237;;, + 46;3; 0.135398, 0.015523, 0.293922;;, + 47;3; 0.135398, 0.015523, 0.308311;;, + 48;3; 0.135398, 0.015523, 0.313815;;, + 49;3; 0.135398, 0.015523, 0.314835;;, + 50;3; 0.135398, 0.015523, 0.309148;;, + 51;3; 0.135398, 0.015523, 0.290771;;, + 52;3; 0.135398, 0.015523, 0.258454;;, + 53;3; 0.135398, 0.015523, 0.213080;;, + 54;3; 0.135398, 0.015523, 0.158686;;, + 55;3; 0.135398, 0.015523, 0.101401;;, + 56;3; 0.135398, 0.015523, 0.046755;;, + 57;3; 0.135398, 0.015523,-0.001999;;, + 58;3; 0.135398, 0.015523,-0.051857;;, + 59;3; 0.135398, 0.015523,-0.106460;;, + 60;3; 0.135398, 0.015523,-0.154925;;, + 61;3; 0.135398, 0.015523,-0.206693;;, + 62;3; 0.135398, 0.015523,-0.268486;;, + 63;3; 0.135398, 0.015523,-0.311509;;, + 64;3; 0.135398, 0.015523,-0.330121;;, + 65;3; 0.135398, 0.015523,-0.334719;;, + 66;3; 0.135398, 0.015523,-0.332228;;, + 67;3; 0.135398, 0.015523,-0.322988;;, + 68;3; 0.135398, 0.015523,-0.303845;;, + 69;3; 0.135398, 0.015523,-0.271522;;, + 70;3; 0.135398, 0.015523,-0.223860;;, + 71;3; 0.135398, 0.015523,-0.160993;;, + 72;3; 0.135398, 0.015523,-0.085268;;, + 73;3; 0.135398, 0.015523, 0.000000;;, + 74;3; 0.135398, 0.015523, 0.000000;;, + 75;3; 0.135398, 0.021308, 0.095588;;, + 76;3; 0.135398, 0.038571, 0.206502;;, + 77;3; 0.135398, 0.065746, 0.326063;;, + 78;3; 0.135398, 0.098852, 0.443345;;, + 79;3; 0.135398, 0.131970, 0.545509;;, + 80;3; 0.135398, 0.159170, 0.622083;;, + 81;3; 0.135398, 0.176457, 0.667861;;, + 82;3; 0.135398, 0.182252, 0.682612;;, + 83;3; 0.135398, 0.181203, 0.666972;;, + 84;3; 0.135398, 0.177911, 0.618550;;, + 85;3; 0.135398, 0.172332, 0.537822;;, + 86;3; 0.135398, 0.164785, 0.430589;;, + 87;3; 0.135398, 0.155990, 0.308211;;, + 88;3; 0.135398, 0.146856, 0.184430;;, + 89;3; 0.135398, 0.138160, 0.070810;;, + 90;3; 0.135398, 0.130378,-0.025691;;, + 91;3; 0.135398, 0.122923,-0.121019;;, + 92;3; 0.135398, 0.115040,-0.231131;;, + 93;3; 0.135398, 0.106791,-0.349520;;, + 94;3; 0.135398, 0.098329,-0.465728;;, + 95;3; 0.135398, 0.089877,-0.567400;;, + 96;3; 0.135398, 0.081658,-0.644145;;, + 97;3; 0.135398, 0.073821,-0.690390;;, + 98;3; 0.135398, 0.066422,-0.705393;;, + 99;3; 0.135398, 0.058693,-0.689356;;, + 100;3; 0.135398, 0.050027,-0.639602;;, + 101;3; 0.135398, 0.040924,-0.556855;;, + 102;3; 0.135398, 0.032220,-0.447937;;, + 103;3; 0.135398, 0.024869,-0.325462;;, + 104;3; 0.135398, 0.019552,-0.203592;;, + 105;3; 0.135398, 0.016483,-0.093171;;, + 106;3; 0.135398, 0.015523, 0.000000;;, + 107;3; 0.152259, 0.021305, 0.053347;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 1;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 2;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 3;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 4;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 5;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 6;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 7;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 8;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 9;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 10;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 11;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 12;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 13;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 14;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 15;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 16;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 17;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 18;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 19;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 20;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 21;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 22;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 23;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 24;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 25;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 26;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 27;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 28;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 29;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 30;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 31;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 32;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 33;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 34;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 35;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 36;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 37;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 38;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 39;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 40;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 41;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 42;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 43;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 44;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 45;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 46;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 47;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 48;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 49;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 50;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 51;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 52;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 53;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 54;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 55;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 56;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 57;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 58;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 59;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 60;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 61;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 62;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 63;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 64;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 65;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 66;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 67;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 68;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 69;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 70;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 71;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 72;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 73;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 74;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 75;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 76;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 77;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 78;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 79;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 80;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 81;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 82;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 83;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 84;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 85;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 86;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 87;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 88;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 89;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 90;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 91;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 92;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 93;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 94;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 95;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 96;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 97;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 98;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 99;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 100;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 101;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 102;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 103;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 104;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 105;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 106;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 107;4; -0.000000, 1.000000, 0.000000,-0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_IK_Left_Leg} + AnimationKey { //Position + 2; + 108; + 0;3; -0.148583, 0.015523, 0.000000;;, + 1;3; -0.148583, 0.015523, 0.000000;;, + 2;3; -0.148583, 0.015523, 0.000000;;, + 3;3; -0.148583, 0.015523, 0.000000;;, + 4;3; -0.148583, 0.015523, 0.000000;;, + 5;3; -0.148583, 0.015523, 0.000000;;, + 6;3; -0.148583, 0.015523, 0.000000;;, + 7;3; -0.148583, 0.015523, 0.000000;;, + 8;3; -0.148583, 0.015523, 0.000000;;, + 9;3; -0.148583, 0.015523, 0.000000;;, + 10;3; -0.148583, 0.015523, 0.000000;;, + 11;3; -0.148583, 0.015523, 0.000000;;, + 12;3; -0.148583, 0.015523, 0.000000;;, + 13;3; -0.148583, 0.015523, 0.000000;;, + 14;3; -0.148583, 0.015523, 0.000000;;, + 15;3; -0.148583, 0.015523, 0.000000;;, + 16;3; -0.148583, 0.015523, 0.000000;;, + 17;3; -0.148583, 0.015523, 0.000000;;, + 18;3; -0.148583, 0.015523, 0.000000;;, + 19;3; -0.148583, 0.015523, 0.000000;;, + 20;3; -0.148583, 0.015523, 0.000000;;, + 21;3; -0.148583, 0.015523, 0.000000;;, + 22;3; -0.148583, 0.015523, 0.000000;;, + 23;3; -0.148583, 0.015523, 0.000000;;, + 24;3; -0.148583, 0.015523, 0.000000;;, + 25;3; -0.148583, 0.015523, 0.000000;;, + 26;3; -0.148583, 0.015523, 0.000000;;, + 27;3; -0.148583, 0.015523, 0.000000;;, + 28;3; -0.148583, 0.015523, 0.000000;;, + 29;3; -0.148583, 0.015523, 0.000000;;, + 30;3; -0.148583, 0.015523, 0.000000;;, + 31;3; -0.148583, 0.015523, 0.000000;;, + 32;3; -0.148583, 0.015523, 0.000000;;, + 33;3; -0.148583, 0.015523, 0.000000;;, + 34;3; -0.148583, 0.015523, 0.000000;;, + 35;3; -0.148583, 0.015523, 0.000000;;, + 36;3; -0.148583, 0.015523, 0.000000;;, + 37;3; -0.148583, 0.015523, 0.000000;;, + 38;3; -0.148583, 0.015523, 0.000000;;, + 39;3; -0.148583, 0.015523, 0.000000;;, + 40;3; -0.148583, 0.015523, 0.000000;;, + 41;3; -0.148583, 0.015523, 0.000000;;, + 42;3; -0.148583, 0.015523,-0.090308;;, + 43;3; -0.148583, 0.015523,-0.169272;;, + 44;3; -0.148583, 0.015523,-0.234146;;, + 45;3; -0.148583, 0.015523,-0.282853;;, + 46;3; -0.148583, 0.015523,-0.315143;;, + 47;3; -0.148583, 0.015523,-0.333217;;, + 48;3; -0.148583, 0.015523,-0.341039;;, + 49;3; -0.148583, 0.015523,-0.342830;;, + 50;3; -0.148583, 0.015523,-0.336980;;, + 51;3; -0.148583, 0.015523,-0.318078;;, + 52;3; -0.148583, 0.015523,-0.284836;;, + 53;3; -0.148583, 0.015523,-0.238166;;, + 54;3; -0.148583, 0.015523,-0.182217;;, + 55;3; -0.148583, 0.015523,-0.123293;;, + 56;3; -0.148583, 0.015523,-0.067082;;, + 57;3; -0.148583, 0.015523,-0.016933;;, + 58;3; -0.148583, 0.015523, 0.034348;;, + 59;3; -0.148583, 0.015523, 0.090509;;, + 60;3; -0.148583, 0.015523, 0.140371;;, + 61;3; -0.148583, 0.015523, 0.193625;;, + 62;3; -0.148583, 0.015523, 0.257180;;, + 63;3; -0.148583, 0.015523, 0.301524;;, + 64;3; -0.148583, 0.015523, 0.320745;;, + 65;3; -0.148583, 0.015523, 0.325497;;, + 66;3; -0.148583, 0.015523, 0.323525;;, + 67;3; -0.148583, 0.015523, 0.315809;;, + 68;3; -0.148583, 0.015523, 0.299009;;, + 69;3; -0.148583, 0.015523, 0.269414;;, + 70;3; -0.148583, 0.015523, 0.224199;;, + 71;3; -0.148583, 0.015523, 0.162782;;, + 72;3; -0.148583, 0.015523, 0.087006;;, + 73;3; -0.148583, 0.015523, 0.000000;;, + 74;3; -0.148583, 0.015523, 0.000000;;, + 75;3; -0.148583, 0.019677,-0.099088;;, + 76;3; -0.148583, 0.032074,-0.215379;;, + 77;3; -0.148583, 0.051589,-0.341752;;, + 78;3; -0.148583, 0.075362,-0.466453;;, + 79;3; -0.148583, 0.099140,-0.575568;;, + 80;3; -0.148583, 0.118665,-0.657638;;, + 81;3; -0.148583, 0.131070,-0.706840;;, + 82;3; -0.148583, 0.135227,-0.722727;;, + 83;3; -0.148583, 0.134475,-0.707252;;, + 84;3; -0.148583, 0.132113,-0.659277;;, + 85;3; -0.148583, 0.128109,-0.579134;;, + 86;3; -0.148583, 0.122691,-0.472371;;, + 87;3; -0.148583, 0.116377,-0.350035;;, + 88;3; -0.148583, 0.109818,-0.225621;;, + 89;3; -0.148583, 0.103574,-0.110588;;, + 90;3; -0.148583, 0.097987,-0.011924;;, + 91;3; -0.148583, 0.092634, 0.086791;;, + 92;3; -0.148583, 0.086975, 0.201930;;, + 93;3; -0.148583, 0.081052, 0.326595;;, + 94;3; -0.148583, 0.074976, 0.449630;;, + 95;3; -0.148583, 0.068908, 0.557766;;, + 96;3; -0.148583, 0.063007, 0.639718;;, + 97;3; -0.148583, 0.057380, 0.689273;;, + 98;3; -0.148583, 0.052068, 0.705393;;, + 99;3; -0.148583, 0.046518, 0.689573;;, + 100;3; -0.148583, 0.040296, 0.640453;;, + 101;3; -0.148583, 0.033760, 0.558641;;, + 102;3; -0.148583, 0.027511, 0.450678;;, + 103;3; -0.148583, 0.022233, 0.328767;;, + 104;3; -0.148583, 0.018415, 0.206706;;, + 105;3; -0.148583, 0.016213, 0.095177;;, + 106;3; -0.148583, 0.015523, 0.000000;;, + 107;3; -0.156161, 0.012832,-0.060350;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 1;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 2;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 3;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 4;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 5;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 6;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 7;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 8;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 9;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 10;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 11;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 12;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 13;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 14;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 15;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 16;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 17;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 18;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 19;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 20;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 21;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 22;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 23;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 24;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 25;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 26;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 27;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 28;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 29;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 30;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 31;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 32;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 33;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 34;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 35;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 36;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 37;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 38;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 39;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 40;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 41;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 42;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 43;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 44;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 45;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 46;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 47;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 48;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 49;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 50;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 51;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 52;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 53;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 54;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 55;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 56;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 57;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 58;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 59;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 60;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 61;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 62;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 63;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 64;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 65;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 66;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 67;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 68;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 69;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 70;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 71;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 72;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 73;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 74;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 75;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 76;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 77;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 78;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 79;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 80;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 81;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 82;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 83;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 84;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 85;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 86;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 87;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 88;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 89;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 90;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 91;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 92;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 93;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 94;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 95;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 96;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 97;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 98;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 99;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 100;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 101;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 102;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 103;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 104;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 105;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 106;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 107;4; -0.000000, 1.000000, 0.000000,-0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_IK_Left_Hand} + AnimationKey { //Position + 2; + 108; + 0;3; -0.316097, 0.754556, 0.000000;;, + 1;3; -0.316097, 0.754556,-0.000553;;, + 2;3; -0.316097, 0.754556,-0.002272;;, + 3;3; -0.316097, 0.754556,-0.005193;;, + 4;3; -0.316097, 0.754556,-0.009241;;, + 5;3; -0.316097, 0.754556,-0.014196;;, + 6;3; -0.316097, 0.754556,-0.019709;;, + 7;3; -0.316097, 0.754556,-0.025373;;, + 8;3; -0.316097, 0.754556,-0.030822;;, + 9;3; -0.316097, 0.754556,-0.035797;;, + 10;3; -0.316097, 0.754556,-0.040148;;, + 11;3; -0.316097, 0.754556,-0.044499;;, + 12;3; -0.316097, 0.754556,-0.049474;;, + 13;3; -0.316097, 0.754556,-0.054923;;, + 14;3; -0.316097, 0.754556,-0.060587;;, + 15;3; -0.316097, 0.754556,-0.066100;;, + 16;3; -0.316097, 0.754556,-0.071055;;, + 17;3; -0.316097, 0.754556,-0.075103;;, + 18;3; -0.316097, 0.754556,-0.078023;;, + 19;3; -0.316097, 0.754556,-0.079743;;, + 20;3; -0.316097, 0.754556,-0.080296;;, + 21;3; -0.316097, 0.754556,-0.080289;;, + 22;3; -0.316097, 0.754556,-0.080236;;, + 23;3; -0.316097, 0.754556,-0.080073;;, + 24;3; -0.316097, 0.754556,-0.079720;;, + 25;3; -0.316097, 0.754556,-0.079093;;, + 26;3; -0.316097, 0.754556,-0.078123;;, + 27;3; -0.316097, 0.754556,-0.076777;;, + 28;3; -0.316097, 0.754556,-0.075061;;, + 29;3; -0.316097, 0.754556,-0.073009;;, + 30;3; -0.316097, 0.754556,-0.070670;;, + 31;3; -0.316097, 0.754556,-0.067890;;, + 32;3; -0.316097, 0.754556,-0.064517;;, + 33;3; -0.316097, 0.754556,-0.060592;;, + 34;3; -0.316097, 0.754556,-0.056133;;, + 35;3; -0.316097, 0.754556,-0.051142;;, + 36;3; -0.316097, 0.754556,-0.045596;;, + 37;3; -0.316097, 0.754556,-0.039444;;, + 38;3; -0.316097, 0.754556,-0.032578;;, + 39;3; -0.316097, 0.754556,-0.024774;;, + 40;3; -0.316097, 0.754556,-0.015466;;, + 41;3; -0.316097, 0.754556, 0.000000;;, + 42;3; -0.316097, 0.754556, 0.059460;;, + 43;3; -0.316097, 0.754556, 0.141717;;, + 44;3; -0.316097, 0.754556, 0.230109;;, + 45;3; -0.316097, 0.754556, 0.314858;;, + 46;3; -0.316097, 0.754556, 0.389209;;, + 47;3; -0.316097, 0.754556, 0.447871;;, + 48;3; -0.316097, 0.754556, 0.486247;;, + 49;3; -0.316097, 0.754556, 0.500000;;, + 50;3; -0.316097, 0.754556, 0.489995;;, + 51;3; -0.316097, 0.754556, 0.458566;;, + 52;3; -0.316097, 0.754556, 0.405218;;, + 53;3; -0.316097, 0.754556, 0.332884;;, + 54;3; -0.316097, 0.754556, 0.248325;;, + 55;3; -0.316097, 0.754556, 0.160156;;, + 56;3; -0.316097, 0.754556, 0.075835;;, + 57;3; -0.316097, 0.754556, 0.000000;;, + 58;3; -0.316097, 0.754556,-0.077935;;, + 59;3; -0.316097, 0.754556,-0.162805;;, + 60;3; -0.316097, 0.754556,-0.236963;;, + 61;3; -0.316097, 0.754556,-0.307531;;, + 62;3; -0.316097, 0.754556,-0.382085;;, + 63;3; -0.316097, 0.754556,-0.446637;;, + 64;3; -0.316097, 0.754556,-0.487225;;, + 65;3; -0.316097, 0.754556,-0.500000;;, + 66;3; -0.316097, 0.754556,-0.484078;;, + 67;3; -0.316097, 0.754556,-0.440649;;, + 68;3; -0.316097, 0.754556,-0.375753;;, + 69;3; -0.316097, 0.754556,-0.295300;;, + 70;3; -0.316097, 0.754556,-0.205809;;, + 71;3; -0.316097, 0.754556,-0.115669;;, + 72;3; -0.316097, 0.754556,-0.038027;;, + 73;3; -0.316097, 0.754556, 0.000000;;, + 74;3; -0.280185, 1.779512,-1.040664;;, + 75;3; -0.280185, 1.791992,-1.040664;;, + 76;3; -0.280185, 1.829242,-1.040664;;, + 77;3; -0.280185, 1.887885,-1.040664;;, + 78;3; -0.280185, 1.959322,-1.040664;;, + 79;3; -0.280185, 2.030761,-1.040664;;, + 80;3; -0.280185, 2.089408,-1.040664;;, + 81;3; -0.280185, 2.126663,-1.040664;;, + 82;3; -0.280185, 2.139145,-1.040664;;, + 83;3; -0.280185, 2.127405,-1.040664;;, + 84;3; -0.280185, 2.092366,-1.040664;;, + 85;3; -0.280185, 2.037206,-1.040664;;, + 86;3; -0.280185, 1.970016,-1.040664;;, + 87;3; -0.280185, 1.902828,-1.040664;;, + 88;3; -0.280185, 1.847672,-1.040664;;, + 89;3; -0.280185, 1.812637,-1.040664;;, + 90;3; -0.280185, 1.800899,-1.040664;;, + 91;3; -0.280185, 1.811608,-1.040664;;, + 92;3; -0.280185, 1.843557,-1.040664;;, + 93;3; -0.280185, 1.893841,-1.040664;;, + 94;3; -0.280185, 1.955109,-1.040664;;, + 95;3; -0.280185, 2.016426,-1.040664;;, + 96;3; -0.280185, 2.066823,-1.040664;;, + 97;3; -0.280185, 2.098878,-1.040664;;, + 98;3; -0.280185, 2.109629,-1.040664;;, + 99;3; -0.280185, 2.098046,-1.040664;;, + 100;3; -0.280185, 2.063213,-1.040664;;, + 101;3; -0.280185, 2.008193,-1.040664;;, + 102;3; -0.280185, 1.941528,-1.040664;;, + 103;3; -0.280185, 1.875865,-1.040664;;, + 104;3; -0.280185, 1.823099,-1.040664;;, + 105;3; -0.280185, 1.790307,-1.040664;;, + 106;3; -0.280185, 1.779512,-1.040664;;, + 107;3; -0.296230, 1.779106,-1.035724;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 1;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 2;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 3;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 4;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 5;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 6;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 7;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 8;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 9;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 10;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 11;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 12;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 13;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 14;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 15;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 16;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 17;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 18;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 19;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 20;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 21;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 22;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 23;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 24;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 25;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 26;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 27;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 28;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 29;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 30;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 31;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 32;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 33;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 34;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 35;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 36;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 37;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 38;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 39;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 40;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 41;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 42;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 43;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 44;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 45;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 46;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 47;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 48;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 49;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 50;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 51;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 52;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 53;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 54;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 55;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 56;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 57;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 58;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 59;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 60;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 61;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 62;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 63;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 64;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 65;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 66;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 67;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 68;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 69;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 70;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 71;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 72;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 73;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 74;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 75;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 76;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 77;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 78;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 79;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 80;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 81;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 82;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 83;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 84;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 85;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 86;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 87;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 88;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 89;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 90;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 91;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 92;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 93;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 94;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 95;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 96;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 97;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 98;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 99;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 100;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 101;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 102;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 103;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 104;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 105;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 106;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 107;4; -0.000000, 1.000000, 0.000000,-0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_IK_Right_hand} + AnimationKey { //Position + 2; + 108; + 0;3; 0.304691, 0.744702, 0.000000;;, + 1;3; 0.304691, 0.744702,-0.000157;;, + 2;3; 0.304691, 0.744702,-0.000649;;, + 3;3; 0.304691, 0.744702,-0.001493;;, + 4;3; 0.304691, 0.744702,-0.002680;;, + 5;3; 0.304691, 0.744702,-0.004156;;, + 6;3; 0.304691, 0.744702,-0.005831;;, + 7;3; 0.304691, 0.744702,-0.007595;;, + 8;3; 0.304691, 0.744702,-0.009345;;, + 9;3; 0.304691, 0.744702,-0.011001;;, + 10;3; 0.304691, 0.744702,-0.012516;;, + 11;3; 0.304691, 0.744702,-0.014113;;, + 12;3; 0.304691, 0.744702,-0.016015;;, + 13;3; 0.304691, 0.744702,-0.018164;;, + 14;3; 0.304691, 0.744702,-0.020452;;, + 15;3; 0.304691, 0.744702,-0.022720;;, + 16;3; 0.304691, 0.744702,-0.024788;;, + 17;3; 0.304691, 0.744702,-0.026497;;, + 18;3; 0.304691, 0.744702,-0.027742;;, + 19;3; 0.304691, 0.744702,-0.028480;;, + 20;3; 0.304691, 0.744702,-0.028719;;, + 21;3; 0.304691, 0.744702,-0.028537;;, + 22;3; 0.304691, 0.744702,-0.027970;;, + 23;3; 0.304691, 0.744702,-0.027003;;, + 24;3; 0.304691, 0.744702,-0.025658;;, + 25;3; 0.304691, 0.744702,-0.024003;;, + 26;3; 0.304691, 0.744702,-0.022149;;, + 27;3; 0.304691, 0.744702,-0.020229;;, + 28;3; 0.304691, 0.744702,-0.018363;;, + 29;3; 0.304691, 0.744702,-0.016638;;, + 30;3; 0.304691, 0.744702,-0.015105;;, + 31;3; 0.304691, 0.744702,-0.013623;;, + 32;3; 0.304691, 0.744702,-0.012053;;, + 33;3; 0.304691, 0.744702,-0.010419;;, + 34;3; 0.304691, 0.744702,-0.008746;;, + 35;3; 0.304691, 0.744702,-0.007059;;, + 36;3; 0.304691, 0.744702,-0.005387;;, + 37;3; 0.304691, 0.744702,-0.003770;;, + 38;3; 0.304691, 0.744702,-0.002265;;, + 39;3; 0.304691, 0.744702,-0.000977;;, + 40;3; 0.304691, 0.744702,-0.000156;;, + 41;3; 0.304691, 0.744702, 0.000000;;, + 42;3; 0.304691, 0.744702,-0.033814;;, + 43;3; 0.304691, 0.744702,-0.108158;;, + 44;3; 0.304691, 0.744702,-0.198239;;, + 45;3; 0.304691, 0.744702,-0.289641;;, + 46;3; 0.304691, 0.744702,-0.372553;;, + 47;3; 0.304691, 0.744702,-0.439437;;, + 48;3; 0.304691, 0.744702,-0.483890;;, + 49;3; 0.304691, 0.744702,-0.500000;;, + 50;3; 0.304691, 0.744702,-0.489994;;, + 51;3; 0.304691, 0.744702,-0.458565;;, + 52;3; 0.304691, 0.744702,-0.405217;;, + 53;3; 0.304691, 0.744702,-0.332884;;, + 54;3; 0.304691, 0.744702,-0.248324;;, + 55;3; 0.304691, 0.744702,-0.160156;;, + 56;3; 0.304691, 0.744702,-0.075834;;, + 57;3; 0.304691, 0.744702, 0.000000;;, + 58;3; 0.304691, 0.744702, 0.077935;;, + 59;3; 0.304691, 0.744702, 0.162806;;, + 60;3; 0.304691, 0.744702, 0.236963;;, + 61;3; 0.304691, 0.744702, 0.307532;;, + 62;3; 0.304691, 0.744702, 0.382086;;, + 63;3; 0.304691, 0.744702, 0.446638;;, + 64;3; 0.304691, 0.744702, 0.487225;;, + 65;3; 0.304691, 0.744702, 0.500000;;, + 66;3; 0.304691, 0.744702, 0.499392;;, + 67;3; 0.304691, 0.744702, 0.495075;;, + 68;3; 0.304691, 0.744702, 0.482976;;, + 69;3; 0.304691, 0.744702, 0.458109;;, + 70;3; 0.304691, 0.744702, 0.413662;;, + 71;3; 0.304691, 0.744702, 0.339134;;, + 72;3; 0.304691, 0.744702, 0.215665;;, + 73;3; 0.304691, 0.744702, 0.000000;;, + 74;3; 0.340603, 1.781662,-1.045200;;, + 75;3; 0.340603, 1.791563,-1.045200;;, + 76;3; 0.340603, 1.821117,-1.045200;;, + 77;3; 0.340603, 1.867644,-1.045200;;, + 78;3; 0.340603, 1.924320,-1.045200;;, + 79;3; 0.340603, 1.980997,-1.045200;;, + 80;3; 0.340603, 2.027524,-1.045200;;, + 81;3; 0.340603, 2.057079,-1.045200;;, + 82;3; 0.340603, 2.066980,-1.045200;;, + 83;3; 0.340603, 2.059355,-1.045200;;, + 84;3; 0.340603, 2.036595,-1.045200;;, + 85;3; 0.340603, 2.000763,-1.045200;;, + 86;3; 0.340603, 1.957116,-1.045200;;, + 87;3; 0.340603, 1.913468,-1.045200;;, + 88;3; 0.340603, 1.877638,-1.045200;;, + 89;3; 0.340603, 1.854878,-1.045200;;, + 90;3; 0.340603, 1.847253,-1.045200;;, + 91;3; 0.340603, 1.856014,-1.045200;;, + 92;3; 0.340603, 1.882160,-1.045200;;, + 93;3; 0.340603, 1.923317,-1.045200;;, + 94;3; 0.340603, 1.973458,-1.045200;;, + 95;3; 0.340603, 2.023617,-1.045200;;, + 96;3; 0.340603, 2.064815,-1.045200;;, + 97;3; 0.340603, 2.090999,-1.045200;;, + 98;3; 0.340603, 2.099775,-1.045200;;, + 99;3; 0.340603, 2.088636,-1.045200;;, + 100;3; 0.340603, 2.055114,-1.045200;;, + 101;3; 0.340603, 2.002126,-1.045200;;, + 102;3; 0.340603, 1.937877,-1.045200;;, + 103;3; 0.340603, 1.874564,-1.045200;;, + 104;3; 0.340603, 1.823682,-1.045200;;, + 105;3; 0.340603, 1.792067,-1.045200;;, + 106;3; 0.340603, 1.781662,-1.045200;;, + 107;3; 0.347242, 1.784378,-1.046669;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 1;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 2;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 3;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 4;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 5;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 6;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 7;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 8;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 9;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 10;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 11;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 12;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 13;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 14;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 15;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 16;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 17;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 18;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 19;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 20;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 21;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 22;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 23;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 24;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 25;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 26;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 27;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 28;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 29;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 30;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 31;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 32;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 33;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 34;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 35;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 36;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 37;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 38;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 39;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 40;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 41;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 42;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 43;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 44;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 45;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 46;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 47;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 48;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 49;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 50;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 51;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 52;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 53;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 54;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 55;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 56;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 57;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 58;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 59;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 60;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 61;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 62;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 63;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 64;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 65;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 66;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 67;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 68;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 69;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 70;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 71;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 72;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 73;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 74;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 75;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 76;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 77;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 78;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 79;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 80;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 81;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 82;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 83;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 84;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 85;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 86;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 87;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 88;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 89;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 90;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 91;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 92;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 93;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 94;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 95;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 96;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 97;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 98;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 99;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 100;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 101;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 102;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 103;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 104;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 105;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 106;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 107;4; -0.000000, 1.000000, 0.000000,-0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Body} + AnimationKey { //Position + 2; + 108; + 0;3; 0.000000, 0.855036, 0.000000;;, + 1;3; 0.000000, 0.855036, 0.000000;;, + 2;3; 0.000000, 0.855036, 0.000000;;, + 3;3; 0.000000, 0.855036, 0.000000;;, + 4;3; 0.000000, 0.855036, 0.000000;;, + 5;3; 0.000000, 0.855036, 0.000000;;, + 6;3; 0.000000, 0.855036, 0.000000;;, + 7;3; 0.000000, 0.855036, 0.000000;;, + 8;3; 0.000000, 0.855036, 0.000000;;, + 9;3; 0.000000, 0.855036, 0.000000;;, + 10;3; 0.000000, 0.855036, 0.000000;;, + 11;3; 0.000000, 0.855036, 0.000000;;, + 12;3; 0.000000, 0.855036, 0.000000;;, + 13;3; 0.000000, 0.855036, 0.000000;;, + 14;3; 0.000000, 0.855036, 0.000000;;, + 15;3; 0.000000, 0.855036, 0.000000;;, + 16;3; 0.000000, 0.855036, 0.000000;;, + 17;3; 0.000000, 0.855036, 0.000000;;, + 18;3; 0.000000, 0.855036, 0.000000;;, + 19;3; 0.000000, 0.855036, 0.000000;;, + 20;3; 0.000000, 0.855036, 0.000000;;, + 21;3; 0.000000, 0.855036, 0.000000;;, + 22;3; 0.000000, 0.855036, 0.000000;;, + 23;3; 0.000000, 0.855036, 0.000000;;, + 24;3; 0.000000, 0.855036, 0.000000;;, + 25;3; 0.000000, 0.855036, 0.000000;;, + 26;3; 0.000000, 0.855036, 0.000000;;, + 27;3; 0.000000, 0.855036, 0.000000;;, + 28;3; 0.000000, 0.855036, 0.000000;;, + 29;3; 0.000000, 0.855036, 0.000000;;, + 30;3; 0.000000, 0.855036, 0.000000;;, + 31;3; 0.000000, 0.855036, 0.000000;;, + 32;3; 0.000000, 0.855036, 0.000000;;, + 33;3; 0.000000, 0.855036, 0.000000;;, + 34;3; 0.000000, 0.855036, 0.000000;;, + 35;3; 0.000000, 0.855036, 0.000000;;, + 36;3; 0.000000, 0.855036, 0.000000;;, + 37;3; 0.000000, 0.855036, 0.000000;;, + 38;3; 0.000000, 0.855036, 0.000000;;, + 39;3; 0.000000, 0.855036, 0.000000;;, + 40;3; 0.000000, 0.855036, 0.000000;;, + 41;3; 0.000000, 0.855036, 0.000000;;, + 42;3; 0.000000, 0.855036, 0.000000;;, + 43;3; 0.000000, 0.855036, 0.000000;;, + 44;3; 0.000000, 0.855036, 0.000000;;, + 45;3; 0.000000, 0.855036, 0.000000;;, + 46;3; 0.000000, 0.855036, 0.000000;;, + 47;3; 0.000000, 0.855036, 0.000000;;, + 48;3; 0.000000, 0.855036, 0.000000;;, + 49;3; 0.000000, 0.855036, 0.000000;;, + 50;3; 0.000000, 0.855036, 0.000000;;, + 51;3; 0.000000, 0.855036, 0.000000;;, + 52;3; 0.000000, 0.855036, 0.000000;;, + 53;3; 0.000000, 0.855036, 0.000000;;, + 54;3; 0.000000, 0.855036, 0.000000;;, + 55;3; 0.000000, 0.855036, 0.000000;;, + 56;3; 0.000000, 0.855036, 0.000000;;, + 57;3; 0.000000, 0.855036, 0.000000;;, + 58;3; 0.000000, 0.855036, 0.000000;;, + 59;3; 0.000000, 0.855036, 0.000000;;, + 60;3; 0.000000, 0.855036, 0.000000;;, + 61;3; 0.000000, 0.855036, 0.000000;;, + 62;3; 0.000000, 0.855036, 0.000000;;, + 63;3; 0.000000, 0.855036, 0.000000;;, + 64;3; 0.000000, 0.855036, 0.000000;;, + 65;3; 0.000000, 0.855036, 0.000000;;, + 66;3; 0.000000, 0.855036, 0.000000;;, + 67;3; 0.000000, 0.855036, 0.000000;;, + 68;3; 0.000000, 0.855036, 0.000000;;, + 69;3; 0.000000, 0.855036, 0.000000;;, + 70;3; 0.000000, 0.855036, 0.000000;;, + 71;3; 0.000000, 0.855036, 0.000000;;, + 72;3; 0.000000, 0.855036, 0.000000;;, + 73;3; 0.000000, 0.855036, 0.000000;;, + 74;3; 0.000000, 1.033846, 0.000000;;, + 75;3; 0.000000, 1.033846, 0.000000;;, + 76;3; 0.000000, 1.033846, 0.000000;;, + 77;3; 0.000000, 1.033846, 0.000000;;, + 78;3; 0.000000, 1.033846, 0.000000;;, + 79;3; 0.000000, 1.033846, 0.000000;;, + 80;3; 0.000000, 1.033846, 0.000000;;, + 81;3; 0.000000, 1.033846, 0.000000;;, + 82;3; 0.000000, 1.033846, 0.000000;;, + 83;3; 0.000000, 1.033846, 0.000000;;, + 84;3; 0.000000, 1.033846, 0.000000;;, + 85;3; 0.000000, 1.033846, 0.000000;;, + 86;3; 0.000000, 1.033846, 0.000000;;, + 87;3; 0.000000, 1.033846, 0.000000;;, + 88;3; 0.000000, 1.033846, 0.000000;;, + 89;3; 0.000000, 1.033846, 0.000000;;, + 90;3; 0.000000, 1.033846, 0.000000;;, + 91;3; 0.000000, 1.033846, 0.000000;;, + 92;3; 0.000000, 1.033846, 0.000000;;, + 93;3; 0.000000, 1.033846, 0.000000;;, + 94;3; 0.000000, 1.033846, 0.000000;;, + 95;3; 0.000000, 1.033846, 0.000000;;, + 96;3; 0.000000, 1.033846, 0.000000;;, + 97;3; 0.000000, 1.033846, 0.000000;;, + 98;3; 0.000000, 1.033846, 0.000000;;, + 99;3; 0.000000, 1.033846, 0.000000;;, + 100;3; 0.000000, 1.033846, 0.000000;;, + 101;3; 0.000000, 1.033846, 0.000000;;, + 102;3; 0.000000, 1.033846, 0.000000;;, + 103;3; 0.000000, 1.033846, 0.000000;;, + 104;3; 0.000000, 1.033846, 0.000000;;, + 105;3; 0.000000, 1.033846, 0.000000;;, + 106;3; 0.000000, 1.033846, 0.000000;;, + 107;3; 0.000000, 1.033846, 0.000000;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 1;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 2;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 3;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 4;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 5;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 6;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 7;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 8;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 9;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 10;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 11;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 12;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 13;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 14;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 15;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 16;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 17;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 18;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 19;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 20;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 21;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 22;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 23;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 24;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 25;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 26;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 27;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 28;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 29;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 30;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 31;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 32;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 33;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 34;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 35;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 36;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 37;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 38;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 39;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 40;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 41;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 42;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 43;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 44;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 45;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 46;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 47;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 48;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 49;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 50;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 51;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 52;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 53;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 54;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 55;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 56;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 57;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 58;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 59;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 60;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 61;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 62;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 63;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 64;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 65;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 66;4; -1.000000,-0.000000, 0.000000, 0.000000;;, + 67;4; -1.000000,-0.000000, 0.000000, 0.000000;;, + 68;4; -1.000000,-0.000000, 0.000000, 0.000000;;, + 69;4; -1.000000,-0.000000, 0.000000, 0.000000;;, + 70;4; -1.000000,-0.000000, 0.000000, 0.000000;;, + 71;4; -1.000000,-0.000000, 0.000000, 0.000000;;, + 72;4; -1.000000,-0.000000, 0.000000, 0.000000;;, + 73;4; -1.000000,-0.000000, 0.000000, 0.000000;;, + 74;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 75;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 76;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 77;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 78;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 79;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 80;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 81;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 82;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 83;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 84;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 85;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 86;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 87;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 88;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 89;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 90;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 91;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 92;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 93;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 94;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 95;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 96;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 97;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 98;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 99;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 100;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 101;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 102;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 103;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 104;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 105;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 106;4; -0.998689,-0.051182,-0.000000, 0.000000;;, + 107;4; -0.998689,-0.051182,-0.000000, 0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Bone_001} + AnimationKey { //Position + 2; + 108; + 0;3; 0.225856, 0.800000, 0.000000;;, + 1;3; 0.225856, 0.800000, 0.000000;;, + 2;3; 0.225856, 0.800000, 0.000000;;, + 3;3; 0.225856, 0.800000, 0.000000;;, + 4;3; 0.225856, 0.800000, 0.000000;;, + 5;3; 0.225856, 0.800000, 0.000000;;, + 6;3; 0.225856, 0.800000, 0.000000;;, + 7;3; 0.225856, 0.800000, 0.000000;;, + 8;3; 0.225856, 0.800000, 0.000000;;, + 9;3; 0.225856, 0.800000, 0.000000;;, + 10;3; 0.225856, 0.800000, 0.000000;;, + 11;3; 0.225856, 0.800000, 0.000000;;, + 12;3; 0.225856, 0.800000, 0.000000;;, + 13;3; 0.225856, 0.800000, 0.000000;;, + 14;3; 0.225856, 0.800000, 0.000000;;, + 15;3; 0.225856, 0.800000, 0.000000;;, + 16;3; 0.225856, 0.800000, 0.000000;;, + 17;3; 0.225856, 0.800000, 0.000000;;, + 18;3; 0.225856, 0.800000, 0.000000;;, + 19;3; 0.225856, 0.800000, 0.000000;;, + 20;3; 0.225856, 0.800000, 0.000000;;, + 21;3; 0.225856, 0.800000, 0.000000;;, + 22;3; 0.225856, 0.800000, 0.000000;;, + 23;3; 0.225856, 0.800000, 0.000000;;, + 24;3; 0.225856, 0.800000, 0.000000;;, + 25;3; 0.225856, 0.800000, 0.000000;;, + 26;3; 0.225856, 0.800000, 0.000000;;, + 27;3; 0.225856, 0.800000, 0.000000;;, + 28;3; 0.225856, 0.800000, 0.000000;;, + 29;3; 0.225856, 0.800000, 0.000000;;, + 30;3; 0.225856, 0.800000, 0.000000;;, + 31;3; 0.225856, 0.800000, 0.000000;;, + 32;3; 0.225856, 0.800000, 0.000000;;, + 33;3; 0.225856, 0.800000, 0.000000;;, + 34;3; 0.225856, 0.800000, 0.000000;;, + 35;3; 0.225856, 0.800000, 0.000000;;, + 36;3; 0.225856, 0.800000, 0.000000;;, + 37;3; 0.225856, 0.800000, 0.000000;;, + 38;3; 0.225856, 0.800000, 0.000000;;, + 39;3; 0.225856, 0.800000, 0.000000;;, + 40;3; 0.225856, 0.800000, 0.000000;;, + 41;3; 0.225856, 0.800000, 0.000000;;, + 42;3; 0.225856, 0.800000, 0.000000;;, + 43;3; 0.225856, 0.800000, 0.000000;;, + 44;3; 0.225856, 0.800000, 0.000000;;, + 45;3; 0.225856, 0.800000, 0.000000;;, + 46;3; 0.225856, 0.800000, 0.000000;;, + 47;3; 0.225856, 0.800000, 0.000000;;, + 48;3; 0.225856, 0.800000, 0.000000;;, + 49;3; 0.225856, 0.800000, 0.000000;;, + 50;3; 0.225856, 0.800000, 0.000000;;, + 51;3; 0.225856, 0.800000, 0.000000;;, + 52;3; 0.225856, 0.800000, 0.000000;;, + 53;3; 0.225856, 0.800000, 0.000000;;, + 54;3; 0.225856, 0.800000, 0.000000;;, + 55;3; 0.225856, 0.800000, 0.000000;;, + 56;3; 0.225856, 0.800000, 0.000000;;, + 57;3; 0.225856, 0.800000, 0.000000;;, + 58;3; 0.225856, 0.800000, 0.000000;;, + 59;3; 0.225856, 0.800000, 0.000000;;, + 60;3; 0.225856, 0.800000, 0.000000;;, + 61;3; 0.225856, 0.800000, 0.000000;;, + 62;3; 0.225856, 0.800000, 0.000000;;, + 63;3; 0.225856, 0.800000, 0.000000;;, + 64;3; 0.225856, 0.800000, 0.000000;;, + 65;3; 0.225856, 0.800000, 0.000000;;, + 66;3; 0.225856, 0.800000, 0.000000;;, + 67;3; 0.225856, 0.800000, 0.000000;;, + 68;3; 0.225856, 0.800000, 0.000000;;, + 69;3; 0.225856, 0.800000, 0.000000;;, + 70;3; 0.225856, 0.800000, 0.000000;;, + 71;3; 0.225856, 0.800000, 0.000000;;, + 72;3; 0.225856, 0.800000, 0.000000;;, + 73;3; 0.225856, 0.800000, 0.000000;;, + 74;3; 0.225856, 0.800000, 0.000000;;, + 75;3; 0.225856, 0.800000, 0.000000;;, + 76;3; 0.225856, 0.800000, 0.000000;;, + 77;3; 0.225856, 0.800000, 0.000000;;, + 78;3; 0.225856, 0.800000, 0.000000;;, + 79;3; 0.225856, 0.800000, 0.000000;;, + 80;3; 0.225856, 0.800000, 0.000000;;, + 81;3; 0.225856, 0.800000, 0.000000;;, + 82;3; 0.225856, 0.800000, 0.000000;;, + 83;3; 0.225856, 0.800000, 0.000000;;, + 84;3; 0.225856, 0.800000, 0.000000;;, + 85;3; 0.225856, 0.800000, 0.000000;;, + 86;3; 0.225856, 0.800000, 0.000000;;, + 87;3; 0.225856, 0.800000, 0.000000;;, + 88;3; 0.225856, 0.800000, 0.000000;;, + 89;3; 0.225856, 0.800000, 0.000000;;, + 90;3; 0.225856, 0.800000, 0.000000;;, + 91;3; 0.225856, 0.800000, 0.000000;;, + 92;3; 0.225856, 0.800000, 0.000000;;, + 93;3; 0.225856, 0.800000, 0.000000;;, + 94;3; 0.225856, 0.800000, 0.000000;;, + 95;3; 0.225856, 0.800000, 0.000000;;, + 96;3; 0.225856, 0.800000, 0.000000;;, + 97;3; 0.225856, 0.800000, 0.000000;;, + 98;3; 0.225856, 0.800000, 0.000000;;, + 99;3; 0.225856, 0.800000, 0.000000;;, + 100;3; 0.225856, 0.800000, 0.000000;;, + 101;3; 0.225856, 0.800000, 0.000000;;, + 102;3; 0.225856, 0.800000, 0.000000;;, + 103;3; 0.225856, 0.800000, 0.000000;;, + 104;3; 0.225856, 0.800000, 0.000000;;, + 105;3; 0.225856, 0.800000, 0.000000;;, + 106;3; 0.225856, 0.800000, 0.000000;;, + 107;3; 0.225856, 0.800000, 0.000000;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 0.998933, 0.046192,-0.000000;;, + 1;4; 0.000113, 0.998932, 0.046192, 0.000005;;, + 2;4; 0.000463, 0.998931, 0.046192, 0.000021;;, + 3;4; 0.001052, 0.998930, 0.046191, 0.000049;;, + 4;4; 0.001861, 0.998928, 0.046191, 0.000086;;, + 5;4; 0.002839, 0.998925, 0.046191, 0.000131;;, + 6;4; 0.003910, 0.998921, 0.046191, 0.000181;;, + 7;4; 0.004990, 0.998917, 0.046191, 0.000231;;, + 8;4; 0.006002, 0.998912, 0.046191, 0.000277;;, + 9;4; 0.006897, 0.998908, 0.046190, 0.000319;;, + 10;4; 0.007645, 0.998903, 0.046190, 0.000353;;, + 11;4; 0.008353, 0.998898, 0.046190, 0.000386;;, + 12;4; 0.009124, 0.998891, 0.046190, 0.000422;;, + 13;4; 0.009935, 0.998884, 0.046189, 0.000459;;, + 14;4; 0.010752, 0.998875, 0.046189, 0.000497;;, + 15;4; 0.011526, 0.998866, 0.046189, 0.000533;;, + 16;4; 0.012206, 0.998858, 0.046188, 0.000564;;, + 17;4; 0.012752, 0.998851, 0.046188, 0.000590;;, + 18;4; 0.013140, 0.998846, 0.046188, 0.000608;;, + 19;4; 0.013366, 0.998843, 0.046187, 0.000618;;, + 20;4; 0.013438, 0.998842, 0.046187, 0.000621;;, + 21;4; 0.013396, 0.998843, 0.046187, 0.000619;;, + 22;4; 0.013259, 0.998845, 0.046188, 0.000613;;, + 23;4; 0.013015, 0.998849, 0.046188, 0.000602;;, + 24;4; 0.012659, 0.998854, 0.046188, 0.000585;;, + 25;4; 0.012193, 0.998861, 0.046188, 0.000564;;, + 26;4; 0.011633, 0.998868, 0.046189, 0.000538;;, + 27;4; 0.011006, 0.998875, 0.046189, 0.000509;;, + 28;4; 0.010339, 0.998881, 0.046189, 0.000478;;, + 29;4; 0.009657, 0.998887, 0.046189, 0.000447;;, + 30;4; 0.008979, 0.998892, 0.046190, 0.000415;;, + 31;4; 0.008235, 0.998897, 0.046190, 0.000381;;, + 32;4; 0.007367, 0.998902, 0.046190, 0.000341;;, + 33;4; 0.006405, 0.998906, 0.046190, 0.000296;;, + 34;4; 0.005374, 0.998911, 0.046191, 0.000248;;, + 35;4; 0.004301, 0.998916, 0.046191, 0.000199;;, + 36;4; 0.003216, 0.998920, 0.046191, 0.000149;;, + 37;4; 0.002157, 0.998924, 0.046191, 0.000100;;, + 38;4; 0.001180, 0.998928, 0.046191, 0.000055;;, + 39;4; 0.000383, 0.998931, 0.046192, 0.000018;;, + 40;4; -0.000000, 0.998933, 0.046192,-0.000000;;, + 41;4; -0.000000, 0.998933, 0.046192,-0.000000;;, + 42;4; 0.016411, 0.996908, 0.046098, 0.000759;;, + 43;4; 0.052503, 0.992456, 0.045892, 0.002427;;, + 44;4; 0.096241, 0.987060, 0.045643, 0.004450;;, + 45;4; 0.140624, 0.981585, 0.045389, 0.006502;;, + 46;4; 0.180886, 0.976618, 0.045160, 0.008364;;, + 47;4; 0.213365, 0.972611, 0.044974, 0.009866;;, + 48;4; 0.234951, 0.969948, 0.044851, 0.010864;;, + 49;4; 0.242773, 0.968983, 0.044807, 0.011226;;, + 50;4; 0.234348, 0.970022, 0.044855, 0.010836;;, + 51;4; 0.209203, 0.973124, 0.044998, 0.009674;;, + 52;4; 0.169616, 0.978008, 0.045224, 0.007843;;, + 53;4; 0.121393, 0.983958, 0.045499, 0.005613;;, + 54;4; 0.073168, 0.989907, 0.045774, 0.003383;;, + 55;4; 0.033576, 0.994791, 0.046000, 0.001552;;, + 56;4; 0.008426, 0.997893, 0.046144, 0.000389;;, + 57;4; -0.000000, 0.998933, 0.046192,-0.000000;;, + 58;4; -0.000000, 0.998933, 0.046192,-0.000000;;, + 59;4; -0.000000, 0.998933, 0.046192,-0.000000;;, + 60;4; -0.000000, 0.998933, 0.046192,-0.000000;;, + 61;4; -0.021739, 0.996233, 0.046067,-0.001004;;, + 62;4; -0.082955, 0.988627, 0.045715,-0.003834;;, + 63;4; -0.161536, 0.978863, 0.045264,-0.007469;;, + 64;4; -0.222735, 0.971258, 0.044912,-0.010299;;, + 65;4; -0.244464, 0.968558, 0.044787,-0.011304;;, + 66;4; -0.244163, 0.969535, 0.044832,-0.011290;;, + 67;4; -0.242008, 0.972228, 0.044957,-0.011186;;, + 68;4; -0.235917, 0.976278, 0.045144,-0.010887;;, + 69;4; -0.223338, 0.981298, 0.045376,-0.010263;;, + 70;4; -0.200843, 0.986838, 0.045632,-0.009147;;, + 71;4; -0.163332, 0.992312, 0.045885,-0.007310;;, + 72;4; -0.102212, 0.996851, 0.046095,-0.004424;;, + 73;4; -0.000000, 0.998933, 0.046192,-0.000000;;, + 74;4; 0.726097, 0.686039, 0.031723, 0.033575;;, + 75;4; 0.765734, 0.638365, 0.029519, 0.035296;;, + 76;4; 0.789482, 0.608852, 0.028154, 0.036416;;, + 77;4; 0.804069, 0.590470, 0.027304, 0.037129;;, + 78;4; 0.812819, 0.579387, 0.026791, 0.037561;;, + 79;4; 0.817712, 0.573190, 0.026505, 0.037803;;, + 80;4; 0.820080, 0.570202, 0.026367, 0.037919;;, + 81;4; 0.820918, 0.569151, 0.026318, 0.037960;;, + 82;4; 0.821035, 0.569006, 0.026311, 0.037965;;, + 83;4; 0.818160, 0.572615, 0.026478, 0.037832;;, + 84;4; 0.809580, 0.583387, 0.026976, 0.037436;;, + 85;4; 0.796072, 0.600345, 0.027761, 0.036811;;, + 86;4; 0.779617, 0.621003, 0.028716, 0.036050;;, + 87;4; 0.763162, 0.641661, 0.029671, 0.035289;;, + 88;4; 0.749653, 0.658620, 0.030455, 0.034665;;, + 89;4; 0.741073, 0.669392, 0.030953, 0.034268;;, + 90;4; 0.738198, 0.673000, 0.031120, 0.034135;;, + 91;4; 0.741328, 0.669018, 0.030936, 0.034280;;, + 92;4; 0.750670, 0.657133, 0.030386, 0.034712;;, + 93;4; 0.765376, 0.638421, 0.029521, 0.035392;;, + 94;4; 0.783291, 0.615627, 0.028467, 0.036220;;, + 95;4; 0.801206, 0.592833, 0.027413, 0.037048;;, + 96;4; 0.815912, 0.574122, 0.026548, 0.037729;;, + 97;4; 0.825254, 0.562236, 0.025998, 0.038160;;, + 98;4; 0.828383, 0.558254, 0.025814, 0.038305;;, + 99;4; 0.824723, 0.562805, 0.026025, 0.038136;;, + 100;4; 0.813799, 0.576388, 0.026653, 0.037631;;, + 101;4; 0.796600, 0.597771, 0.027642, 0.036835;;, + 102;4; 0.775650, 0.623820, 0.028846, 0.035867;;, + 103;4; 0.754698, 0.649870, 0.030051, 0.034898;;, + 104;4; 0.737498, 0.671257, 0.031040, 0.034102;;, + 105;4; 0.726572, 0.684843, 0.031668, 0.033597;;, + 106;4; 0.722912, 0.689395, 0.031878, 0.033428;;, + 107;4; 0.722912, 0.689395, 0.031878, 0.033428;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 0.999999;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Bone_002} + AnimationKey { //Position + 2; + 108; + 0;3; -0.238835, 0.800000, 0.000000;;, + 1;3; -0.238835, 0.800000, 0.000000;;, + 2;3; -0.238835, 0.800000, 0.000000;;, + 3;3; -0.238835, 0.800000, 0.000000;;, + 4;3; -0.238835, 0.800000, 0.000000;;, + 5;3; -0.238835, 0.800000, 0.000000;;, + 6;3; -0.238835, 0.800000, 0.000000;;, + 7;3; -0.238835, 0.800000, 0.000000;;, + 8;3; -0.238835, 0.800000, 0.000000;;, + 9;3; -0.238835, 0.800000, 0.000000;;, + 10;3; -0.238835, 0.800000, 0.000000;;, + 11;3; -0.238835, 0.800000, 0.000000;;, + 12;3; -0.238835, 0.800000, 0.000000;;, + 13;3; -0.238835, 0.800000, 0.000000;;, + 14;3; -0.238835, 0.800000, 0.000000;;, + 15;3; -0.238835, 0.800000, 0.000000;;, + 16;3; -0.238835, 0.800000, 0.000000;;, + 17;3; -0.238835, 0.800000, 0.000000;;, + 18;3; -0.238835, 0.800000, 0.000000;;, + 19;3; -0.238835, 0.800000, 0.000000;;, + 20;3; -0.238835, 0.800000, 0.000000;;, + 21;3; -0.238835, 0.800000, 0.000000;;, + 22;3; -0.238835, 0.800000, 0.000000;;, + 23;3; -0.238835, 0.800000, 0.000000;;, + 24;3; -0.238835, 0.800000, 0.000000;;, + 25;3; -0.238835, 0.800000, 0.000000;;, + 26;3; -0.238835, 0.800000, 0.000000;;, + 27;3; -0.238835, 0.800000, 0.000000;;, + 28;3; -0.238835, 0.800000, 0.000000;;, + 29;3; -0.238835, 0.800000, 0.000000;;, + 30;3; -0.238835, 0.800000, 0.000000;;, + 31;3; -0.238835, 0.800000, 0.000000;;, + 32;3; -0.238835, 0.800000, 0.000000;;, + 33;3; -0.238835, 0.800000, 0.000000;;, + 34;3; -0.238835, 0.800000, 0.000000;;, + 35;3; -0.238835, 0.800000, 0.000000;;, + 36;3; -0.238835, 0.800000, 0.000000;;, + 37;3; -0.238835, 0.800000, 0.000000;;, + 38;3; -0.238835, 0.800000, 0.000000;;, + 39;3; -0.238835, 0.800000, 0.000000;;, + 40;3; -0.238835, 0.800000, 0.000000;;, + 41;3; -0.238835, 0.800000, 0.000000;;, + 42;3; -0.238835, 0.800000, 0.000000;;, + 43;3; -0.238835, 0.800000, 0.000000;;, + 44;3; -0.238835, 0.800000, 0.000000;;, + 45;3; -0.238835, 0.800000, 0.000000;;, + 46;3; -0.238835, 0.800000, 0.000000;;, + 47;3; -0.238835, 0.800000, 0.000000;;, + 48;3; -0.238835, 0.800000, 0.000000;;, + 49;3; -0.238835, 0.800000, 0.000000;;, + 50;3; -0.238835, 0.800000, 0.000000;;, + 51;3; -0.238835, 0.800000, 0.000000;;, + 52;3; -0.238835, 0.800000, 0.000000;;, + 53;3; -0.238835, 0.800000, 0.000000;;, + 54;3; -0.238835, 0.800000, 0.000000;;, + 55;3; -0.238835, 0.800000, 0.000000;;, + 56;3; -0.238835, 0.800000, 0.000000;;, + 57;3; -0.238835, 0.800000, 0.000000;;, + 58;3; -0.238835, 0.800000, 0.000000;;, + 59;3; -0.238835, 0.800000, 0.000000;;, + 60;3; -0.238835, 0.800000, 0.000000;;, + 61;3; -0.238835, 0.800000, 0.000000;;, + 62;3; -0.238835, 0.800000, 0.000000;;, + 63;3; -0.238835, 0.800000, 0.000000;;, + 64;3; -0.238835, 0.800000, 0.000000;;, + 65;3; -0.238835, 0.800000, 0.000000;;, + 66;3; -0.238835, 0.800000, 0.000000;;, + 67;3; -0.238835, 0.800000, 0.000000;;, + 68;3; -0.238835, 0.800000, 0.000000;;, + 69;3; -0.238835, 0.800000, 0.000000;;, + 70;3; -0.238835, 0.800000, 0.000000;;, + 71;3; -0.238835, 0.800000, 0.000000;;, + 72;3; -0.238835, 0.800000, 0.000000;;, + 73;3; -0.238835, 0.800000, 0.000000;;, + 74;3; -0.238835, 0.800000, 0.000000;;, + 75;3; -0.238835, 0.800000, 0.000000;;, + 76;3; -0.238835, 0.800000, 0.000000;;, + 77;3; -0.238835, 0.800000, 0.000000;;, + 78;3; -0.238835, 0.800000, 0.000000;;, + 79;3; -0.238835, 0.800000, 0.000000;;, + 80;3; -0.238835, 0.800000, 0.000000;;, + 81;3; -0.238835, 0.800000, 0.000000;;, + 82;3; -0.238835, 0.800000, 0.000000;;, + 83;3; -0.238835, 0.800000, 0.000000;;, + 84;3; -0.238835, 0.800000, 0.000000;;, + 85;3; -0.238835, 0.800000, 0.000000;;, + 86;3; -0.238835, 0.800000, 0.000000;;, + 87;3; -0.238835, 0.800000, 0.000000;;, + 88;3; -0.238835, 0.800000, 0.000000;;, + 89;3; -0.238835, 0.800000, 0.000000;;, + 90;3; -0.238835, 0.800000, 0.000000;;, + 91;3; -0.238835, 0.800000, 0.000000;;, + 92;3; -0.238835, 0.800000, 0.000000;;, + 93;3; -0.238835, 0.800000, 0.000000;;, + 94;3; -0.238835, 0.800000, 0.000000;;, + 95;3; -0.238835, 0.800000, 0.000000;;, + 96;3; -0.238835, 0.800000, 0.000000;;, + 97;3; -0.238835, 0.800000, 0.000000;;, + 98;3; -0.238835, 0.800000, 0.000000;;, + 99;3; -0.238835, 0.800000, 0.000000;;, + 100;3; -0.238835, 0.800000, 0.000000;;, + 101;3; -0.238835, 0.800000, 0.000000;;, + 102;3; -0.238835, 0.800000, 0.000000;;, + 103;3; -0.238835, 0.800000, 0.000000;;, + 104;3; -0.238835, 0.800000, 0.000000;;, + 105;3; -0.238835, 0.800000, 0.000000;;, + 106;3; -0.238835, 0.800000, 0.000000;;, + 107;3; -0.238835, 0.800000, 0.000000;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 0.998905,-0.046776,-0.000000;;, + 1;4; 0.000396, 0.998902,-0.046776,-0.000019;;, + 2;4; 0.001620, 0.998891,-0.046775,-0.000076;;, + 3;4; 0.003679, 0.998871,-0.046774,-0.000172;;, + 4;4; 0.006500, 0.998842,-0.046773,-0.000304;;, + 5;4; 0.009901, 0.998805,-0.046771,-0.000464;;, + 6;4; 0.013615, 0.998761,-0.046769,-0.000638;;, + 7;4; 0.017338, 0.998712,-0.046767,-0.000812;;, + 8;4; 0.020809, 0.998661,-0.046764,-0.000975;;, + 9;4; 0.023851, 0.998609,-0.046762,-0.001117;;, + 10;4; 0.026368, 0.998557,-0.046760,-0.001235;;, + 11;4; 0.028711, 0.998499,-0.046757,-0.001345;;, + 12;4; 0.031226, 0.998427,-0.046754,-0.001462;;, + 13;4; 0.033841, 0.998341,-0.046750,-0.001585;;, + 14;4; 0.036445, 0.998248,-0.046745,-0.001707;;, + 15;4; 0.038889, 0.998154,-0.046741,-0.001821;;, + 16;4; 0.041022, 0.998067,-0.046737,-0.001921;;, + 17;4; 0.042723, 0.997994,-0.046733,-0.002001;;, + 18;4; 0.043926, 0.997941,-0.046731,-0.002057;;, + 19;4; 0.044623, 0.997909,-0.046729,-0.002090;;, + 20;4; 0.044845, 0.997898,-0.046729,-0.002100;;, + 21;4; 0.044841, 0.997899,-0.046729,-0.002100;;, + 22;4; 0.044817, 0.997900,-0.046729,-0.002099;;, + 23;4; 0.044742, 0.997905,-0.046729,-0.002095;;, + 24;4; 0.044579, 0.997913,-0.046729,-0.002088;;, + 25;4; 0.044290, 0.997926,-0.046730,-0.002074;;, + 26;4; 0.043842, 0.997946,-0.046731,-0.002053;;, + 27;4; 0.043222, 0.997973,-0.046732,-0.002024;;, + 28;4; 0.042430, 0.998006,-0.046734,-0.001987;;, + 29;4; 0.041484, 0.998044,-0.046736,-0.001943;;, + 30;4; 0.040405, 0.998088,-0.046738,-0.001892;;, + 31;4; 0.039231, 0.998138,-0.046740,-0.001837;;, + 32;4; 0.037955, 0.998194,-0.046743,-0.001777;;, + 33;4; 0.036535, 0.998257,-0.046746,-0.001711;;, + 34;4; 0.034919, 0.998325,-0.046749,-0.001635;;, + 35;4; 0.033044, 0.998398,-0.046752,-0.001547;;, + 36;4; 0.030822, 0.998476,-0.046756,-0.001443;;, + 37;4; 0.028124, 0.998556,-0.046760,-0.001317;;, + 38;4; 0.024742, 0.998640,-0.046763,-0.001159;;, + 39;4; 0.020284, 0.998725,-0.046767,-0.000950;;, + 40;4; 0.013794, 0.998810,-0.046771,-0.000646;;, + 41;4; -0.000000, 0.998905,-0.046776,-0.000000;;, + 42;4; -0.031189, 0.996841,-0.046679, 0.001460;;, + 43;4; -0.072145, 0.992300,-0.046467, 0.003378;;, + 44;4; -0.115348, 0.986796,-0.046209, 0.005401;;, + 45;4; -0.156373, 0.981211,-0.045947, 0.007322;;, + 46;4; -0.192148, 0.976145,-0.045710, 0.008998;;, + 47;4; -0.220256, 0.972058,-0.045519, 0.010314;;, + 48;4; -0.238588, 0.969342,-0.045392, 0.011172;;, + 49;4; -0.245143, 0.968358,-0.045346, 0.011479;;, + 50;4; -0.236636, 0.969418,-0.045395, 0.011081;;, + 51;4; -0.211245, 0.972582,-0.045543, 0.009892;;, + 52;4; -0.171272, 0.977564,-0.045777, 0.008020;;, + 53;4; -0.122578, 0.983632,-0.046061, 0.005739;;, + 54;4; -0.073882, 0.989700,-0.046345, 0.003459;;, + 55;4; -0.033905, 0.994681,-0.046578, 0.001587;;, + 56;4; -0.008509, 0.997845,-0.046726, 0.000398;;, + 57;4; -0.000000, 0.998905,-0.046776,-0.000000;;, + 58;4; -0.000000, 0.998905,-0.046776,-0.000000;;, + 59;4; -0.000000, 0.998905,-0.046776,-0.000000;;, + 60;4; -0.000000, 0.998905,-0.046776,-0.000000;;, + 61;4; 0.021615, 0.996236,-0.046651,-0.001011;;, + 62;4; 0.082482, 0.988719,-0.046299,-0.003861;;, + 63;4; 0.160618, 0.979066,-0.045847,-0.007521;;, + 64;4; 0.221468, 0.971548,-0.045495,-0.010371;;, + 65;4; 0.243074, 0.968879,-0.045370,-0.011383;;, + 66;4; 0.235291, 0.969846,-0.045415,-0.011014;;, + 67;4; 0.213947, 0.972508,-0.045540,-0.009989;;, + 68;4; 0.181951, 0.976512,-0.045727,-0.008442;;, + 69;4; 0.142284, 0.981474,-0.045960,-0.006525;;, + 70;4; 0.098338, 0.986951,-0.046216,-0.004421;;, + 71;4; 0.054509, 0.992362,-0.046470,-0.002372;;, + 72;4; 0.017496, 0.996849,-0.046680,-0.000720;;, + 73;4; -0.000000, 0.998905,-0.046776,-0.000000;;, + 74;4; 0.721174, 0.691173,-0.032366,-0.033771;;, + 75;4; 0.763079, 0.641077,-0.030020,-0.035614;;, + 76;4; 0.788198, 0.610058,-0.028567,-0.036814;;, + 77;4; 0.803629, 0.590736,-0.027662,-0.037576;;, + 78;4; 0.812887, 0.579085,-0.027117,-0.038040;;, + 79;4; 0.818063, 0.572572,-0.026812,-0.038299;;, + 80;4; 0.820568, 0.569430,-0.026665,-0.038423;;, + 81;4; 0.821455, 0.568326,-0.026613,-0.038466;;, + 82;4; 0.821578, 0.568173,-0.026606,-0.038472;;, + 83;4; 0.818731, 0.571759,-0.026774,-0.038339;;, + 84;4; 0.810231, 0.582463,-0.027275,-0.037941;;, + 85;4; 0.796849, 0.599314,-0.028064,-0.037314;;, + 86;4; 0.780548, 0.619842,-0.029025,-0.036551;;, + 87;4; 0.764247, 0.640369,-0.029987,-0.035788;;, + 88;4; 0.750865, 0.657220,-0.030776,-0.035161;;, + 89;4; 0.742365, 0.667924,-0.031277,-0.034763;;, + 90;4; 0.739518, 0.671510,-0.031445,-0.034630;;, + 91;4; 0.742645, 0.667513,-0.031258,-0.034776;;, + 92;4; 0.751981, 0.655582,-0.030699,-0.035213;;, + 93;4; 0.766679, 0.636798,-0.029819,-0.035901;;, + 94;4; 0.784583, 0.613917,-0.028748,-0.036740;;, + 95;4; 0.802487, 0.591036,-0.027676,-0.037578;;, + 96;4; 0.817184, 0.572253,-0.026797,-0.038266;;, + 97;4; 0.826520, 0.560322,-0.026238,-0.038704;;, + 98;4; 0.829648, 0.556324,-0.026051,-0.038850;;, + 99;4; 0.825855, 0.561033,-0.026272,-0.038673;;, + 100;4; 0.814535, 0.575088,-0.026930,-0.038142;;, + 101;4; 0.796714, 0.597215,-0.027966,-0.037308;;, + 102;4; 0.775005, 0.624169,-0.029228,-0.036291;;, + 103;4; 0.753296, 0.651125,-0.030490,-0.035275;;, + 104;4; 0.735473, 0.673255,-0.031527,-0.034440;;, + 105;4; 0.724152, 0.687313,-0.032185,-0.033910;;, + 106;4; 0.720358, 0.692023,-0.032405,-0.033732;;, + 107;4; 0.720358, 0.692023,-0.032405,-0.033732;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Bone_003} + AnimationKey { //Position + 2; + 108; + 0;3; -0.144872, 0.061513, 0.000000;;, + 1;3; -0.144872, 0.061513, 0.000000;;, + 2;3; -0.144872, 0.061513, 0.000000;;, + 3;3; -0.144872, 0.061513, 0.000000;;, + 4;3; -0.144872, 0.061513, 0.000000;;, + 5;3; -0.144872, 0.061513, 0.000000;;, + 6;3; -0.144872, 0.061513, 0.000000;;, + 7;3; -0.144872, 0.061513, 0.000000;;, + 8;3; -0.144872, 0.061513, 0.000000;;, + 9;3; -0.144872, 0.061513, 0.000000;;, + 10;3; -0.144872, 0.061513, 0.000000;;, + 11;3; -0.144872, 0.061513, 0.000000;;, + 12;3; -0.144872, 0.061513, 0.000000;;, + 13;3; -0.144872, 0.061513, 0.000000;;, + 14;3; -0.144872, 0.061513, 0.000000;;, + 15;3; -0.144872, 0.061513, 0.000000;;, + 16;3; -0.144872, 0.061513, 0.000000;;, + 17;3; -0.144872, 0.061513, 0.000000;;, + 18;3; -0.144872, 0.061513, 0.000000;;, + 19;3; -0.144872, 0.061513, 0.000000;;, + 20;3; -0.144872, 0.061513, 0.000000;;, + 21;3; -0.144872, 0.061513, 0.000000;;, + 22;3; -0.144872, 0.061513, 0.000000;;, + 23;3; -0.144872, 0.061513, 0.000000;;, + 24;3; -0.144872, 0.061513, 0.000000;;, + 25;3; -0.144872, 0.061513, 0.000000;;, + 26;3; -0.144872, 0.061513, 0.000000;;, + 27;3; -0.144872, 0.061513, 0.000000;;, + 28;3; -0.144872, 0.061513, 0.000000;;, + 29;3; -0.144872, 0.061513, 0.000000;;, + 30;3; -0.144872, 0.061513, 0.000000;;, + 31;3; -0.144872, 0.061513, 0.000000;;, + 32;3; -0.144872, 0.061513, 0.000000;;, + 33;3; -0.144872, 0.061513, 0.000000;;, + 34;3; -0.144872, 0.061513, 0.000000;;, + 35;3; -0.144872, 0.061513, 0.000000;;, + 36;3; -0.144872, 0.061513, 0.000000;;, + 37;3; -0.144872, 0.061513, 0.000000;;, + 38;3; -0.144872, 0.061513, 0.000000;;, + 39;3; -0.144872, 0.061513, 0.000000;;, + 40;3; -0.144872, 0.061513, 0.000000;;, + 41;3; -0.144872, 0.061513, 0.000000;;, + 42;3; -0.144872, 0.061513, 0.000000;;, + 43;3; -0.144872, 0.061513, 0.000000;;, + 44;3; -0.144872, 0.061513, 0.000000;;, + 45;3; -0.144872, 0.061513, 0.000000;;, + 46;3; -0.144872, 0.061513, 0.000000;;, + 47;3; -0.144872, 0.061513, 0.000000;;, + 48;3; -0.144872, 0.061513, 0.000000;;, + 49;3; -0.144872, 0.061513, 0.000000;;, + 50;3; -0.144872, 0.061513, 0.000000;;, + 51;3; -0.144872, 0.061513, 0.000000;;, + 52;3; -0.144872, 0.061513, 0.000000;;, + 53;3; -0.144872, 0.061513, 0.000000;;, + 54;3; -0.144872, 0.061513, 0.000000;;, + 55;3; -0.144872, 0.061513, 0.000000;;, + 56;3; -0.144872, 0.061513, 0.000000;;, + 57;3; -0.144872, 0.061513, 0.000000;;, + 58;3; -0.144872, 0.061513, 0.000000;;, + 59;3; -0.144872, 0.061513, 0.000000;;, + 60;3; -0.144872, 0.061513, 0.000000;;, + 61;3; -0.144872, 0.061513, 0.000000;;, + 62;3; -0.144872, 0.061513, 0.000000;;, + 63;3; -0.144872, 0.061513, 0.000000;;, + 64;3; -0.144872, 0.061513, 0.000000;;, + 65;3; -0.144872, 0.061513, 0.000000;;, + 66;3; -0.144872, 0.061513, 0.000000;;, + 67;3; -0.144872, 0.061513, 0.000000;;, + 68;3; -0.144872, 0.061513, 0.000000;;, + 69;3; -0.144872, 0.061513, 0.000000;;, + 70;3; -0.144872, 0.061513, 0.000000;;, + 71;3; -0.144872, 0.061513, 0.000000;;, + 72;3; -0.144872, 0.061513, 0.000000;;, + 73;3; -0.144872, 0.061513, 0.000000;;, + 74;3; -0.144872, 0.061513, 0.000000;;, + 75;3; -0.144872, 0.061513, 0.000000;;, + 76;3; -0.144872, 0.061513, 0.000000;;, + 77;3; -0.144872, 0.061513, 0.000000;;, + 78;3; -0.144872, 0.061513, 0.000000;;, + 79;3; -0.144872, 0.061513, 0.000000;;, + 80;3; -0.144872, 0.061513, 0.000000;;, + 81;3; -0.144872, 0.061513, 0.000000;;, + 82;3; -0.144872, 0.061513, 0.000000;;, + 83;3; -0.144872, 0.061513, 0.000000;;, + 84;3; -0.144872, 0.061513, 0.000000;;, + 85;3; -0.144872, 0.061513, 0.000000;;, + 86;3; -0.144872, 0.061513, 0.000000;;, + 87;3; -0.144872, 0.061513, 0.000000;;, + 88;3; -0.144872, 0.061513, 0.000000;;, + 89;3; -0.144872, 0.061513, 0.000000;;, + 90;3; -0.144872, 0.061513, 0.000000;;, + 91;3; -0.144872, 0.061513, 0.000000;;, + 92;3; -0.144872, 0.061513, 0.000000;;, + 93;3; -0.144872, 0.061513, 0.000000;;, + 94;3; -0.144872, 0.061513, 0.000000;;, + 95;3; -0.144872, 0.061513, 0.000000;;, + 96;3; -0.144872, 0.061513, 0.000000;;, + 97;3; -0.144872, 0.061513, 0.000000;;, + 98;3; -0.144872, 0.061513, 0.000000;;, + 99;3; -0.144872, 0.061513, 0.000000;;, + 100;3; -0.144872, 0.061513, 0.000000;;, + 101;3; -0.144872, 0.061513, 0.000000;;, + 102;3; -0.144872, 0.061513, 0.000000;;, + 103;3; -0.144872, 0.061513, 0.000000;;, + 104;3; -0.144872, 0.061513, 0.000000;;, + 105;3; -0.144872, 0.061513, 0.000000;;, + 106;3; -0.144872, 0.061513, 0.000000;;, + 107;3; -0.144872, 0.061513, 0.000000;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 1;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 2;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 3;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 4;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 5;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 6;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 7;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 8;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 9;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 10;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 11;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 12;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 13;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 14;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 15;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 16;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 17;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 18;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 19;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 20;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 21;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 22;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 23;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 24;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 25;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 26;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 27;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 28;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 29;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 30;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 31;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 32;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 33;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 34;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 35;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 36;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 37;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 38;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 39;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 40;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 41;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 42;4; 0.012248, 0.998881,-0.000000,-0.000000;;, + 43;4; 0.039184, 0.996421,-0.000000,-0.000000;;, + 44;4; 0.071828, 0.993438,-0.000000,-0.000000;;, + 45;4; 0.104954, 0.990412,-0.000000,-0.000000;;, + 46;4; 0.135005, 0.987667,-0.000000,-0.000000;;, + 47;4; 0.159246, 0.985452,-0.000000,-0.000000;;, + 48;4; 0.175357, 0.983980,-0.000000,-0.000000;;, + 49;4; 0.181195, 0.983447,-0.000000,-0.000000;;, + 50;4; 0.174908, 0.984022,-0.000000,-0.000000;;, + 51;4; 0.156139, 0.985736,-0.000000,-0.000000;;, + 52;4; 0.126593, 0.988435,-0.000000,-0.000000;;, + 53;4; 0.090600, 0.991724,-0.000000,-0.000000;;, + 54;4; 0.054607, 0.995012,-0.000000,-0.000000;;, + 55;4; 0.025058, 0.997711,-0.000000,-0.000000;;, + 56;4; 0.006288, 0.999426,-0.000000,-0.000000;;, + 57;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 58;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 59;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 60;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 61;4; -0.015047, 0.998718,-0.000000,-0.000000;;, + 62;4; -0.057422, 0.995106,-0.000000,-0.000000;;, + 63;4; -0.111826, 0.990469,-0.000000,-0.000000;;, + 64;4; -0.154196, 0.986857,-0.000000,-0.000000;;, + 65;4; -0.169240, 0.985575,-0.000000,-0.000000;;, + 66;4; -0.166047, 0.986040,-0.000000,-0.000000;;, + 67;4; -0.156832, 0.987322,-0.000000,-0.000000;;, + 68;4; -0.142082, 0.989252,-0.000000,-0.000000;;, + 69;4; -0.122229, 0.991645,-0.000000,-0.000000;;, + 70;4; -0.097673, 0.994282,-0.000000,-0.000000;;, + 71;4; -0.068804, 0.996881,-0.000000,-0.000000;;, + 72;4; -0.036052, 0.999025,-0.000000,-0.000000;;, + 73;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 74;4; 0.053673, 0.998559,-0.000000,-0.000000;;, + 75;4; 0.106079, 0.991342,-0.000000,-0.000000;;, + 76;4; 0.163098, 0.980061,-0.000000,-0.000000;;, + 77;4; 0.218649, 0.967459,-0.000000,-0.000000;;, + 78;4; 0.269086, 0.955138,-0.000000,-0.000000;;, + 79;4; 0.311807, 0.944200,-0.000000,-0.000000;;, + 80;4; 0.344689, 0.935502,-0.000000,-0.000000;;, + 81;4; 0.365809, 0.929779,-0.000000,-0.000000;;, + 82;4; 0.373278, 0.927719,-0.000000,-0.000000;;, + 83;4; 0.365966, 0.930188,-0.000000,-0.000000;;, + 84;4; 0.343286, 0.937556,-0.000000,-0.000000;;, + 85;4; 0.305474, 0.949156,-0.000000,-0.000000;;, + 86;4; 0.255428, 0.963286,-0.000000,-0.000000;;, + 87;4; 0.198768, 0.977416,-0.000000,-0.000000;;, + 88;4; 0.142120, 0.989015,-0.000000,-0.000000;;, + 89;4; 0.090827, 0.996384,-0.000000,-0.000000;;, + 90;4; 0.047904, 0.998852,-0.000000,-0.000000;;, + 91;4; 0.006316, 0.997886,-0.000000,-0.000000;;, + 92;4; -0.040994, 0.995002,-0.000000,-0.000000;;, + 93;4; -0.091373, 0.990461,-0.000000,-0.000000;;, + 94;4; -0.140400, 0.984931,-0.000000,-0.000000;;, + 95;4; -0.182814, 0.979400,-0.000000,-0.000000;;, + 96;4; -0.214363, 0.974859,-0.000000,-0.000000;;, + 97;4; -0.233064, 0.971975,-0.000000,-0.000000;;, + 98;4; -0.239043, 0.971009,-0.000000,-0.000000;;, + 99;4; -0.229083, 0.971975,-0.000000,-0.000000;;, + 100;4; -0.199358, 0.974859,-0.000000,-0.000000;;, + 101;4; -0.152566, 0.979398,-0.000000,-0.000000;;, + 102;4; -0.095562, 0.984928,-0.000000,-0.000000;;, + 103;4; -0.038544, 0.990458,-0.000000,-0.000000;;, + 104;4; 0.008280, 0.994997,-0.000000,-0.000000;;, + 105;4; 0.038035, 0.997881,-0.000000,-0.000000;;, + 106;4; 0.048007, 0.998847,-0.000000,-0.000000;;, + 107;4; 0.048007, 0.998847,-0.000000,-0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Bone_004} + AnimationKey { //Position + 2; + 108; + 0;3; 0.135398, 0.070410, 0.000000;;, + 1;3; 0.135398, 0.070410, 0.000000;;, + 2;3; 0.135398, 0.070410, 0.000000;;, + 3;3; 0.135398, 0.070410, 0.000000;;, + 4;3; 0.135398, 0.070410, 0.000000;;, + 5;3; 0.135398, 0.070410, 0.000000;;, + 6;3; 0.135398, 0.070410, 0.000000;;, + 7;3; 0.135398, 0.070410, 0.000000;;, + 8;3; 0.135398, 0.070410, 0.000000;;, + 9;3; 0.135398, 0.070410, 0.000000;;, + 10;3; 0.135398, 0.070410, 0.000000;;, + 11;3; 0.135398, 0.070410, 0.000000;;, + 12;3; 0.135398, 0.070410, 0.000000;;, + 13;3; 0.135398, 0.070410, 0.000000;;, + 14;3; 0.135398, 0.070410, 0.000000;;, + 15;3; 0.135398, 0.070410, 0.000000;;, + 16;3; 0.135398, 0.070410, 0.000000;;, + 17;3; 0.135398, 0.070410, 0.000000;;, + 18;3; 0.135398, 0.070410, 0.000000;;, + 19;3; 0.135398, 0.070410, 0.000000;;, + 20;3; 0.135398, 0.070410, 0.000000;;, + 21;3; 0.135398, 0.070410, 0.000000;;, + 22;3; 0.135398, 0.070410, 0.000000;;, + 23;3; 0.135398, 0.070410, 0.000000;;, + 24;3; 0.135398, 0.070410, 0.000000;;, + 25;3; 0.135398, 0.070410, 0.000000;;, + 26;3; 0.135398, 0.070410, 0.000000;;, + 27;3; 0.135398, 0.070410, 0.000000;;, + 28;3; 0.135398, 0.070410, 0.000000;;, + 29;3; 0.135398, 0.070410, 0.000000;;, + 30;3; 0.135398, 0.070410, 0.000000;;, + 31;3; 0.135398, 0.070410, 0.000000;;, + 32;3; 0.135398, 0.070410, 0.000000;;, + 33;3; 0.135398, 0.070410, 0.000000;;, + 34;3; 0.135398, 0.070410, 0.000000;;, + 35;3; 0.135398, 0.070410, 0.000000;;, + 36;3; 0.135398, 0.070410, 0.000000;;, + 37;3; 0.135398, 0.070410, 0.000000;;, + 38;3; 0.135398, 0.070410, 0.000000;;, + 39;3; 0.135398, 0.070410, 0.000000;;, + 40;3; 0.135398, 0.070410, 0.000000;;, + 41;3; 0.135398, 0.070410, 0.000000;;, + 42;3; 0.135398, 0.070410, 0.000000;;, + 43;3; 0.135398, 0.070410, 0.000000;;, + 44;3; 0.135398, 0.070410, 0.000000;;, + 45;3; 0.135398, 0.070410, 0.000000;;, + 46;3; 0.135398, 0.070410, 0.000000;;, + 47;3; 0.135398, 0.070410, 0.000000;;, + 48;3; 0.135398, 0.070410, 0.000000;;, + 49;3; 0.135398, 0.070410, 0.000000;;, + 50;3; 0.135398, 0.070410, 0.000000;;, + 51;3; 0.135398, 0.070410, 0.000000;;, + 52;3; 0.135398, 0.070410, 0.000000;;, + 53;3; 0.135398, 0.070410, 0.000000;;, + 54;3; 0.135398, 0.070410, 0.000000;;, + 55;3; 0.135398, 0.070410, 0.000000;;, + 56;3; 0.135398, 0.070410, 0.000000;;, + 57;3; 0.135398, 0.070410, 0.000000;;, + 58;3; 0.135398, 0.070410, 0.000000;;, + 59;3; 0.135398, 0.070410, 0.000000;;, + 60;3; 0.135398, 0.070410, 0.000000;;, + 61;3; 0.135398, 0.070410, 0.000000;;, + 62;3; 0.135398, 0.070410, 0.000000;;, + 63;3; 0.135398, 0.070410, 0.000000;;, + 64;3; 0.135398, 0.070410, 0.000000;;, + 65;3; 0.135398, 0.070410, 0.000000;;, + 66;3; 0.135398, 0.070410, 0.000000;;, + 67;3; 0.135398, 0.070410, 0.000000;;, + 68;3; 0.135398, 0.070410, 0.000000;;, + 69;3; 0.135398, 0.070410, 0.000000;;, + 70;3; 0.135398, 0.070410, 0.000000;;, + 71;3; 0.135398, 0.070410, 0.000000;;, + 72;3; 0.135398, 0.070410, 0.000000;;, + 73;3; 0.135398, 0.070410, 0.000000;;, + 74;3; 0.135398, 0.070410, 0.000000;;, + 75;3; 0.135398, 0.070410, 0.000000;;, + 76;3; 0.135398, 0.070410, 0.000000;;, + 77;3; 0.135398, 0.070410, 0.000000;;, + 78;3; 0.135398, 0.070410, 0.000000;;, + 79;3; 0.135398, 0.070410, 0.000000;;, + 80;3; 0.135398, 0.070410, 0.000000;;, + 81;3; 0.135398, 0.070410, 0.000000;;, + 82;3; 0.135398, 0.070410, 0.000000;;, + 83;3; 0.135398, 0.070410, 0.000000;;, + 84;3; 0.135398, 0.070410, 0.000000;;, + 85;3; 0.135398, 0.070410, 0.000000;;, + 86;3; 0.135398, 0.070410, 0.000000;;, + 87;3; 0.135398, 0.070410, 0.000000;;, + 88;3; 0.135398, 0.070410, 0.000000;;, + 89;3; 0.135398, 0.070410, 0.000000;;, + 90;3; 0.135398, 0.070410, 0.000000;;, + 91;3; 0.135398, 0.070410, 0.000000;;, + 92;3; 0.135398, 0.070411, 0.000000;;, + 93;3; 0.135398, 0.070410, 0.000000;;, + 94;3; 0.135398, 0.070410, 0.000000;;, + 95;3; 0.135398, 0.070410, 0.000000;;, + 96;3; 0.135398, 0.070410, 0.000000;;, + 97;3; 0.135398, 0.070410, 0.000000;;, + 98;3; 0.135398, 0.070410, 0.000000;;, + 99;3; 0.135398, 0.070410, 0.000000;;, + 100;3; 0.135398, 0.070410, 0.000000;;, + 101;3; 0.135398, 0.070410, 0.000000;;, + 102;3; 0.135398, 0.070410, 0.000000;;, + 103;3; 0.135398, 0.070410, 0.000000;;, + 104;3; 0.135398, 0.070410, 0.000000;;, + 105;3; 0.135398, 0.070410, 0.000000;;, + 106;3; 0.135398, 0.070410, 0.000000;;, + 107;3; 0.135398, 0.070410, 0.000000;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 1;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 2;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 3;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 4;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 5;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 6;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 7;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 8;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 9;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 10;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 11;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 12;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 13;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 14;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 15;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 16;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 17;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 18;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 19;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 20;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 21;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 22;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 23;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 24;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 25;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 26;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 27;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 28;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 29;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 30;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 31;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 32;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 33;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 34;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 35;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 36;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 37;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 38;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 39;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 40;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 41;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 42;4; -0.011497, 0.999015,-0.000000,-0.000000;;, + 43;4; -0.036781, 0.996849,-0.000000,-0.000000;;, + 44;4; -0.067423, 0.994224,-0.000000,-0.000000;;, + 45;4; -0.098518, 0.991561,-0.000000,-0.000000;;, + 46;4; -0.126725, 0.989144,-0.000000,-0.000000;;, + 47;4; -0.149480, 0.987195,-0.000000,-0.000000;;, + 48;4; -0.164603, 0.985899,-0.000000,-0.000000;;, + 49;4; -0.170083, 0.985430,-0.000000,-0.000000;;, + 50;4; -0.164181, 0.985935,-0.000000,-0.000000;;, + 51;4; -0.146564, 0.987445,-0.000000,-0.000000;;, + 52;4; -0.118829, 0.989821,-0.000000,-0.000000;;, + 53;4; -0.085044, 0.992715,-0.000000,-0.000000;;, + 54;4; -0.051258, 0.995609,-0.000000,-0.000000;;, + 55;4; -0.023522, 0.997985,-0.000000,-0.000000;;, + 56;4; -0.005903, 0.999494,-0.000000,-0.000000;;, + 57;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 58;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 59;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 60;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 61;4; 0.015161, 0.998698,-0.000000,-0.000000;;, + 62;4; 0.057858, 0.995031,-0.000000,-0.000000;;, + 63;4; 0.112676, 0.990322,-0.000000,-0.000000;;, + 64;4; 0.155368, 0.986655,-0.000000,-0.000000;;, + 65;4; 0.170525, 0.985353,-0.000000,-0.000000;;, + 66;4; 0.165031, 0.985825,-0.000000,-0.000000;;, + 67;4; 0.149868, 0.987128,-0.000000,-0.000000;;, + 68;4; 0.127055, 0.989087,-0.000000,-0.000000;;, + 69;4; 0.098775, 0.991516,-0.000000,-0.000000;;, + 70;4; 0.067600, 0.994194,-0.000000,-0.000000;;, + 71;4; 0.036878, 0.996833,-0.000000,-0.000000;;, + 72;4; 0.011527, 0.999010,-0.000000,-0.000000;;, + 73;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 74;4; 0.055475, 0.998460,-0.000000,-0.000000;;, + 75;4; 0.034281, 0.994439,-0.000000,-0.000000;;, + 76;4; -0.012328, 0.989066,-0.000000,-0.000000;;, + 77;4; -0.068815, 0.983361,-0.000000,-0.000000;;, + 78;4; -0.126137, 0.977927,-0.000000,-0.000000;;, + 79;4; -0.178136, 0.973177,-0.000000,-0.000000;;, + 80;4; -0.220084, 0.969440,-0.000000,-0.000000;;, + 81;4; -0.247962, 0.967001,-0.000000,-0.000000;;, + 82;4; -0.258065, 0.966128,-0.000000,-0.000000;;, + 83;4; -0.251248, 0.967264,-0.000000,-0.000000;;, + 84;4; -0.230090, 0.970657,-0.000000,-0.000000;;, + 85;4; -0.194778, 0.975997,-0.000000,-0.000000;;, + 86;4; -0.147975, 0.982503,-0.000000,-0.000000;;, + 87;4; -0.094886, 0.989009,-0.000000,-0.000000;;, + 88;4; -0.041671, 0.994350,-0.000000,-0.000000;;, + 89;4; 0.006683, 0.997742,-0.000000,-0.000000;;, + 90;4; 0.047348, 0.998878,-0.000000,-0.000000;;, + 91;4; 0.087012, 0.997046,-0.000000,-0.000000;;, + 92;4; 0.132380, 0.991576,-0.000000,-0.000000;;, + 93;4; 0.180897, 0.982965,-0.000000,-0.000000;;, + 94;4; 0.228266, 0.972475,-0.000000,-0.000000;;, + 95;4; 0.269349, 0.961985,-0.000000,-0.000000;;, + 96;4; 0.299967, 0.953373,-0.000000,-0.000000;;, + 97;4; 0.318143, 0.947904,-0.000000,-0.000000;;, + 98;4; 0.323959, 0.946071,-0.000000,-0.000000;;, + 99;4; 0.314574, 0.947893,-0.000000,-0.000000;;, + 100;4; 0.286565, 0.953331,-0.000000,-0.000000;;, + 101;4; 0.242473, 0.961891,-0.000000,-0.000000;;, + 102;4; 0.188759, 0.972320,-0.000000,-0.000000;;, + 103;4; 0.135032, 0.982748,-0.000000,-0.000000;;, + 104;4; 0.090913, 0.991309,-0.000000,-0.000000;;, + 105;4; 0.062878, 0.996747,-0.000000,-0.000000;;, + 106;4; 0.053483, 0.998569,-0.000000,-0.000000;;, + 107;4; 0.053483, 0.998569,-0.000000,-0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Bone_005} + AnimationKey { //Position + 2; + 108; + 0;3; -0.002513, 0.866015, 0.122502;;, + 1;3; -0.002513, 0.866015, 0.122502;;, + 2;3; -0.002513, 0.866015, 0.122502;;, + 3;3; -0.002513, 0.866015, 0.122502;;, + 4;3; -0.002513, 0.866015, 0.122502;;, + 5;3; -0.002513, 0.866015, 0.122502;;, + 6;3; -0.002513, 0.866015, 0.122502;;, + 7;3; -0.002513, 0.866015, 0.122502;;, + 8;3; -0.002513, 0.866015, 0.122502;;, + 9;3; -0.002513, 0.866015, 0.122502;;, + 10;3; -0.002513, 0.866015, 0.122502;;, + 11;3; -0.002513, 0.866015, 0.122502;;, + 12;3; -0.002513, 0.866015, 0.122502;;, + 13;3; -0.002513, 0.866015, 0.122502;;, + 14;3; -0.002513, 0.866015, 0.122502;;, + 15;3; -0.002513, 0.866015, 0.122502;;, + 16;3; -0.002513, 0.866015, 0.122502;;, + 17;3; -0.002513, 0.866015, 0.122502;;, + 18;3; -0.002513, 0.866015, 0.122502;;, + 19;3; -0.002513, 0.866015, 0.122502;;, + 20;3; -0.002513, 0.866015, 0.122502;;, + 21;3; -0.002513, 0.866015, 0.122502;;, + 22;3; -0.002513, 0.866015, 0.122502;;, + 23;3; -0.002513, 0.866015, 0.122502;;, + 24;3; -0.002513, 0.866015, 0.122502;;, + 25;3; -0.002513, 0.866015, 0.122502;;, + 26;3; -0.002513, 0.866015, 0.122502;;, + 27;3; -0.002513, 0.866015, 0.122502;;, + 28;3; -0.002513, 0.866015, 0.122502;;, + 29;3; -0.002513, 0.866015, 0.122502;;, + 30;3; -0.002513, 0.866015, 0.122502;;, + 31;3; -0.002513, 0.866015, 0.122502;;, + 32;3; -0.002513, 0.866015, 0.122502;;, + 33;3; -0.002513, 0.866015, 0.122502;;, + 34;3; -0.002513, 0.866015, 0.122502;;, + 35;3; -0.002513, 0.866015, 0.122502;;, + 36;3; -0.002513, 0.866015, 0.122502;;, + 37;3; -0.002513, 0.866015, 0.122502;;, + 38;3; -0.002513, 0.866015, 0.122502;;, + 39;3; -0.002513, 0.866015, 0.122502;;, + 40;3; -0.002513, 0.866015, 0.122502;;, + 41;3; -0.002513, 0.866015, 0.122502;;, + 42;3; -0.002513, 0.866015, 0.122502;;, + 43;3; -0.002513, 0.866015, 0.122502;;, + 44;3; -0.002513, 0.866015, 0.122502;;, + 45;3; -0.002513, 0.866015, 0.122502;;, + 46;3; -0.002513, 0.866015, 0.122502;;, + 47;3; -0.002513, 0.866015, 0.122502;;, + 48;3; -0.002513, 0.866015, 0.122502;;, + 49;3; -0.002513, 0.866015, 0.122502;;, + 50;3; -0.002513, 0.866015, 0.122502;;, + 51;3; -0.002513, 0.866015, 0.122502;;, + 52;3; -0.002513, 0.866015, 0.122502;;, + 53;3; -0.002513, 0.866015, 0.122502;;, + 54;3; -0.002513, 0.866015, 0.122502;;, + 55;3; -0.002513, 0.866015, 0.122502;;, + 56;3; -0.002513, 0.866015, 0.122502;;, + 57;3; -0.002513, 0.866015, 0.122502;;, + 58;3; -0.002513, 0.866015, 0.122502;;, + 59;3; -0.002513, 0.866015, 0.122502;;, + 60;3; -0.002513, 0.866015, 0.122502;;, + 61;3; -0.002513, 0.866015, 0.122502;;, + 62;3; -0.002513, 0.866015, 0.122502;;, + 63;3; -0.002513, 0.866015, 0.122502;;, + 64;3; -0.002513, 0.866015, 0.122502;;, + 65;3; -0.002513, 0.866015, 0.122502;;, + 66;3; -0.002513, 0.866015, 0.122502;;, + 67;3; -0.002513, 0.866015, 0.122502;;, + 68;3; -0.002513, 0.866015, 0.122502;;, + 69;3; -0.002513, 0.866015, 0.122502;;, + 70;3; -0.002513, 0.866015, 0.122502;;, + 71;3; -0.002513, 0.866015, 0.122502;;, + 72;3; -0.002513, 0.866015, 0.122502;;, + 73;3; -0.002513, 0.866015, 0.122502;;, + 74;3; -0.002513, 0.866015, 0.122502;;, + 75;3; -0.002513, 0.866015, 0.122502;;, + 76;3; -0.002513, 0.866015, 0.122502;;, + 77;3; -0.002513, 0.866015, 0.122502;;, + 78;3; -0.002513, 0.866015, 0.122502;;, + 79;3; -0.002513, 0.866015, 0.122502;;, + 80;3; -0.002513, 0.866015, 0.122502;;, + 81;3; -0.002513, 0.866015, 0.122502;;, + 82;3; -0.002513, 0.866015, 0.122502;;, + 83;3; -0.002513, 0.866015, 0.122502;;, + 84;3; -0.002513, 0.866015, 0.122502;;, + 85;3; -0.002513, 0.866015, 0.122502;;, + 86;3; -0.002513, 0.866015, 0.122502;;, + 87;3; -0.002513, 0.866015, 0.122502;;, + 88;3; -0.002513, 0.866015, 0.122502;;, + 89;3; -0.002513, 0.866015, 0.122502;;, + 90;3; -0.002513, 0.866015, 0.122502;;, + 91;3; -0.002513, 0.866015, 0.122502;;, + 92;3; -0.002513, 0.866015, 0.122502;;, + 93;3; -0.002513, 0.866015, 0.122502;;, + 94;3; -0.002513, 0.866015, 0.122502;;, + 95;3; -0.002513, 0.866015, 0.122502;;, + 96;3; -0.002513, 0.866015, 0.122502;;, + 97;3; -0.002513, 0.866015, 0.122502;;, + 98;3; -0.002513, 0.866015, 0.122502;;, + 99;3; -0.002513, 0.866015, 0.122502;;, + 100;3; -0.002513, 0.866015, 0.122502;;, + 101;3; -0.002513, 0.866015, 0.122502;;, + 102;3; -0.002513, 0.866015, 0.122502;;, + 103;3; -0.002513, 0.866015, 0.122502;;, + 104;3; -0.002513, 0.866015, 0.122502;;, + 105;3; -0.002513, 0.866015, 0.122502;;, + 106;3; -0.002513, 0.866015, 0.122502;;, + 107;3; -0.002513, 0.866015, 0.122502;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 1;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 2;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 3;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 4;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 5;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 6;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 7;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 8;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 9;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 10;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 11;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 12;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 13;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 14;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 15;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 16;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 17;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 18;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 19;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 20;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 21;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 22;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 23;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 24;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 25;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 26;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 27;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 28;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 29;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 30;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 31;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 32;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 33;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 34;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 35;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 36;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 37;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 38;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 39;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 40;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 41;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 42;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 43;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 44;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 45;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 46;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 47;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 48;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 49;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 50;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 51;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 52;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 53;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 54;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 55;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 56;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 57;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 58;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 59;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 60;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 61;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 62;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 63;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 64;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 65;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 66;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 67;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 68;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 69;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 70;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 71;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 72;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 73;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 74;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 75;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 76;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 77;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 78;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 79;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 80;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 81;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 82;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 83;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 84;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 85;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 86;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 87;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 88;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 89;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 90;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 91;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 92;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 93;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 94;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 95;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 96;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 97;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 98;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 99;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 100;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 101;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 102;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 103;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 104;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 105;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 106;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 107;4; -0.999935,-0.004138, 0.000565,-0.000851;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Body_001} + AnimationKey { //Position + 2; + 108; + 0;3; 0.000000, 0.187946,-0.206990;;, + 1;3; 0.000000, 0.187946,-0.206990;;, + 2;3; 0.000000, 0.187946,-0.206990;;, + 3;3; 0.000000, 0.187946,-0.206990;;, + 4;3; 0.000000, 0.187946,-0.206990;;, + 5;3; 0.000000, 0.187946,-0.206990;;, + 6;3; 0.000000, 0.187946,-0.206990;;, + 7;3; 0.000000, 0.187946,-0.206990;;, + 8;3; 0.000000, 0.187946,-0.206990;;, + 9;3; 0.000000, 0.187946,-0.206990;;, + 10;3; 0.000000, 0.187946,-0.206990;;, + 11;3; 0.000000, 0.187946,-0.206990;;, + 12;3; 0.000000, 0.187946,-0.206990;;, + 13;3; 0.000000, 0.187946,-0.206990;;, + 14;3; 0.000000, 0.187946,-0.206990;;, + 15;3; 0.000000, 0.187946,-0.206990;;, + 16;3; 0.000000, 0.187946,-0.206990;;, + 17;3; 0.000000, 0.187946,-0.206990;;, + 18;3; 0.000000, 0.187946,-0.206990;;, + 19;3; 0.000000, 0.187946,-0.206990;;, + 20;3; 0.000000, 0.187946,-0.206990;;, + 21;3; 0.000000, 0.187946,-0.206990;;, + 22;3; 0.000000, 0.187946,-0.206990;;, + 23;3; 0.000000, 0.187946,-0.206990;;, + 24;3; 0.000000, 0.187946,-0.206990;;, + 25;3; 0.000000, 0.187946,-0.206990;;, + 26;3; 0.000000, 0.187946,-0.206990;;, + 27;3; 0.000000, 0.187946,-0.206990;;, + 28;3; 0.000000, 0.187946,-0.206990;;, + 29;3; 0.000000, 0.187946,-0.206990;;, + 30;3; 0.000000, 0.187946,-0.206990;;, + 31;3; 0.000000, 0.187946,-0.206990;;, + 32;3; 0.000000, 0.187946,-0.206990;;, + 33;3; 0.000000, 0.187946,-0.206990;;, + 34;3; 0.000000, 0.187946,-0.206990;;, + 35;3; 0.000000, 0.187946,-0.206990;;, + 36;3; 0.000000, 0.187946,-0.206990;;, + 37;3; 0.000000, 0.187946,-0.206990;;, + 38;3; 0.000000, 0.187946,-0.206990;;, + 39;3; 0.000000, 0.187946,-0.206990;;, + 40;3; 0.000000, 0.187946,-0.206990;;, + 41;3; 0.000000, 0.187946,-0.206990;;, + 42;3; 0.000000, 0.187946,-0.206990;;, + 43;3; 0.000000, 0.187946,-0.206990;;, + 44;3; 0.000000, 0.187946,-0.206990;;, + 45;3; 0.000000, 0.187946,-0.206990;;, + 46;3; 0.000000, 0.187946,-0.206990;;, + 47;3; 0.000000, 0.187946,-0.206990;;, + 48;3; 0.000000, 0.187946,-0.206990;;, + 49;3; 0.000000, 0.187946,-0.206990;;, + 50;3; 0.000000, 0.187946,-0.206990;;, + 51;3; 0.000000, 0.187946,-0.206990;;, + 52;3; 0.000000, 0.187946,-0.206990;;, + 53;3; 0.000000, 0.187946,-0.206990;;, + 54;3; 0.000000, 0.187946,-0.206990;;, + 55;3; 0.000000, 0.187946,-0.206990;;, + 56;3; 0.000000, 0.187946,-0.206990;;, + 57;3; 0.000000, 0.187946,-0.206990;;, + 58;3; 0.000000, 0.187946,-0.206990;;, + 59;3; 0.000000, 0.187946,-0.206990;;, + 60;3; 0.000000, 0.187946,-0.206990;;, + 61;3; 0.000000, 0.187946,-0.206990;;, + 62;3; 0.000000, 0.187946,-0.206990;;, + 63;3; 0.000000, 0.187946,-0.206990;;, + 64;3; 0.000000, 0.187946,-0.206990;;, + 65;3; 0.000000, 0.187946,-0.206990;;, + 66;3; 0.000000, 0.187946,-0.206990;;, + 67;3; 0.000000, 0.187946,-0.206990;;, + 68;3; 0.000000, 0.187946,-0.206990;;, + 69;3; 0.000000, 0.187946,-0.206990;;, + 70;3; 0.000000, 0.187946,-0.206990;;, + 71;3; 0.000000, 0.187946,-0.206990;;, + 72;3; 0.000000, 0.187946,-0.206990;;, + 73;3; 0.000000, 0.187946,-0.206990;;, + 74;3; 0.000000, 0.187946,-0.206990;;, + 75;3; 0.000000, 0.187946,-0.206990;;, + 76;3; 0.000000, 0.187946,-0.206990;;, + 77;3; 0.000000, 0.187946,-0.206990;;, + 78;3; 0.000000, 0.187946,-0.206990;;, + 79;3; 0.000000, 0.187946,-0.206990;;, + 80;3; 0.000000, 0.187946,-0.206990;;, + 81;3; 0.000000, 0.187946,-0.206990;;, + 82;3; 0.000000, 0.187946,-0.206990;;, + 83;3; 0.000000, 0.187946,-0.206990;;, + 84;3; 0.000000, 0.187946,-0.206990;;, + 85;3; 0.000000, 0.187946,-0.206990;;, + 86;3; 0.000000, 0.187946,-0.206990;;, + 87;3; 0.000000, 0.187946,-0.206990;;, + 88;3; 0.000000, 0.187946,-0.206990;;, + 89;3; 0.000000, 0.187946,-0.206990;;, + 90;3; 0.000000, 0.187946,-0.206990;;, + 91;3; 0.000000, 0.187946,-0.206990;;, + 92;3; 0.000000, 0.187946,-0.206990;;, + 93;3; 0.000000, 0.187946,-0.206990;;, + 94;3; 0.000000, 0.187946,-0.206990;;, + 95;3; 0.000000, 0.187946,-0.206990;;, + 96;3; 0.000000, 0.187946,-0.206990;;, + 97;3; 0.000000, 0.187946,-0.206990;;, + 98;3; 0.000000, 0.187946,-0.206990;;, + 99;3; 0.000000, 0.187946,-0.206990;;, + 100;3; 0.000000, 0.187946,-0.206990;;, + 101;3; 0.000000, 0.187946,-0.206990;;, + 102;3; 0.000000, 0.187946,-0.206990;;, + 103;3; 0.000000, 0.187946,-0.206990;;, + 104;3; 0.000000, 0.187946,-0.206990;;, + 105;3; 0.000000, 0.187946,-0.206990;;, + 106;3; 0.000000, 0.187946,-0.206990;;, + 107;3; 0.000000, 0.187946,-0.206990;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 1;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 2;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 3;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 4;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 5;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 6;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 7;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 8;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 9;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 10;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 11;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 12;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 13;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 14;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 15;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 16;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 17;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 18;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 19;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 20;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 21;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 22;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 23;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 24;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 25;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 26;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 27;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 28;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 29;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 30;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 31;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 32;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 33;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 34;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 35;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 36;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 37;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 38;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 39;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 40;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 41;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 42;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 43;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 44;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 45;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 46;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 47;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 48;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 49;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 50;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 51;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 52;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 53;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 54;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 55;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 56;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 57;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 58;4; 0.001880, 0.999959, 0.000000,-0.000000;;, + 59;4; 0.007192, 0.999844, 0.000000,-0.000000;;, + 60;4; 0.013047, 0.999717, 0.000000,-0.000000;;, + 61;4; 0.019463, 0.999578, 0.000000,-0.000000;;, + 62;4; 0.027724, 0.999400, 0.000000,-0.000000;;, + 63;4; 0.035868, 0.999223, 0.000000,-0.000000;;, + 64;4; 0.041445, 0.999102, 0.000000,-0.000000;;, + 65;4; 0.043294, 0.999062, 0.000000,-0.000000;;, + 66;4; 0.041899, 0.999093, 0.000000,-0.000000;;, + 67;4; 0.038050, 0.999176, 0.000000,-0.000000;;, + 68;4; 0.032257, 0.999301, 0.000000,-0.000000;;, + 69;4; 0.025077, 0.999457, 0.000000,-0.000000;;, + 70;4; 0.017162, 0.999628, 0.000000,-0.000000;;, + 71;4; 0.009362, 0.999797, 0.000000,-0.000000;;, + 72;4; 0.002926, 0.999937, 0.000000,-0.000000;;, + 73;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 74;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 75;4; 0.015626, 0.998169, 0.000000,-0.000000;;, + 76;4; 0.049991, 0.994143, 0.000000,-0.000000;;, + 77;4; 0.091638, 0.989263, 0.000000,-0.000000;;, + 78;4; 0.133898, 0.984312, 0.000000,-0.000000;;, + 79;4; 0.172235, 0.979820, 0.000000,-0.000000;;, + 80;4; 0.203160, 0.976196, 0.000000,-0.000000;;, + 81;4; 0.223714, 0.973788, 0.000000,-0.000000;;, + 82;4; 0.231162, 0.972915, 0.000000,-0.000000;;, + 83;4; 0.223140, 0.973855, 0.000000,-0.000000;;, + 84;4; 0.199196, 0.976661, 0.000000,-0.000000;;, + 85;4; 0.161500, 0.981077, 0.000000,-0.000000;;, + 86;4; 0.115581, 0.986458, 0.000000,-0.000000;;, + 87;4; 0.069662, 0.991838, 0.000000,-0.000000;;, + 88;4; 0.031966, 0.996255, 0.000000,-0.000000;;, + 89;4; 0.008022, 0.999060, 0.000000,-0.000000;;, + 90;4; -0.000000, 1.000000,-0.000000,-0.000000;;, + 91;4; 0.006839, 0.999319, 0.000000,-0.000000;;, + 92;4; 0.027254, 0.997288, 0.000000,-0.000000;;, + 93;4; 0.059392, 0.994089, 0.000000,-0.000000;;, + 94;4; 0.098542, 0.990193, 0.000000,-0.000000;;, + 95;4; 0.137691, 0.986297, 0.000000,-0.000000;;, + 96;4; 0.169830, 0.983099, 0.000000,-0.000000;;, + 97;4; 0.190244, 0.981067, 0.000000,-0.000000;;, + 98;4; 0.197083, 0.980387, 0.000000,-0.000000;;, + 99;4; 0.190245, 0.981067, 0.000000,-0.000000;;, + 100;4; 0.169833, 0.983099, 0.000000,-0.000000;;, + 101;4; 0.137700, 0.986297, 0.000000,-0.000000;;, + 102;4; 0.098556, 0.990193, 0.000000,-0.000000;;, + 103;4; 0.059407, 0.994089, 0.000000,-0.000000;;, + 104;4; 0.027264, 0.997288, 0.000000,-0.000000;;, + 105;4; 0.006842, 0.999319, 0.000000,-0.000000;;, + 106;4; -0.000000, 1.000000, 0.000000,-0.000000;;, + 107;4; -0.000000, 1.000000, 0.000000,-0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Body_002} + AnimationKey { //Position + 2; + 108; + 0;3; 0.000000, 0.185728, 0.203380;;, + 1;3; 0.000000, 0.185728, 0.203380;;, + 2;3; 0.000000, 0.185728, 0.203380;;, + 3;3; 0.000000, 0.185728, 0.203380;;, + 4;3; 0.000000, 0.185728, 0.203380;;, + 5;3; 0.000000, 0.185728, 0.203380;;, + 6;3; 0.000000, 0.185728, 0.203380;;, + 7;3; 0.000000, 0.185728, 0.203380;;, + 8;3; 0.000000, 0.185728, 0.203380;;, + 9;3; 0.000000, 0.185728, 0.203380;;, + 10;3; 0.000000, 0.185728, 0.203380;;, + 11;3; 0.000000, 0.185728, 0.203380;;, + 12;3; 0.000000, 0.185728, 0.203380;;, + 13;3; 0.000000, 0.185728, 0.203380;;, + 14;3; 0.000000, 0.185728, 0.203380;;, + 15;3; 0.000000, 0.185728, 0.203380;;, + 16;3; 0.000000, 0.185728, 0.203380;;, + 17;3; 0.000000, 0.185728, 0.203380;;, + 18;3; 0.000000, 0.185728, 0.203380;;, + 19;3; 0.000000, 0.185728, 0.203380;;, + 20;3; 0.000000, 0.185728, 0.203380;;, + 21;3; 0.000000, 0.185728, 0.203380;;, + 22;3; 0.000000, 0.185728, 0.203380;;, + 23;3; 0.000000, 0.185728, 0.203380;;, + 24;3; 0.000000, 0.185728, 0.203380;;, + 25;3; 0.000000, 0.185728, 0.203380;;, + 26;3; 0.000000, 0.185728, 0.203380;;, + 27;3; 0.000000, 0.185728, 0.203380;;, + 28;3; 0.000000, 0.185728, 0.203380;;, + 29;3; 0.000000, 0.185728, 0.203380;;, + 30;3; 0.000000, 0.185728, 0.203380;;, + 31;3; 0.000000, 0.185728, 0.203380;;, + 32;3; 0.000000, 0.185728, 0.203380;;, + 33;3; 0.000000, 0.185728, 0.203380;;, + 34;3; 0.000000, 0.185728, 0.203380;;, + 35;3; 0.000000, 0.185728, 0.203380;;, + 36;3; 0.000000, 0.185728, 0.203380;;, + 37;3; 0.000000, 0.185728, 0.203380;;, + 38;3; 0.000000, 0.185728, 0.203380;;, + 39;3; 0.000000, 0.185728, 0.203380;;, + 40;3; 0.000000, 0.185728, 0.203380;;, + 41;3; 0.000000, 0.185728, 0.203380;;, + 42;3; 0.000000, 0.185728, 0.203380;;, + 43;3; 0.000000, 0.185728, 0.203380;;, + 44;3; 0.000000, 0.185728, 0.203380;;, + 45;3; 0.000000, 0.185728, 0.203380;;, + 46;3; 0.000000, 0.185728, 0.203380;;, + 47;3; 0.000000, 0.185728, 0.203380;;, + 48;3; 0.000000, 0.185728, 0.203380;;, + 49;3; 0.000000, 0.185728, 0.203380;;, + 50;3; 0.000000, 0.185728, 0.203380;;, + 51;3; 0.000000, 0.185728, 0.203380;;, + 52;3; 0.000000, 0.185728, 0.203380;;, + 53;3; 0.000000, 0.185728, 0.203380;;, + 54;3; 0.000000, 0.185728, 0.203380;;, + 55;3; 0.000000, 0.185728, 0.203380;;, + 56;3; 0.000000, 0.185728, 0.203380;;, + 57;3; 0.000000, 0.185728, 0.203380;;, + 58;3; 0.000000, 0.185728, 0.203380;;, + 59;3; 0.000000, 0.185728, 0.203380;;, + 60;3; 0.000000, 0.185728, 0.203380;;, + 61;3; 0.000000, 0.185728, 0.203380;;, + 62;3; 0.000000, 0.185728, 0.203380;;, + 63;3; 0.000000, 0.185728, 0.203380;;, + 64;3; 0.000000, 0.185728, 0.203380;;, + 65;3; 0.000000, 0.185728, 0.203380;;, + 66;3; 0.000000, 0.185728, 0.203380;;, + 67;3; 0.000000, 0.185728, 0.203380;;, + 68;3; 0.000000, 0.185728, 0.203380;;, + 69;3; 0.000000, 0.185728, 0.203380;;, + 70;3; 0.000000, 0.185728, 0.203380;;, + 71;3; 0.000000, 0.185728, 0.203380;;, + 72;3; 0.000000, 0.185728, 0.203380;;, + 73;3; 0.000000, 0.185728, 0.203380;;, + 74;3; 0.000000, 0.185728, 0.203380;;, + 75;3; 0.000000, 0.185728, 0.203380;;, + 76;3; 0.000000, 0.185728, 0.203380;;, + 77;3; 0.000000, 0.185728, 0.203380;;, + 78;3; 0.000000, 0.185728, 0.203380;;, + 79;3; 0.000000, 0.185728, 0.203380;;, + 80;3; 0.000000, 0.185727, 0.203380;;, + 81;3; 0.000000, 0.185728, 0.203380;;, + 82;3; 0.000000, 0.185728, 0.203380;;, + 83;3; 0.000000, 0.185728, 0.203380;;, + 84;3; 0.000000, 0.185727, 0.203380;;, + 85;3; 0.000000, 0.185728, 0.203380;;, + 86;3; 0.000000, 0.185728, 0.203380;;, + 87;3; 0.000000, 0.185728, 0.203380;;, + 88;3; 0.000000, 0.185728, 0.203380;;, + 89;3; 0.000000, 0.185728, 0.203380;;, + 90;3; 0.000000, 0.185728, 0.203380;;, + 91;3; 0.000000, 0.185728, 0.203380;;, + 92;3; 0.000000, 0.185728, 0.203380;;, + 93;3; 0.000000, 0.185728, 0.203380;;, + 94;3; 0.000000, 0.185728, 0.203380;;, + 95;3; 0.000000, 0.185728, 0.203380;;, + 96;3; 0.000000, 0.185728, 0.203380;;, + 97;3; 0.000000, 0.185728, 0.203380;;, + 98;3; 0.000000, 0.185728, 0.203380;;, + 99;3; 0.000000, 0.185728, 0.203380;;, + 100;3; 0.000000, 0.185728, 0.203380;;, + 101;3; 0.000000, 0.185728, 0.203380;;, + 102;3; 0.000000, 0.185728, 0.203380;;, + 103;3; 0.000000, 0.185728, 0.203380;;, + 104;3; 0.000000, 0.185728, 0.203380;;, + 105;3; 0.000000, 0.185728, 0.203380;;, + 106;3; 0.000000, 0.185728, 0.203380;;, + 107;3; 0.000000, 0.185728, 0.203380;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 1;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 2;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 3;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 4;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 5;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 6;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 7;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 8;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 9;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 10;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 11;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 12;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 13;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 14;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 15;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 16;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 17;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 18;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 19;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 20;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 21;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 22;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 23;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 24;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 25;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 26;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 27;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 28;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 29;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 30;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 31;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 32;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 33;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 34;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 35;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 36;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 37;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 38;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 39;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 40;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 41;4; -0.000000, 1.000000,-0.000000, 0.000000;;, + 42;4; -0.004277, 0.999865, 0.000000, 0.000000;;, + 43;4; -0.013685, 0.999567, 0.000000, 0.000000;;, + 44;4; -0.025085, 0.999205, 0.000000, 0.000000;;, + 45;4; -0.036655, 0.998839, 0.000000, 0.000000;;, + 46;4; -0.047150, 0.998507, 0.000000, 0.000000;;, + 47;4; -0.055616, 0.998239, 0.000000, 0.000000;;, + 48;4; -0.061243, 0.998060, 0.000000, 0.000000;;, + 49;4; -0.063282, 0.997996, 0.000000, 0.000000;;, + 50;4; -0.061086, 0.998065, 0.000000, 0.000000;;, + 51;4; -0.054531, 0.998273, 0.000000, 0.000000;;, + 52;4; -0.044212, 0.998600, 0.000000, 0.000000;;, + 53;4; -0.031641, 0.998998, 0.000000, 0.000000;;, + 54;4; -0.019070, 0.999396, 0.000000, 0.000000;;, + 55;4; -0.008751, 0.999723, 0.000000, 0.000000;;, + 56;4; -0.002196, 0.999930, 0.000000, 0.000000;;, + 57;4; -0.000000, 1.000000,-0.000000, 0.000000;;, + 58;4; -0.002423, 0.999932, 0.000000, 0.000000;;, + 59;4; -0.009268, 0.999741, 0.000000, 0.000000;;, + 60;4; -0.016812, 0.999531, 0.000000, 0.000000;;, + 61;4; -0.025079, 0.999300, 0.000000, 0.000000;;, + 62;4; -0.035723, 0.999003, 0.000000, 0.000000;;, + 63;4; -0.046218, 0.998710, 0.000000, 0.000000;;, + 64;4; -0.053403, 0.998509, 0.000000, 0.000000;;, + 65;4; -0.055786, 0.998443, 0.000000, 0.000000;;, + 66;4; -0.053989, 0.998493, 0.000000, 0.000000;;, + 67;4; -0.049029, 0.998631, 0.000000, 0.000000;;, + 68;4; -0.041565, 0.998840, 0.000000, 0.000000;;, + 69;4; -0.032313, 0.999098, 0.000000, 0.000000;;, + 70;4; -0.022114, 0.999383, 0.000000, 0.000000;;, + 71;4; -0.012064, 0.999663, 0.000000, 0.000000;;, + 72;4; -0.003771, 0.999895, 0.000000, 0.000000;;, + 73;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 74;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 75;4; -0.007476, 0.999644, 0.000000, 0.000000;;, + 76;4; -0.023917, 0.998849, 0.000000, 0.000000;;, + 77;4; -0.043843, 0.997862, 0.000000, 0.000000;;, + 78;4; -0.064063, 0.996828, 0.000000, 0.000000;;, + 79;4; -0.082406, 0.995842, 0.000000, 0.000000;;, + 80;4; -0.097203, 0.994979, 0.000000, 0.000000;;, + 81;4; -0.107038, 0.994301, 0.000000, 0.000000;;, + 82;4; -0.110602, 0.993865, 0.000000, 0.000000;;, + 83;4; -0.102646, 0.993617, 0.000000, 0.000000;;, + 84;4; -0.078897, 0.993470, 0.000000, 0.000000;;, + 85;4; -0.041511, 0.993409, 0.000000, 0.000000;;, + 86;4; 0.004030, 0.993400,-0.000000, 0.000000;;, + 87;4; 0.049571, 0.993391,-0.000000, 0.000000;;, + 88;4; 0.086957, 0.993330,-0.000000, 0.000000;;, + 89;4; 0.110704, 0.993182,-0.000000, 0.000000;;, + 90;4; 0.118660, 0.992935,-0.000000, 0.000000;;, + 91;4; 0.108565, 0.992415,-0.000000, 0.000000;;, + 92;4; 0.078432, 0.991462,-0.000000, 0.000000;;, + 93;4; 0.030993, 0.990149,-0.000000, 0.000000;;, + 94;4; -0.026794, 0.988645, 0.000000, 0.000000;;, + 95;4; -0.084582, 0.987193, 0.000000, 0.000000;;, + 96;4; -0.132021, 0.986026, 0.000000, 0.000000;;, + 97;4; -0.162155, 0.985296, 0.000000, 0.000000;;, + 98;4; -0.172251, 0.985053, 0.000000, 0.000000;;, + 99;4; -0.166274, 0.985572, 0.000000, 0.000000;;, + 100;4; -0.148433, 0.987120, 0.000000, 0.000000;;, + 101;4; -0.120347, 0.989557, 0.000000, 0.000000;;, + 102;4; -0.086134, 0.992527, 0.000000, 0.000000;;, + 103;4; -0.051918, 0.995496, 0.000000, 0.000000;;, + 104;4; -0.023827, 0.997933, 0.000000, 0.000000;;, + 105;4; -0.005980, 0.999481, 0.000000, 0.000000;;, + 106;4; -0.000000, 1.000000, 0.000000, 0.000000;;, + 107;4; -0.000000, 1.000000, 0.000000, 0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_IK_head} + AnimationKey { //Position + 2; + 108; + 0;3; -0.002513, 2.032632,-0.710142;;, + 1;3; 0.003029, 2.032632,-0.710205;;, + 2;3; 0.019705, 2.032632,-0.710394;;, + 3;3; 0.046815, 2.032632,-0.710702;;, + 4;3; 0.082268, 2.032632,-0.711105;;, + 5;3; 0.122426, 2.032632,-0.711561;;, + 6;3; 0.162579, 2.032632,-0.712017;;, + 7;3; 0.198022, 2.032632,-0.712420;;, + 8;3; 0.225121, 2.032632,-0.712728;;, + 9;3; 0.241788, 2.032632,-0.712917;;, + 10;3; 0.247326, 2.032632,-0.712980;;, + 11;3; 0.244145, 2.032632,-0.712714;;, + 12;3; 0.234264, 2.032632,-0.711886;;, + 13;3; 0.217479, 2.032632,-0.710481;;, + 14;3; 0.194218, 2.032632,-0.708534;;, + 15;3; 0.165740, 2.032632,-0.706149;;, + 16;3; 0.134057, 2.032632,-0.703497;;, + 17;3; 0.101506, 2.032632,-0.700772;;, + 18;3; 0.070184, 2.032632,-0.698150;;, + 19;3; 0.041593, 2.032632,-0.695756;;, + 20;3; 0.016584, 2.032632,-0.693663;;, + 21;3; -0.008426, 2.032632,-0.691569;;, + 22;3; -0.037016, 2.032632,-0.689175;;, + 23;3; -0.068338, 2.032632,-0.686553;;, + 24;3; -0.100890, 2.032632,-0.683828;;, + 25;3; -0.132572, 2.032632,-0.681176;;, + 26;3; -0.161050, 2.032632,-0.678791;;, + 27;3; -0.184311, 2.032632,-0.676844;;, + 28;3; -0.201096, 2.032632,-0.675439;;, + 29;3; -0.210978, 2.032632,-0.674611;;, + 30;3; -0.214159, 2.032632,-0.674345;;, + 31;3; -0.209825, 2.032632,-0.675078;;, + 32;3; -0.197888, 2.032632,-0.677097;;, + 33;3; -0.179747, 2.032632,-0.680165;;, + 34;3; -0.156637, 2.032632,-0.684074;;, + 35;3; -0.129732, 2.032632,-0.688625;;, + 36;3; -0.100266, 2.032632,-0.693608;;, + 37;3; -0.069709, 2.032632,-0.698777;;, + 38;3; -0.040113, 2.032632,-0.703782;;, + 39;3; -0.014989, 2.032632,-0.708032;;, + 40;3; -0.002513, 2.032632,-0.710142;;, + 41;3; -0.002513, 2.032632,-0.710142;;, + 42;3; -0.008930, 2.032632,-0.710142;;, + 43;3; -0.023043, 2.032632,-0.710142;;, + 44;3; -0.040147, 2.032632,-0.710142;;, + 45;3; -0.057504, 2.032632,-0.710142;;, + 46;3; -0.073249, 2.032632,-0.710142;;, + 47;3; -0.085951, 2.032632,-0.710142;;, + 48;3; -0.094393, 2.032632,-0.710142;;, + 49;3; -0.097452, 2.032632,-0.710142;;, + 50;3; -0.095389, 2.032632,-0.710092;;, + 51;3; -0.088904, 2.032632,-0.709935;;, + 52;3; -0.077889, 2.032632,-0.709668;;, + 53;3; -0.062950, 2.032632,-0.709307;;, + 54;3; -0.045489, 2.032632,-0.708884;;, + 55;3; -0.027292, 2.032632,-0.708443;;, + 56;3; -0.009895, 2.032632,-0.708022;;, + 57;3; 0.005751, 2.032632,-0.707643;;, + 58;3; 0.021832, 2.032632,-0.707254;;, + 59;3; 0.039347, 2.032632,-0.706830;;, + 60;3; 0.054648, 2.032632,-0.706460;;, + 61;3; 0.069212, 2.032632,-0.706107;;, + 62;3; 0.084604, 2.032632,-0.705735;;, + 63;3; 0.097938, 2.032632,-0.705412;;, + 64;3; 0.106319, 2.032632,-0.705209;;, + 65;3; 0.108954, 2.032632,-0.705145;;, + 66;3; 0.105086, 2.032632,-0.705318;;, + 67;3; 0.093540, 2.032632,-0.705836;;, + 68;3; 0.075363, 2.032632,-0.706651;;, + 69;3; 0.053221, 2.032632,-0.707643;;, + 70;3; 0.031078, 2.032632,-0.708636;;, + 71;3; 0.012901, 2.032632,-0.709451;;, + 72;3; 0.001355, 2.032632,-0.709968;;, + 73;3; -0.002513, 2.032632,-0.710142;;, + 74;3; -0.002513, 1.936344,-1.928771;;, + 75;3; -0.002513, 1.945240,-1.927712;;, + 76;3; -0.002513, 1.971791,-1.924551;;, + 77;3; -0.002513, 2.013590,-1.919574;;, + 78;3; -0.002513, 2.064508,-1.913512;;, + 79;3; -0.002513, 2.115429,-1.907449;;, + 80;3; -0.002513, 2.157234,-1.902473;;, + 81;3; -0.002513, 2.183791,-1.899312;;, + 82;3; -0.002513, 2.192689,-1.898253;;, + 83;3; -0.002513, 2.179227,-1.899748;;, + 84;3; -0.002513, 2.139049,-1.904208;;, + 85;3; -0.002513, 2.075801,-1.911230;;, + 86;3; -0.002513, 1.998762,-1.919784;;, + 87;3; -0.002513, 1.921726,-1.928343;;, + 88;3; -0.002513, 1.858487,-1.935375;;, + 89;3; -0.002513, 1.818318,-1.939846;;, + 90;3; -0.002513, 1.804860,-1.941345;;, + 91;3; -0.002513, 1.818518,-1.925309;;, + 92;3; -0.002513, 1.859243,-1.877552;;, + 93;3; -0.002513, 1.923315,-1.802499;;, + 94;3; -0.002513, 2.001404,-1.711082;;, + 95;3; -0.002513, 2.079635,-1.619478;;, + 96;3; -0.002513, 2.144034,-1.543998;;, + 97;3; -0.002513, 2.185064,-1.495840;;, + 98;3; -0.002513, 2.198845,-1.479644;;, + 99;3; -0.002513, 2.189593,-1.495524;;, + 100;3; -0.002513, 2.161810,-1.543163;;, + 101;3; -0.002513, 2.118002,-1.618187;;, + 102;3; -0.002513, 2.065008,-1.708839;;, + 103;3; -0.002513, 2.012862,-1.797974;;, + 104;3; -0.002513, 1.970968,-1.869573;;, + 105;3; -0.002513, 1.944924,-1.914098;;, + 106;3; -0.002513, 1.936344,-1.928771;;, + 107;3; -0.015253, 1.944273,-1.915417;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 1;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 2;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 3;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 4;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 5;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 6;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 7;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 8;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 9;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 10;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 11;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 12;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 13;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 14;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 15;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 16;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 17;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 18;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 19;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 20;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 21;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 22;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 23;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 24;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 25;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 26;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 27;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 28;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 29;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 30;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 31;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 32;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 33;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 34;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 35;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 36;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 37;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 38;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 39;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 40;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 41;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 42;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 43;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 44;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 45;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 46;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 47;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 48;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 49;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 50;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 51;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 52;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 53;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 54;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 55;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 56;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 57;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 58;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 59;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 60;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 61;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 62;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 63;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 64;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 65;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 66;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 67;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 68;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 69;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 70;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 71;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 72;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 73;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 74;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 75;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 76;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 77;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 78;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 79;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 80;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 81;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 82;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 83;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 84;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 85;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 86;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 87;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 88;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 89;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 90;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 91;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 92;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 93;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 94;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 95;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 96;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 97;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 98;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 99;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 100;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 101;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 102;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 103;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 104;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 105;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 106;4; -0.999994,-0.003482, 0.000000,-0.000000;;, + 107;4; -0.999994,-0.003482, 0.000000,-0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Bone_006} + AnimationKey { //Position + 2; + 108; + 0;3; -0.000000, 0.306782, 0.000000;;, + 1;3; -0.000000, 0.306782, 0.000000;;, + 2;3; -0.000000, 0.306782, 0.000000;;, + 3;3; -0.000000, 0.306782, 0.000000;;, + 4;3; -0.000000, 0.306782, 0.000000;;, + 5;3; -0.000000, 0.306782, 0.000000;;, + 6;3; -0.000000, 0.306782, 0.000000;;, + 7;3; -0.000000, 0.306782, 0.000000;;, + 8;3; -0.000000, 0.306782, 0.000000;;, + 9;3; -0.000000, 0.306782, 0.000000;;, + 10;3; -0.000000, 0.306782, 0.000000;;, + 11;3; -0.000000, 0.306782, 0.000000;;, + 12;3; -0.000000, 0.306782, 0.000000;;, + 13;3; -0.000000, 0.306782, 0.000000;;, + 14;3; -0.000000, 0.306782, 0.000000;;, + 15;3; -0.000000, 0.306782, 0.000000;;, + 16;3; -0.000000, 0.306782, 0.000000;;, + 17;3; -0.000000, 0.306782, 0.000000;;, + 18;3; -0.000000, 0.306782, 0.000000;;, + 19;3; -0.000000, 0.306782, 0.000000;;, + 20;3; -0.000000, 0.306782, 0.000000;;, + 21;3; -0.000000, 0.306782, 0.000000;;, + 22;3; -0.000000, 0.306782, 0.000000;;, + 23;3; -0.000000, 0.306782, 0.000000;;, + 24;3; -0.000000, 0.306782, 0.000000;;, + 25;3; -0.000000, 0.306782, 0.000000;;, + 26;3; -0.000000, 0.306782, 0.000000;;, + 27;3; -0.000000, 0.306782, 0.000000;;, + 28;3; -0.000000, 0.306782, 0.000000;;, + 29;3; -0.000000, 0.306782, 0.000000;;, + 30;3; -0.000000, 0.306782, 0.000000;;, + 31;3; -0.000000, 0.306782, 0.000000;;, + 32;3; -0.000000, 0.306782, 0.000000;;, + 33;3; -0.000000, 0.306782, 0.000000;;, + 34;3; -0.000000, 0.306782, 0.000000;;, + 35;3; -0.000000, 0.306782, 0.000000;;, + 36;3; -0.000000, 0.306782, 0.000000;;, + 37;3; -0.000000, 0.306782, 0.000000;;, + 38;3; -0.000000, 0.306782, 0.000000;;, + 39;3; -0.000000, 0.306782, 0.000000;;, + 40;3; -0.000000, 0.306782, 0.000000;;, + 41;3; -0.000000, 0.306782, 0.000000;;, + 42;3; -0.000000, 0.306782, 0.000000;;, + 43;3; -0.000000, 0.306782, 0.000000;;, + 44;3; -0.000000, 0.306782, 0.000000;;, + 45;3; -0.000000, 0.306782, 0.000000;;, + 46;3; -0.000000, 0.306782, 0.000000;;, + 47;3; -0.000000, 0.306782, 0.000000;;, + 48;3; -0.000000, 0.306782, 0.000000;;, + 49;3; -0.000000, 0.306782, 0.000000;;, + 50;3; -0.000000, 0.306782, 0.000000;;, + 51;3; -0.000000, 0.306782, 0.000000;;, + 52;3; -0.000000, 0.306782, 0.000000;;, + 53;3; -0.000000, 0.306782, 0.000000;;, + 54;3; -0.000000, 0.306782, 0.000000;;, + 55;3; -0.000000, 0.306782, 0.000000;;, + 56;3; -0.000000, 0.306782, 0.000000;;, + 57;3; -0.000000, 0.306782, 0.000000;;, + 58;3; -0.000000, 0.306782, 0.000000;;, + 59;3; -0.000000, 0.306782, 0.000000;;, + 60;3; -0.000000, 0.306782, 0.000000;;, + 61;3; -0.000000, 0.306782, 0.000000;;, + 62;3; -0.000000, 0.306782, 0.000000;;, + 63;3; -0.000000, 0.306782, 0.000000;;, + 64;3; -0.000000, 0.306782, 0.000000;;, + 65;3; -0.000000, 0.306782, 0.000000;;, + 66;3; -0.000000, 0.306782, 0.000000;;, + 67;3; -0.000000, 0.306782, 0.000000;;, + 68;3; -0.000000, 0.306782, 0.000000;;, + 69;3; -0.000000, 0.306782, 0.000000;;, + 70;3; -0.000000, 0.306782, 0.000000;;, + 71;3; -0.000000, 0.306782, 0.000000;;, + 72;3; -0.000000, 0.306782, 0.000000;;, + 73;3; -0.000000, 0.306782, 0.000000;;, + 74;3; 0.000000, 0.306782,-0.000000;;, + 75;3; 0.000000, 0.306782,-0.000000;;, + 76;3; 0.000000, 0.306782,-0.000000;;, + 77;3; 0.000000, 0.306782, 0.000000;;, + 78;3; 0.000000, 0.306782,-0.000000;;, + 79;3; 0.000000, 0.306782,-0.000000;;, + 80;3; 0.000000, 0.306782,-0.000000;;, + 81;3; 0.000000, 0.306782,-0.000000;;, + 82;3; 0.000000, 0.306782,-0.000000;;, + 83;3; 0.000000, 0.306782,-0.000000;;, + 84;3; 0.000000, 0.306782,-0.000000;;, + 85;3; 0.000000, 0.306782,-0.000000;;, + 86;3; 0.000000, 0.306782,-0.000000;;, + 87;3; 0.000000, 0.306782, 0.000000;;, + 88;3; 0.000000, 0.306782, 0.000000;;, + 89;3; 0.000000, 0.306782,-0.000000;;, + 90;3; 0.000000, 0.306782,-0.000000;;, + 91;3; 0.000000, 0.306782, 0.000000;;, + 92;3; 0.000000, 0.306782,-0.000000;;, + 93;3; 0.000000, 0.306782,-0.000000;;, + 94;3; 0.000000, 0.306782,-0.000000;;, + 95;3; 0.000000, 0.306782,-0.000000;;, + 96;3; 0.000000, 0.306782, 0.000000;;, + 97;3; 0.000000, 0.306782,-0.000000;;, + 98;3; 0.000000, 0.306782,-0.000000;;, + 99;3; 0.000000, 0.306782, 0.000000;;, + 100;3; 0.000000, 0.306782, 0.000000;;, + 101;3; 0.000000, 0.306782, 0.000000;;, + 102;3; 0.000000, 0.306782, 0.000000;;, + 103;3; 0.000000, 0.306782,-0.000000;;, + 104;3; 0.000000, 0.306782,-0.000000;;, + 105;3; 0.000000, 0.306782,-0.000000;;, + 106;3; 0.000000, 0.306782,-0.000000;;, + 107;3; -0.000000, 0.306782,-0.000000;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 1;4; -0.527614,-0.521697, 0.474320,-0.473524;;, + 2;4; -0.530802,-0.518079, 0.470380,-0.477122;;, + 3;4; -0.535985,-0.512196, 0.463975,-0.482972;;, + 4;4; -0.542764,-0.504502, 0.455598,-0.490624;;, + 5;4; -0.550443,-0.495786, 0.446109,-0.499292;;, + 6;4; -0.558122,-0.487070, 0.436619,-0.507959;;, + 7;4; -0.564900,-0.479376, 0.428242,-0.515611;;, + 8;4; -0.570083,-0.473494, 0.421838,-0.521461;;, + 9;4; -0.573270,-0.469876, 0.417899,-0.525058;;, + 10;4; -0.574329,-0.468674, 0.416590,-0.526254;;, + 11;4; -0.573665,-0.469478, 0.417462,-0.525499;;, + 12;4; -0.571604,-0.471962, 0.420154,-0.523156;;, + 13;4; -0.568105,-0.476149, 0.424694,-0.519183;;, + 14;4; -0.563262,-0.481894, 0.430929,-0.513690;;, + 15;4; -0.557341,-0.488840, 0.438472,-0.506982;;, + 16;4; -0.550765,-0.496445, 0.446740,-0.499544;;, + 17;4; -0.544025,-0.504100, 0.455074,-0.491936;;, + 18;4; -0.537558,-0.511276, 0.462901,-0.484654;;, + 19;4; -0.531676,-0.517607, 0.469822,-0.478052;;, + 20;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 21;4; -0.521480,-0.527910, 0.481147,-0.466682;;, + 22;4; -0.515742,-0.533392, 0.487201,-0.460317;;, + 23;4; -0.509507,-0.539187, 0.493617,-0.453419;;, + 24;4; -0.503070,-0.545036, 0.500108,-0.446312;;, + 25;4; -0.496839,-0.550595, 0.506286,-0.439444;;, + 26;4; -0.491262,-0.555494, 0.511740,-0.433305;;, + 27;4; -0.486723,-0.559433, 0.516130,-0.428313;;, + 28;4; -0.483456,-0.562239, 0.519260,-0.424724;;, + 29;4; -0.481538,-0.563874, 0.521085,-0.422618;;, + 30;4; -0.480921,-0.564396, 0.521669,-0.421941;;, + 31;4; -0.481856,-0.563546, 0.520726,-0.422973;;, + 32;4; -0.484429,-0.561206, 0.518129,-0.425815;;, + 33;4; -0.488341,-0.557649, 0.514183,-0.430133;;, + 34;4; -0.493324,-0.553118, 0.509156,-0.435635;;, + 35;4; -0.499125,-0.547843, 0.503303,-0.442041;;, + 36;4; -0.505478,-0.542065, 0.496893,-0.449056;;, + 37;4; -0.512066,-0.536074, 0.490246,-0.456331;;, + 38;4; -0.518448,-0.530272, 0.483808,-0.463377;;, + 39;4; -0.523865,-0.525346, 0.478343,-0.469358;;, + 40;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 41;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 42;4; -0.524850,-0.524520, 0.477419,-0.470438;;, + 43;4; -0.521100,-0.528085, 0.481358,-0.466281;;, + 44;4; -0.516557,-0.532405, 0.486132,-0.461244;;, + 45;4; -0.511945,-0.536789, 0.490976,-0.456131;;, + 46;4; -0.507763,-0.540766, 0.495370,-0.451494;;, + 47;4; -0.504388,-0.543974, 0.498915,-0.447753;;, + 48;4; -0.502146,-0.546106, 0.501270,-0.445267;;, + 49;4; -0.501333,-0.546878, 0.502124,-0.444366;;, + 50;4; -0.502208,-0.546046, 0.501205,-0.445336;;, + 51;4; -0.504821,-0.543562, 0.498460,-0.448232;;, + 52;4; -0.508934,-0.539652, 0.494140,-0.452792;;, + 53;4; -0.513944,-0.534889, 0.488876,-0.458347;;, + 54;4; -0.518954,-0.530126, 0.483613,-0.463901;;, + 55;4; -0.523067,-0.526216, 0.479293,-0.468461;;, + 56;4; -0.525679,-0.523732, 0.476548,-0.471358;;, + 57;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 58;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 59;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 60;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 61;4; -0.528979,-0.520291, 0.472777,-0.475049;;, + 62;4; -0.535807,-0.512944, 0.464744,-0.482712;;, + 63;4; -0.544574,-0.503511, 0.454430,-0.492552;;, + 64;4; -0.551403,-0.496165, 0.446398,-0.500216;;, + 65;4; -0.553827,-0.493556, 0.443546,-0.502936;;, + 66;4; -0.552948,-0.494502, 0.444580,-0.501950;;, + 67;4; -0.550523,-0.497111, 0.447433,-0.499228;;, + 68;4; -0.546874,-0.501037, 0.451725,-0.495133;;, + 69;4; -0.542351,-0.505903, 0.457046,-0.490057;;, + 70;4; -0.537365,-0.511268, 0.462911,-0.484461;;, + 71;4; -0.532452,-0.516554, 0.468691,-0.478947;;, + 72;4; -0.528398,-0.520916, 0.473460,-0.474397;;, + 73;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 74;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 75;4; -0.528282,-0.521070, 0.477189,-0.470676;;, + 76;4; -0.532082,-0.517047, 0.480621,-0.467041;;, + 77;4; -0.536687,-0.512171, 0.484781,-0.462637;;, + 78;4; -0.541360,-0.507223, 0.489002,-0.458168;;, + 79;4; -0.545599,-0.502735, 0.492831,-0.454113;;, + 80;4; -0.549019,-0.499114, 0.495920,-0.450843;;, + 81;4; -0.551291,-0.496707, 0.497973,-0.448669;;, + 82;4; -0.552115,-0.495835, 0.498717,-0.447881;;, + 83;4; -0.550457,-0.497520, 0.497219,-0.449403;;, + 84;4; -0.545507,-0.502547, 0.492748,-0.453943;;, + 85;4; -0.537714,-0.510461, 0.485709,-0.461092;;, + 86;4; -0.528222,-0.520101, 0.477135,-0.469800;;, + 87;4; -0.518730,-0.529742, 0.468560,-0.478509;;, + 88;4; -0.510937,-0.537656, 0.461522,-0.485657;;, + 89;4; -0.505987,-0.542683, 0.457051,-0.490198;;, + 90;4; -0.504329,-0.544367, 0.455553,-0.491720;;, + 91;4; -0.505971,-0.542702, 0.457035,-0.490215;;, + 92;4; -0.510870,-0.537730, 0.461461,-0.485724;;, + 93;4; -0.518584,-0.529904, 0.468429,-0.478655;;, + 94;4; -0.527981,-0.520369, 0.476917,-0.470042;;, + 95;4; -0.537378,-0.510835, 0.485405,-0.461430;;, + 96;4; -0.545092,-0.503008, 0.492373,-0.454360;;, + 97;4; -0.549992,-0.498037, 0.496799,-0.449870;;, + 98;4; -0.551633,-0.496371, 0.498282,-0.448365;;, + 99;4; -0.550763,-0.497292, 0.497496,-0.449197;;, + 100;4; -0.548165,-0.500040, 0.495150,-0.451679;;, + 101;4; -0.544076,-0.504366, 0.491455,-0.455586;;, + 102;4; -0.539094,-0.509635, 0.486955,-0.460346;;, + 103;4; -0.534112,-0.514905, 0.482455,-0.465107;;, + 104;4; -0.530023,-0.519231, 0.478761,-0.469014;;, + 105;4; -0.527425,-0.521979, 0.476415,-0.471496;;, + 106;4; -0.526554,-0.522900, 0.475629,-0.472328;;, + 107;4; -0.526554,-0.522900, 0.475629,-0.472328;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Armature_Bone_007} + AnimationKey { //Position + 2; + 108; + 0;3; 0.078315, 0.084604,-0.007980;;, + 1;3; 0.078315, 0.084604,-0.007980;;, + 2;3; 0.078315, 0.084604,-0.007980;;, + 3;3; 0.078315, 0.084604,-0.007980;;, + 4;3; 0.078315, 0.084604,-0.007980;;, + 5;3; 0.078315, 0.084604,-0.007980;;, + 6;3; 0.078315, 0.084604,-0.007980;;, + 7;3; 0.078315, 0.084604,-0.007980;;, + 8;3; 0.078315, 0.084604,-0.007980;;, + 9;3; 0.078315, 0.084604,-0.007980;;, + 10;3; 0.078315, 0.084604,-0.007980;;, + 11;3; 0.078315, 0.084604,-0.007980;;, + 12;3; 0.078315, 0.084604,-0.007980;;, + 13;3; 0.078315, 0.084604,-0.007980;;, + 14;3; 0.078315, 0.084604,-0.007980;;, + 15;3; 0.078315, 0.084604,-0.007980;;, + 16;3; 0.078315, 0.084604,-0.007980;;, + 17;3; 0.078315, 0.084604,-0.007980;;, + 18;3; 0.078315, 0.084604,-0.007980;;, + 19;3; 0.078315, 0.084604,-0.007980;;, + 20;3; 0.078315, 0.084604,-0.007980;;, + 21;3; 0.078316, 0.084604,-0.007980;;, + 22;3; 0.078315, 0.084604,-0.007980;;, + 23;3; 0.078315, 0.084604,-0.007980;;, + 24;3; 0.078315, 0.084604,-0.007980;;, + 25;3; 0.078316, 0.084604,-0.007980;;, + 26;3; 0.078316, 0.084604,-0.007980;;, + 27;3; 0.078315, 0.084604,-0.007980;;, + 28;3; 0.078315, 0.084604,-0.007980;;, + 29;3; 0.078315, 0.084604,-0.007980;;, + 30;3; 0.078315, 0.084604,-0.007980;;, + 31;3; 0.078315, 0.084604,-0.007980;;, + 32;3; 0.078315, 0.084604,-0.007980;;, + 33;3; 0.078315, 0.084604,-0.007980;;, + 34;3; 0.078315, 0.084604,-0.007980;;, + 35;3; 0.078315, 0.084604,-0.007980;;, + 36;3; 0.078315, 0.084604,-0.007980;;, + 37;3; 0.078315, 0.084604,-0.007980;;, + 38;3; 0.078315, 0.084604,-0.007980;;, + 39;3; 0.078316, 0.084604,-0.007980;;, + 40;3; 0.078315, 0.084604,-0.007980;;, + 41;3; 0.078315, 0.084604,-0.007980;;, + 42;3; 0.078315, 0.084604,-0.007980;;, + 43;3; 0.078316, 0.084604,-0.007980;;, + 44;3; 0.078315, 0.084604,-0.007980;;, + 45;3; 0.078315, 0.084604,-0.007980;;, + 46;3; 0.078315, 0.084604,-0.007980;;, + 47;3; 0.078315, 0.084604,-0.007980;;, + 48;3; 0.078315, 0.084604,-0.007980;;, + 49;3; 0.078315, 0.084604,-0.007980;;, + 50;3; 0.078315, 0.084604,-0.007980;;, + 51;3; 0.078315, 0.084604,-0.007980;;, + 52;3; 0.078315, 0.084604,-0.007980;;, + 53;3; 0.078315, 0.084604,-0.007980;;, + 54;3; 0.078316, 0.084604,-0.007980;;, + 55;3; 0.078316, 0.084604,-0.007980;;, + 56;3; 0.078315, 0.084604,-0.007980;;, + 57;3; 0.078315, 0.084604,-0.007980;;, + 58;3; 0.078315, 0.084604,-0.007980;;, + 59;3; 0.078315, 0.084604,-0.007980;;, + 60;3; 0.078315, 0.084604,-0.007980;;, + 61;3; 0.078315, 0.084604,-0.007980;;, + 62;3; 0.078315, 0.084604,-0.007980;;, + 63;3; 0.078316, 0.084604,-0.007980;;, + 64;3; 0.078315, 0.084604,-0.007980;;, + 65;3; 0.078315, 0.084604,-0.007980;;, + 66;3; 0.078315, 0.084604,-0.007980;;, + 67;3; 0.078315, 0.084604,-0.007980;;, + 68;3; 0.078315, 0.084604,-0.007980;;, + 69;3; 0.078315, 0.084604,-0.007980;;, + 70;3; 0.078315, 0.084604,-0.007980;;, + 71;3; 0.078315, 0.084604,-0.007980;;, + 72;3; 0.078315, 0.084604,-0.007980;;, + 73;3; 0.078315, 0.084604,-0.007980;;, + 74;3; 0.078315, 0.084604,-0.007980;;, + 75;3; 0.078315, 0.084604,-0.007980;;, + 76;3; 0.078315, 0.084604,-0.007980;;, + 77;3; 0.078316, 0.084604,-0.007980;;, + 78;3; 0.078315, 0.084604,-0.007980;;, + 79;3; 0.078315, 0.084604,-0.007980;;, + 80;3; 0.078315, 0.084604,-0.007980;;, + 81;3; 0.078315, 0.084604,-0.007980;;, + 82;3; 0.078315, 0.084604,-0.007980;;, + 83;3; 0.078315, 0.084604,-0.007980;;, + 84;3; 0.078315, 0.084604,-0.007980;;, + 85;3; 0.078315, 0.084604,-0.007980;;, + 86;3; 0.078316, 0.084604,-0.007980;;, + 87;3; 0.078316, 0.084604,-0.007980;;, + 88;3; 0.078316, 0.084604,-0.007980;;, + 89;3; 0.078315, 0.084604,-0.007980;;, + 90;3; 0.078315, 0.084604,-0.007980;;, + 91;3; 0.078315, 0.084604,-0.007980;;, + 92;3; 0.078315, 0.084604,-0.007980;;, + 93;3; 0.078315, 0.084604,-0.007980;;, + 94;3; 0.078315, 0.084604,-0.007980;;, + 95;3; 0.078316, 0.084604,-0.007980;;, + 96;3; 0.078315, 0.084604,-0.007980;;, + 97;3; 0.078315, 0.084604,-0.007980;;, + 98;3; 0.078315, 0.084604,-0.007980;;, + 99;3; 0.078315, 0.084604,-0.007980;;, + 100;3; 0.078315, 0.084604,-0.007980;;, + 101;3; 0.078315, 0.084604,-0.007980;;, + 102;3; 0.078315, 0.084604,-0.007980;;, + 103;3; 0.078316, 0.084604,-0.007980;;, + 104;3; 0.078315, 0.084604,-0.007980;;, + 105;3; 0.078315, 0.084604,-0.007980;;, + 106;3; 0.078315, 0.084604,-0.007980;;, + 107;3; 0.078315, 0.084604,-0.007980;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 1;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 2;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 3;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 4;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 5;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 6;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 7;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 8;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 9;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 10;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 11;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 12;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 13;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 14;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 15;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 16;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 17;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 18;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 19;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 20;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 21;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 22;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 23;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 24;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 25;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 26;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 27;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 28;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 29;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 30;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 31;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 32;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 33;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 34;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 35;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 36;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 37;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 38;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 39;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 40;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 41;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 42;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 43;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 44;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 45;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 46;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 47;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 48;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 49;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 50;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 51;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 52;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 53;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 54;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 55;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 56;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 57;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 58;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 59;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 60;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 61;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 62;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 63;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 64;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 65;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 66;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 67;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 68;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 69;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 70;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 71;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 72;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 73;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 74;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 75;4; -0.706230,-0.227278,-0.637929,-0.205297;;, + 76;4; -0.702922,-0.236361,-0.634941,-0.213502;;, + 77;4; -0.698913,-0.247369,-0.631319,-0.223445;;, + 78;4; -0.694845,-0.258540,-0.627644,-0.233535;;, + 79;4; -0.691154,-0.268673,-0.624311,-0.242689;;, + 80;4; -0.688177,-0.276848,-0.621622,-0.250073;;, + 81;4; -0.686199,-0.282281,-0.619834,-0.254980;;, + 82;4; -0.685482,-0.284249,-0.619187,-0.256758;;, + 83;4; -0.686254,-0.282129,-0.619884,-0.254843;;, + 84;4; -0.688559,-0.275800,-0.621966,-0.249126;;, + 85;4; -0.692188,-0.265836,-0.625244,-0.240126;;, + 86;4; -0.696608,-0.253699,-0.629237,-0.229162;;, + 87;4; -0.701028,-0.241561,-0.633230,-0.218199;;, + 88;4; -0.704657,-0.231598,-0.636508,-0.209199;;, + 89;4; -0.706962,-0.225269,-0.638590,-0.203482;;, + 90;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 91;4; -0.706658,-0.225928,-0.638315,-0.204078;;, + 92;4; -0.703445,-0.234227,-0.635412,-0.211573;;, + 93;4; -0.698386,-0.247291,-0.630843,-0.223374;;, + 94;4; -0.692224,-0.263205,-0.625277,-0.237749;;, + 95;4; -0.686062,-0.279119,-0.619711,-0.252124;;, + 96;4; -0.681003,-0.292183,-0.615141,-0.263925;;, + 97;4; -0.677790,-0.300481,-0.612239,-0.271420;;, + 98;4; -0.676713,-0.303261,-0.611266,-0.273932;;, + 99;4; -0.677790,-0.300481,-0.612239,-0.271420;;, + 100;4; -0.681003,-0.292183,-0.615141,-0.263925;;, + 101;4; -0.686062,-0.279119,-0.619711,-0.252124;;, + 102;4; -0.692224,-0.263205,-0.625277,-0.237749;;, + 103;4; -0.698386,-0.247291,-0.630843,-0.223374;;, + 104;4; -0.703445,-0.234227,-0.635412,-0.211573;;, + 105;4; -0.706658,-0.225928,-0.638315,-0.204078;;, + 106;4; -0.707734,-0.223148,-0.639287,-0.201567;;, + 107;4; -0.707120,-0.224647,-0.638732,-0.202920;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 1.000000, 1.000000, 1.000000;;, + 1;3; 1.000000, 1.000000, 1.000000;;, + 2;3; 1.000000, 1.000000, 1.000000;;, + 3;3; 1.000000, 1.000000, 1.000000;;, + 4;3; 1.000000, 1.000000, 1.000000;;, + 5;3; 1.000000, 1.000000, 1.000000;;, + 6;3; 1.000000, 1.000000, 1.000000;;, + 7;3; 1.000000, 1.000000, 1.000000;;, + 8;3; 1.000000, 1.000000, 1.000000;;, + 9;3; 1.000000, 1.000000, 1.000000;;, + 10;3; 1.000000, 1.000000, 1.000000;;, + 11;3; 1.000000, 1.000000, 1.000000;;, + 12;3; 1.000000, 1.000000, 1.000000;;, + 13;3; 1.000000, 1.000000, 1.000000;;, + 14;3; 1.000000, 1.000000, 1.000000;;, + 15;3; 1.000000, 1.000000, 1.000000;;, + 16;3; 1.000000, 1.000000, 1.000000;;, + 17;3; 1.000000, 1.000000, 1.000000;;, + 18;3; 1.000000, 1.000000, 1.000000;;, + 19;3; 1.000000, 1.000000, 1.000000;;, + 20;3; 1.000000, 1.000000, 1.000000;;, + 21;3; 1.000000, 1.000000, 1.000000;;, + 22;3; 1.000000, 1.000000, 1.000000;;, + 23;3; 1.000000, 1.000000, 1.000000;;, + 24;3; 1.000000, 1.000000, 1.000000;;, + 25;3; 1.000000, 1.000000, 1.000000;;, + 26;3; 1.000000, 1.000000, 1.000000;;, + 27;3; 1.000000, 1.000000, 1.000000;;, + 28;3; 1.000000, 1.000000, 1.000000;;, + 29;3; 1.000000, 1.000000, 1.000000;;, + 30;3; 1.000000, 1.000000, 1.000000;;, + 31;3; 1.000000, 1.000000, 1.000000;;, + 32;3; 1.000000, 1.000000, 1.000000;;, + 33;3; 1.000000, 1.000000, 1.000000;;, + 34;3; 1.000000, 1.000000, 1.000000;;, + 35;3; 1.000000, 1.000000, 1.000000;;, + 36;3; 1.000000, 1.000000, 1.000000;;, + 37;3; 1.000000, 1.000000, 1.000000;;, + 38;3; 1.000000, 1.000000, 1.000000;;, + 39;3; 1.000000, 1.000000, 1.000000;;, + 40;3; 1.000000, 1.000000, 1.000000;;, + 41;3; 1.000000, 1.000000, 1.000000;;, + 42;3; 1.000000, 1.000000, 1.000000;;, + 43;3; 1.000000, 1.000000, 1.000000;;, + 44;3; 1.000000, 1.000000, 1.000000;;, + 45;3; 1.000000, 1.000000, 1.000000;;, + 46;3; 1.000000, 1.000000, 1.000000;;, + 47;3; 1.000000, 1.000000, 1.000000;;, + 48;3; 1.000000, 1.000000, 1.000000;;, + 49;3; 1.000000, 1.000000, 1.000000;;, + 50;3; 1.000000, 1.000000, 1.000000;;, + 51;3; 1.000000, 1.000000, 1.000000;;, + 52;3; 1.000000, 1.000000, 1.000000;;, + 53;3; 1.000000, 1.000000, 1.000000;;, + 54;3; 1.000000, 1.000000, 1.000000;;, + 55;3; 1.000000, 1.000000, 1.000000;;, + 56;3; 1.000000, 1.000000, 1.000000;;, + 57;3; 1.000000, 1.000000, 1.000000;;, + 58;3; 1.000000, 1.000000, 1.000000;;, + 59;3; 1.000000, 1.000000, 1.000000;;, + 60;3; 1.000000, 1.000000, 1.000000;;, + 61;3; 1.000000, 1.000000, 1.000000;;, + 62;3; 1.000000, 1.000000, 1.000000;;, + 63;3; 1.000000, 1.000000, 1.000000;;, + 64;3; 1.000000, 1.000000, 1.000000;;, + 65;3; 1.000000, 1.000000, 1.000000;;, + 66;3; 1.000000, 1.000000, 1.000000;;, + 67;3; 1.000000, 1.000000, 1.000000;;, + 68;3; 1.000000, 1.000000, 1.000000;;, + 69;3; 1.000000, 1.000000, 1.000000;;, + 70;3; 1.000000, 1.000000, 1.000000;;, + 71;3; 1.000000, 1.000000, 1.000000;;, + 72;3; 1.000000, 1.000000, 1.000000;;, + 73;3; 1.000000, 1.000000, 1.000000;;, + 74;3; 1.000000, 1.000000, 1.000000;;, + 75;3; 1.000000, 1.000000, 1.000000;;, + 76;3; 1.000000, 1.000000, 1.000000;;, + 77;3; 1.000000, 1.000000, 1.000000;;, + 78;3; 1.000000, 1.000000, 1.000000;;, + 79;3; 1.000000, 1.000000, 1.000000;;, + 80;3; 1.000000, 1.000000, 1.000000;;, + 81;3; 1.000000, 1.000000, 1.000000;;, + 82;3; 1.000000, 1.000000, 1.000000;;, + 83;3; 1.000000, 1.000000, 1.000000;;, + 84;3; 1.000000, 1.000000, 1.000000;;, + 85;3; 1.000000, 1.000000, 1.000000;;, + 86;3; 1.000000, 1.000000, 1.000000;;, + 87;3; 1.000000, 1.000000, 1.000000;;, + 88;3; 1.000000, 1.000000, 1.000000;;, + 89;3; 1.000000, 1.000000, 1.000000;;, + 90;3; 1.000000, 1.000000, 1.000000;;, + 91;3; 1.000000, 1.000000, 1.000000;;, + 92;3; 1.000000, 1.000000, 1.000000;;, + 93;3; 1.000000, 1.000000, 1.000000;;, + 94;3; 1.000000, 1.000000, 1.000000;;, + 95;3; 1.000000, 1.000000, 1.000000;;, + 96;3; 1.000000, 1.000000, 1.000000;;, + 97;3; 1.000000, 1.000000, 1.000000;;, + 98;3; 1.000000, 1.000000, 1.000000;;, + 99;3; 1.000000, 1.000000, 1.000000;;, + 100;3; 1.000000, 1.000000, 1.000000;;, + 101;3; 1.000000, 1.000000, 1.000000;;, + 102;3; 1.000000, 1.000000, 1.000000;;, + 103;3; 1.000000, 1.000000, 1.000000;;, + 104;3; 1.000000, 1.000000, 1.000000;;, + 105;3; 1.000000, 1.000000, 1.000000;;, + 106;3; 1.000000, 1.000000, 1.000000;;, + 107;3; 1.000000, 1.000000, 1.000000;;; + } + } + Animation { + {Sand_monster} + AnimationKey { //Position + 2; + 108; + 0;3; -0.000000, 0.000000, 0.000000;;, + 1;3; -0.000000, 0.000000, 0.000000;;, + 2;3; -0.000000, 0.000000, 0.000000;;, + 3;3; -0.000000, 0.000000, 0.000000;;, + 4;3; -0.000000, 0.000000, 0.000000;;, + 5;3; -0.000000, 0.000000, 0.000000;;, + 6;3; -0.000000, 0.000000, 0.000000;;, + 7;3; -0.000000, 0.000000, 0.000000;;, + 8;3; -0.000000, 0.000000, 0.000000;;, + 9;3; -0.000000, 0.000000, 0.000000;;, + 10;3; -0.000000, 0.000000, 0.000000;;, + 11;3; -0.000000, 0.000000, 0.000000;;, + 12;3; -0.000000, 0.000000, 0.000000;;, + 13;3; -0.000000, 0.000000, 0.000000;;, + 14;3; -0.000000, 0.000000, 0.000000;;, + 15;3; -0.000000, 0.000000, 0.000000;;, + 16;3; -0.000000, 0.000000, 0.000000;;, + 17;3; -0.000000, 0.000000, 0.000000;;, + 18;3; -0.000000, 0.000000, 0.000000;;, + 19;3; -0.000000, 0.000000, 0.000000;;, + 20;3; -0.000000, 0.000000, 0.000000;;, + 21;3; -0.000000, 0.000000, 0.000000;;, + 22;3; -0.000000, 0.000000, 0.000000;;, + 23;3; -0.000000, 0.000000, 0.000000;;, + 24;3; -0.000000, 0.000000, 0.000000;;, + 25;3; -0.000000, 0.000000, 0.000000;;, + 26;3; -0.000000, 0.000000, 0.000000;;, + 27;3; -0.000000, 0.000000, 0.000000;;, + 28;3; -0.000000, 0.000000, 0.000000;;, + 29;3; -0.000000, 0.000000, 0.000000;;, + 30;3; -0.000000, 0.000000, 0.000000;;, + 31;3; -0.000000, 0.000000, 0.000000;;, + 32;3; -0.000000, 0.000000, 0.000000;;, + 33;3; -0.000000, 0.000000, 0.000000;;, + 34;3; -0.000000, 0.000000, 0.000000;;, + 35;3; -0.000000, 0.000000, 0.000000;;, + 36;3; -0.000000, 0.000000, 0.000000;;, + 37;3; -0.000000, 0.000000, 0.000000;;, + 38;3; -0.000000, 0.000000, 0.000000;;, + 39;3; -0.000000, 0.000000, 0.000000;;, + 40;3; -0.000000, 0.000000, 0.000000;;, + 41;3; -0.000000, 0.000000, 0.000000;;, + 42;3; -0.000000, 0.000000, 0.000000;;, + 43;3; -0.000000, 0.000000, 0.000000;;, + 44;3; -0.000000, 0.000000, 0.000000;;, + 45;3; -0.000000, 0.000000, 0.000000;;, + 46;3; -0.000000, 0.000000, 0.000000;;, + 47;3; -0.000000, 0.000000, 0.000000;;, + 48;3; -0.000000, 0.000000, 0.000000;;, + 49;3; -0.000000, 0.000000, 0.000000;;, + 50;3; -0.000000, 0.000000, 0.000000;;, + 51;3; -0.000000, 0.000000, 0.000000;;, + 52;3; -0.000000, 0.000000, 0.000000;;, + 53;3; -0.000000, 0.000000, 0.000000;;, + 54;3; -0.000000, 0.000000, 0.000000;;, + 55;3; -0.000000, 0.000000, 0.000000;;, + 56;3; -0.000000, 0.000000, 0.000000;;, + 57;3; -0.000000, 0.000000, 0.000000;;, + 58;3; -0.000000, 0.000000, 0.000000;;, + 59;3; -0.000000, 0.000000, 0.000000;;, + 60;3; -0.000000, 0.000000, 0.000000;;, + 61;3; -0.000000, 0.000000, 0.000000;;, + 62;3; -0.000000, 0.000000, 0.000000;;, + 63;3; -0.000000, 0.000000, 0.000000;;, + 64;3; -0.000000, 0.000000, 0.000000;;, + 65;3; -0.000000, 0.000000, 0.000000;;, + 66;3; -0.000000, 0.000000, 0.000000;;, + 67;3; -0.000000, 0.000000, 0.000000;;, + 68;3; -0.000000, 0.000000, 0.000000;;, + 69;3; -0.000000, 0.000000, 0.000000;;, + 70;3; -0.000000, 0.000000, 0.000000;;, + 71;3; -0.000000, 0.000000, 0.000000;;, + 72;3; -0.000000, 0.000000, 0.000000;;, + 73;3; -0.000000, 0.000000, 0.000000;;, + 74;3; -0.000000, 0.000000, 0.000000;;, + 75;3; -0.000000, 0.000000, 0.000000;;, + 76;3; -0.000000, 0.000000, 0.000000;;, + 77;3; -0.000000, 0.000000, 0.000000;;, + 78;3; -0.000000, 0.000000, 0.000000;;, + 79;3; -0.000000, 0.000000, 0.000000;;, + 80;3; -0.000000, 0.000000, 0.000000;;, + 81;3; -0.000000, 0.000000, 0.000000;;, + 82;3; -0.000000, 0.000000, 0.000000;;, + 83;3; -0.000000, 0.000000, 0.000000;;, + 84;3; -0.000000, 0.000000, 0.000000;;, + 85;3; -0.000000, 0.000000, 0.000000;;, + 86;3; -0.000000, 0.000000, 0.000000;;, + 87;3; -0.000000, 0.000000, 0.000000;;, + 88;3; -0.000000, 0.000000, 0.000000;;, + 89;3; -0.000000, 0.000000, 0.000000;;, + 90;3; -0.000000, 0.000000, 0.000000;;, + 91;3; -0.000000, 0.000000, 0.000000;;, + 92;3; -0.000000, 0.000000, 0.000000;;, + 93;3; -0.000000, 0.000000, 0.000000;;, + 94;3; -0.000000, 0.000000, 0.000000;;, + 95;3; -0.000000, 0.000000, 0.000000;;, + 96;3; -0.000000, 0.000000, 0.000000;;, + 97;3; -0.000000, 0.000000, 0.000000;;, + 98;3; -0.000000, 0.000000, 0.000000;;, + 99;3; -0.000000, 0.000000, 0.000000;;, + 100;3; -0.000000, 0.000000, 0.000000;;, + 101;3; -0.000000, 0.000000, 0.000000;;, + 102;3; -0.000000, 0.000000, 0.000000;;, + 103;3; -0.000000, 0.000000, 0.000000;;, + 104;3; -0.000000, 0.000000, 0.000000;;, + 105;3; -0.000000, 0.000000, 0.000000;;, + 106;3; -0.000000, 0.000000, 0.000000;;, + 107;3; -0.000000, 0.000000, 0.000000;;; + } + AnimationKey { //Rotation + 0; + 108; + 0;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 1;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 2;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 3;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 4;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 5;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 6;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 7;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 8;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 9;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 10;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 11;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 12;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 13;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 14;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 15;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 16;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 17;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 18;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 19;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 20;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 21;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 22;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 23;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 24;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 25;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 26;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 27;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 28;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 29;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 30;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 31;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 32;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 33;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 34;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 35;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 36;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 37;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 38;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 39;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 40;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 41;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 42;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 43;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 44;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 45;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 46;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 47;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 48;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 49;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 50;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 51;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 52;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 53;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 54;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 55;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 56;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 57;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 58;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 59;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 60;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 61;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 62;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 63;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 64;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 65;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 66;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 67;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 68;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 69;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 70;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 71;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 72;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 73;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 74;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 75;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 76;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 77;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 78;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 79;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 80;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 81;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 82;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 83;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 84;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 85;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 86;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 87;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 88;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 89;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 90;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 91;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 92;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 93;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 94;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 95;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 96;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 97;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 98;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 99;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 100;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 101;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 102;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 103;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 104;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 105;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 106;4; -1.000000, 0.000000, 0.000000, 0.000000;;, + 107;4; -1.000000, 0.000000, 0.000000, 0.000000;;; + } + AnimationKey { //Scale + 1; + 108; + 0;3; 0.746845, 0.740784, 0.740784;;, + 1;3; 0.746845, 0.740784, 0.740784;;, + 2;3; 0.746845, 0.740784, 0.740784;;, + 3;3; 0.746845, 0.740784, 0.740784;;, + 4;3; 0.746845, 0.740784, 0.740784;;, + 5;3; 0.746845, 0.740784, 0.740784;;, + 6;3; 0.746845, 0.740784, 0.740784;;, + 7;3; 0.746845, 0.740784, 0.740784;;, + 8;3; 0.746845, 0.740784, 0.740784;;, + 9;3; 0.746845, 0.740784, 0.740784;;, + 10;3; 0.746845, 0.740784, 0.740784;;, + 11;3; 0.746845, 0.740784, 0.740784;;, + 12;3; 0.746845, 0.740784, 0.740784;;, + 13;3; 0.746845, 0.740784, 0.740784;;, + 14;3; 0.746845, 0.740784, 0.740784;;, + 15;3; 0.746845, 0.740784, 0.740784;;, + 16;3; 0.746845, 0.740784, 0.740784;;, + 17;3; 0.746845, 0.740784, 0.740784;;, + 18;3; 0.746845, 0.740784, 0.740784;;, + 19;3; 0.746845, 0.740784, 0.740784;;, + 20;3; 0.746845, 0.740784, 0.740784;;, + 21;3; 0.746845, 0.740784, 0.740784;;, + 22;3; 0.746845, 0.740784, 0.740784;;, + 23;3; 0.746845, 0.740784, 0.740784;;, + 24;3; 0.746845, 0.740784, 0.740784;;, + 25;3; 0.746845, 0.740784, 0.740784;;, + 26;3; 0.746845, 0.740784, 0.740784;;, + 27;3; 0.746845, 0.740784, 0.740784;;, + 28;3; 0.746845, 0.740784, 0.740784;;, + 29;3; 0.746845, 0.740784, 0.740784;;, + 30;3; 0.746845, 0.740784, 0.740784;;, + 31;3; 0.746845, 0.740784, 0.740784;;, + 32;3; 0.746845, 0.740784, 0.740784;;, + 33;3; 0.746845, 0.740784, 0.740784;;, + 34;3; 0.746845, 0.740784, 0.740784;;, + 35;3; 0.746845, 0.740784, 0.740784;;, + 36;3; 0.746845, 0.740784, 0.740784;;, + 37;3; 0.746845, 0.740784, 0.740784;;, + 38;3; 0.746845, 0.740784, 0.740784;;, + 39;3; 0.746845, 0.740784, 0.740784;;, + 40;3; 0.746845, 0.740784, 0.740784;;, + 41;3; 0.746845, 0.740784, 0.740784;;, + 42;3; 0.746845, 0.740784, 0.740784;;, + 43;3; 0.746845, 0.740784, 0.740784;;, + 44;3; 0.746845, 0.740784, 0.740784;;, + 45;3; 0.746845, 0.740784, 0.740784;;, + 46;3; 0.746845, 0.740784, 0.740784;;, + 47;3; 0.746845, 0.740784, 0.740784;;, + 48;3; 0.746845, 0.740784, 0.740784;;, + 49;3; 0.746845, 0.740784, 0.740784;;, + 50;3; 0.746845, 0.740784, 0.740784;;, + 51;3; 0.746845, 0.740784, 0.740784;;, + 52;3; 0.746845, 0.740784, 0.740784;;, + 53;3; 0.746845, 0.740784, 0.740784;;, + 54;3; 0.746845, 0.740784, 0.740784;;, + 55;3; 0.746845, 0.740784, 0.740784;;, + 56;3; 0.746845, 0.740784, 0.740784;;, + 57;3; 0.746845, 0.740784, 0.740784;;, + 58;3; 0.746845, 0.740784, 0.740784;;, + 59;3; 0.746845, 0.740784, 0.740784;;, + 60;3; 0.746845, 0.740784, 0.740784;;, + 61;3; 0.746845, 0.740784, 0.740784;;, + 62;3; 0.746845, 0.740784, 0.740784;;, + 63;3; 0.746845, 0.740784, 0.740784;;, + 64;3; 0.746845, 0.740784, 0.740784;;, + 65;3; 0.746845, 0.740784, 0.740784;;, + 66;3; 0.746845, 0.740784, 0.740784;;, + 67;3; 0.746845, 0.740784, 0.740784;;, + 68;3; 0.746845, 0.740784, 0.740784;;, + 69;3; 0.746845, 0.740784, 0.740784;;, + 70;3; 0.746845, 0.740784, 0.740784;;, + 71;3; 0.746845, 0.740784, 0.740784;;, + 72;3; 0.746845, 0.740784, 0.740784;;, + 73;3; 0.746845, 0.740784, 0.740784;;, + 74;3; 0.746845, 0.740784, 0.740784;;, + 75;3; 0.746845, 0.740784, 0.740784;;, + 76;3; 0.746845, 0.740784, 0.740784;;, + 77;3; 0.746845, 0.740784, 0.740784;;, + 78;3; 0.746845, 0.740784, 0.740784;;, + 79;3; 0.746845, 0.740784, 0.740784;;, + 80;3; 0.746845, 0.740784, 0.740784;;, + 81;3; 0.746845, 0.740784, 0.740784;;, + 82;3; 0.746845, 0.740784, 0.740784;;, + 83;3; 0.746845, 0.740784, 0.740784;;, + 84;3; 0.746845, 0.740784, 0.740784;;, + 85;3; 0.746845, 0.740784, 0.740784;;, + 86;3; 0.746845, 0.740784, 0.740784;;, + 87;3; 0.746845, 0.740784, 0.740784;;, + 88;3; 0.746845, 0.740784, 0.740784;;, + 89;3; 0.746845, 0.740784, 0.740784;;, + 90;3; 0.746845, 0.740784, 0.740784;;, + 91;3; 0.746845, 0.740784, 0.740784;;, + 92;3; 0.746845, 0.740784, 0.740784;;, + 93;3; 0.746845, 0.740784, 0.740784;;, + 94;3; 0.746845, 0.740784, 0.740784;;, + 95;3; 0.746845, 0.740784, 0.740784;;, + 96;3; 0.746845, 0.740784, 0.740784;;, + 97;3; 0.746845, 0.740784, 0.740784;;, + 98;3; 0.746845, 0.740784, 0.740784;;, + 99;3; 0.746845, 0.740784, 0.740784;;, + 100;3; 0.746845, 0.740784, 0.740784;;, + 101;3; 0.746845, 0.740784, 0.740784;;, + 102;3; 0.746845, 0.740784, 0.740784;;, + 103;3; 0.746845, 0.740784, 0.740784;;, + 104;3; 0.746845, 0.740784, 0.740784;;, + 105;3; 0.746845, 0.740784, 0.740784;;, + 106;3; 0.746845, 0.740784, 0.740784;;, + 107;3; 0.746845, 0.740784, 0.740784;;; + } + } +} //End of AnimationSet diff --git a/mods/fantasy_mobs/mummy.lua b/mods/fantasy_mobs/mummy.lua new file mode 100644 index 0000000..ce0728d --- /dev/null +++ b/mods/fantasy_mobs/mummy.lua @@ -0,0 +1,47 @@ +mobs:register_mob('fantasy_mobs:mummy', { + description = 'Mummy', + type = 'monster', + damage = 20, + attack_type = 'dogfight', + hp_min = 100, + hp_max = 200, + armor = 50, + collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.9, 0.4}, + visual = 'mesh', + mesh = 'fantasy_mummy.x', + textures = { + {'fantasy_mummy.png'}, + }, + visual_size = {x = 8, y = 8}, + walk_velocity = 2, + run_velocity = 4, + jump = true, + water_damage = 15, + lava_damage = 30, + light_damage = 10, + reach = 3, + view_range = 7, + drops = { + {name = 'bonemeal:bone', chance = 2, min = 1, max = 10}, + {name = 'furniture:fabric_white', chance = 2, min = 1, max = 1} + }, + animation = { + stand_start = 74, + stand_end = 74, + walk_start = 74, + walk_end = 105, + punch_start = 74, + punch_end = 105, + }, +}) + +mobs:spawn({ + name = 'fantasy_mobs:mummy', + nodes = {'pyramids:deco_stone1', 'pyramids:deco_stone2', 'pyramids:deco_stone3', 'pyramids:trap'}, + max_light = 13, + min_height = -3, + max_height = 150, + interval = 30, + chance = 200, + active_object_count = 10, +}) diff --git a/mods/fantasy_mobs/sounds/fantasy_cavefreak_die.ogg b/mods/fantasy_mobs/sounds/fantasy_cavefreak_die.ogg new file mode 100644 index 0000000..1e9bb65 Binary files /dev/null and b/mods/fantasy_mobs/sounds/fantasy_cavefreak_die.ogg differ diff --git a/mods/fantasy_mobs/sounds/fantasy_cavefreak_punch.ogg b/mods/fantasy_mobs/sounds/fantasy_cavefreak_punch.ogg new file mode 100644 index 0000000..7742da2 Binary files /dev/null and b/mods/fantasy_mobs/sounds/fantasy_cavefreak_punch.ogg differ diff --git a/mods/fantasy_mobs/sounds/fantasy_fire_start.ogg b/mods/fantasy_mobs/sounds/fantasy_fire_start.ogg new file mode 100644 index 0000000..f175368 Binary files /dev/null and b/mods/fantasy_mobs/sounds/fantasy_fire_start.ogg differ diff --git a/mods/fantasy_mobs/sounds/gnome_angry.ogg b/mods/fantasy_mobs/sounds/gnome_angry.ogg new file mode 100644 index 0000000..873cbf8 Binary files /dev/null and b/mods/fantasy_mobs/sounds/gnome_angry.ogg differ diff --git a/mods/fantasy_mobs/sounds/gnome_confused.ogg b/mods/fantasy_mobs/sounds/gnome_confused.ogg new file mode 100644 index 0000000..1f3a1e7 Binary files /dev/null and b/mods/fantasy_mobs/sounds/gnome_confused.ogg differ diff --git a/mods/fantasy_mobs/sounds/gnome_happy.ogg b/mods/fantasy_mobs/sounds/gnome_happy.ogg new file mode 100644 index 0000000..7d6c1a9 Binary files /dev/null and b/mods/fantasy_mobs/sounds/gnome_happy.ogg differ diff --git a/mods/fantasy_mobs/sounds/slimes_attack.ogg b/mods/fantasy_mobs/sounds/slimes_attack.ogg new file mode 100644 index 0000000..7afa4cb Binary files /dev/null and b/mods/fantasy_mobs/sounds/slimes_attack.ogg differ diff --git a/mods/fantasy_mobs/sounds/slimes_damage.ogg b/mods/fantasy_mobs/sounds/slimes_damage.ogg new file mode 100644 index 0000000..966ff77 Binary files /dev/null and b/mods/fantasy_mobs/sounds/slimes_damage.ogg differ diff --git a/mods/fantasy_mobs/sounds/slimes_death.ogg b/mods/fantasy_mobs/sounds/slimes_death.ogg new file mode 100644 index 0000000..7eef1f4 Binary files /dev/null and b/mods/fantasy_mobs/sounds/slimes_death.ogg differ diff --git a/mods/fantasy_mobs/sounds/slimes_jump.ogg b/mods/fantasy_mobs/sounds/slimes_jump.ogg new file mode 100644 index 0000000..2c836e4 Binary files /dev/null and b/mods/fantasy_mobs/sounds/slimes_jump.ogg differ diff --git a/mods/fantasy_mobs/textures/fantasy_cavefreak1.png b/mods/fantasy_mobs/textures/fantasy_cavefreak1.png new file mode 100644 index 0000000..c37f9a4 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_cavefreak1.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_cavefreak2.png b/mods/fantasy_mobs/textures/fantasy_cavefreak2.png new file mode 100644 index 0000000..1877736 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_cavefreak2.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_cavefreak3.png b/mods/fantasy_mobs/textures/fantasy_cavefreak3.png new file mode 100644 index 0000000..281def6 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_cavefreak3.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_cavefreak_fire.png b/mods/fantasy_mobs/textures/fantasy_cavefreak_fire.png new file mode 100644 index 0000000..76f7663 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_cavefreak_fire.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_cloud_puff_blood.png b/mods/fantasy_mobs/textures/fantasy_cloud_puff_blood.png new file mode 100644 index 0000000..f1a3858 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_cloud_puff_blood.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_cloud_puff_front.png b/mods/fantasy_mobs/textures/fantasy_cloud_puff_front.png new file mode 100644 index 0000000..d73f103 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_cloud_puff_front.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_cloud_puff_sides.png b/mods/fantasy_mobs/textures/fantasy_cloud_puff_sides.png new file mode 100644 index 0000000..eec1224 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_cloud_puff_sides.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_fairy.png b/mods/fantasy_mobs/textures/fantasy_fairy.png new file mode 100644 index 0000000..23cf769 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_fairy.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_gnome_blue.png b/mods/fantasy_mobs/textures/fantasy_gnome_blue.png new file mode 100644 index 0000000..0d8e5e6 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_gnome_blue.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_gnome_green.png b/mods/fantasy_mobs/textures/fantasy_gnome_green.png new file mode 100644 index 0000000..52a6c46 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_gnome_green.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_gnome_inv.png b/mods/fantasy_mobs/textures/fantasy_gnome_inv.png new file mode 100644 index 0000000..8f64c5e Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_gnome_inv.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_gnome_orange.png b/mods/fantasy_mobs/textures/fantasy_gnome_orange.png new file mode 100644 index 0000000..9410ca1 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_gnome_orange.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_gnome_purple.png b/mods/fantasy_mobs/textures/fantasy_gnome_purple.png new file mode 100644 index 0000000..0077fd3 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_gnome_purple.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_gnome_red.png b/mods/fantasy_mobs/textures/fantasy_gnome_red.png new file mode 100644 index 0000000..d87696f Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_gnome_red.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_1.png b/mods/fantasy_mobs/textures/fantasy_goblin_1.png new file mode 100644 index 0000000..171e533 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_1.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_10.png b/mods/fantasy_mobs/textures/fantasy_goblin_10.png new file mode 100644 index 0000000..0e23a51 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_10.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_11.png b/mods/fantasy_mobs/textures/fantasy_goblin_11.png new file mode 100644 index 0000000..89d93a6 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_11.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_12.png b/mods/fantasy_mobs/textures/fantasy_goblin_12.png new file mode 100644 index 0000000..550e529 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_12.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_13.png b/mods/fantasy_mobs/textures/fantasy_goblin_13.png new file mode 100644 index 0000000..836c2fd Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_13.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_2.png b/mods/fantasy_mobs/textures/fantasy_goblin_2.png new file mode 100644 index 0000000..17260a7 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_2.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_3.png b/mods/fantasy_mobs/textures/fantasy_goblin_3.png new file mode 100644 index 0000000..acce829 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_3.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_4.png b/mods/fantasy_mobs/textures/fantasy_goblin_4.png new file mode 100644 index 0000000..a3729a5 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_4.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_5.png b/mods/fantasy_mobs/textures/fantasy_goblin_5.png new file mode 100644 index 0000000..baf1757 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_5.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_6.png b/mods/fantasy_mobs/textures/fantasy_goblin_6.png new file mode 100644 index 0000000..930fef7 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_6.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_7.png b/mods/fantasy_mobs/textures/fantasy_goblin_7.png new file mode 100644 index 0000000..b7da4cd Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_7.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_8.png b/mods/fantasy_mobs/textures/fantasy_goblin_8.png new file mode 100644 index 0000000..0101546 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_8.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblin_9.png b/mods/fantasy_mobs/textures/fantasy_goblin_9.png new file mode 100644 index 0000000..2586039 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblin_9.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_goblins_blood.png b/mods/fantasy_mobs/textures/fantasy_goblins_blood.png new file mode 100644 index 0000000..38f5092 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_goblins_blood.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_larva.png b/mods/fantasy_mobs/textures/fantasy_larva.png new file mode 100644 index 0000000..efd41bd Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_larva.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_mobs_larva_pet.png b/mods/fantasy_mobs/textures/fantasy_mobs_larva_pet.png new file mode 100644 index 0000000..73ae7a9 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_mobs_larva_pet.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_mummy.png b/mods/fantasy_mobs/textures/fantasy_mummy.png new file mode 100644 index 0000000..351383a Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_mummy.png differ diff --git a/mods/fantasy_mobs/textures/fantasy_mushrooms.png b/mods/fantasy_mobs/textures/fantasy_mushrooms.png new file mode 100644 index 0000000..5863474 Binary files /dev/null and b/mods/fantasy_mobs/textures/fantasy_mushrooms.png differ diff --git a/mods/farm_mobs/dog.lua b/mods/farm_mobs/dog.lua new file mode 100644 index 0000000..220029e --- /dev/null +++ b/mods/farm_mobs/dog.lua @@ -0,0 +1,56 @@ +mobs:register_mob('farm_mobs:dog', { + type = 'animal', + passive = true, + attack_type = 'dogfight', + group_attack = true, + reach = 2, + damage = 4, + hp_min = 5, + hp_max = 20, + armor = 200, + collisionbox = {-0.4, -0.01, -0.4, 0.4, 1, 0.4}, + visual = 'mesh', + visual_size = {x=7,y=7}, + mesh = 'farm_mobs_dog.b3d', + textures = { + {'farm_mobs_dog.png'}, + {'farm_mobs_dog1.png'}, + }, + makes_footstep_sound = true, + sounds = { + random = 'farm_mobs_dog', + attack = 'farm_mobs_dog', + }, + walk_velocity = 1, + run_velocity = 2, + jump = true, + drops = { + {name = 'mobs:meat_raw', chance = 1, min = 1, max = 3}, + }, + water_damage = 0, + lava_damage = 5, + light_damage = 0, + animation = { + speed_normal = 10, + speed_run = 15, + stand_start = 110, + stand_end = 140, + walk_start = 50, + walk_end = 90, + run_start = 50, + run_end = 90, + punch_start = 0, + punch_end = 40, + }, + follow = 'mobs:meat_raw', + view_range = 7, + fear_height = 2, + on_rightclick = function(self, clicker) + if mobs:feed_tame(self, clicker, 8, true, true) then + return + end + mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + end, +}) + +mobs:register_egg("farm_mobs:dog", "Dog", "default_grass.png", 1) diff --git a/mods/farm_mobs/german_shepherd.lua b/mods/farm_mobs/german_shepherd.lua new file mode 100644 index 0000000..4ac5344 --- /dev/null +++ b/mods/farm_mobs/german_shepherd.lua @@ -0,0 +1,75 @@ +mobs:register_mob('farm_mobs:german_shepherd', { + type = 'animal', + passive = false, + attack_type = 'dogfight', + group_attack = true, + reach = 3, + damage = 10, + hp_min = 50, + hp_max = 150, + armor = 75, + collisionbox = {-0.3, -0.01, -0.3, 0.3, .7, 0.3}, + visual = 'mesh', + visual_size = {x=4,y=4}, + rotate = 180, + mesh = 'farm_mobs_german_shepherd.b3d', + textures = { + {'farm_mobs_german_shepherd.png'}, + }, + makes_footstep_sound = true, + sounds = { + random = 'farm_mobs_dog', + attack = 'farm_mobs_dog', + }, + walk_velocity = 2, + run_velocity = 5, + jump = true, + drops = { + {name = 'mobs:meat_raw', chance = 1, min = 1, max = 3}, + }, + water_damage = 0, + lava_damage = 5, + light_damage = 0, + animation = { + speed_normal = 40, + speed_run = 30, + stand_speed = 7, + stand_start = 75, + stand_end = 95, + stand1_start = 100, + stand1_end = 130, + walk_start = 135, + walk_end = 195, + run_start = 135, + run_end = 195, + punch_start = 200, + punch_end = 250, + sit_start = 0, + sit_end = 20, + }, +-- follow = 'mobs:meat_raw', + view_range = 7, + fear_height = 2, +--[[ on_rightclick = function(self, clicker) + self.order = 'stand' + --mobs:set_velocity(self, 0) + self.object:set_animation({x = 0, y = 20}, 12, 0, false) + if mobs:feed_tame(self, clicker, 8, true, true) then + return + end + mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + end, +--]] +}) + +mobs:spawn({ + name = 'farm_mobs:german_shepherd', + nodes = {'default:dirt_with_coniferous_litter'}, + min_height = -15, + max_height = 300, + interval = 100, + chance = 8000, + active_object_count = 3, +}) + +mobs:register_egg("farm_mobs:german_shepherd", "German Shepherd", "default_grass.png", 1) diff --git a/mods/farm_mobs/goat.lua b/mods/farm_mobs/goat.lua new file mode 100644 index 0000000..519733f --- /dev/null +++ b/mods/farm_mobs/goat.lua @@ -0,0 +1,177 @@ +--[[ +Animation Data: +1-60 Eating +61-121 Tail wiggle +122-182 Walking +246-330 Attack +]] + +mobs:register_mob('farm_mobs:goat_she', { + type = 'animal', + passive = true, + attack_type = 'dogfight', + damage = 8, + hp_min = 5, hp_max = 15, armor = 200, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.75, 0.3}, + visual = 'mesh', + mesh = 'farm_mobs_she_goat.b3d', + textures = { + {'farm_mobs_goat_brown.png'}, + {'farm_mobs_goat_grey.png'}, + }, + blood_texture = 'mobs_blood.png', + visual_size = {x=2,y=2}, + makes_footstep_sound = true, + sounds = { + random = 'mobs_sheep', + }, + walk_velocity = 1, + run_velocity = 2, + jump = true, + stepheight = 1.1, + drops = { + {name = 'mobs:meat_raw', chance = 1, min = 1, max = 4}, + {name = 'mobs:leather', chance = 2, min = 1, max = 2}, + {name = 'bonemeal:bone', chance = 2, min = 1, max = 5}, + }, + water_damage = 0, + lava_damage = 5, + light_damage = 0, + animation = { + speed_normal = 30, speed_run = 45, + stand_start = 1, stand_end = 60, -- head down/up + walk_start = 122, walk_end = 182, -- walk + run_start = 122, run_end = 182, -- walk + punch_start = 246, punch_end = 330, -- attack + }, + follow = 'farming:wheat', + view_range = 7, + replace_rate = 7, + replace_what = { + {'group:flora', 'air', 0}, + {'group:grain', 'air', 0}, + {'group:veggie', 'air', 0}, + {'epic:poison', 'air', 0} + }, + on_replace = function(self, pos, oldnode, newnode) + if oldnode.name == 'epic:poison' then + self.health = 0 + end + end, + on_rightclick = function(self, clicker) + if mobs:protect(self, clicker) then return end + if mobs:feed_tame(self, clicker, 8, true, true) then + return + end + mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + local tool = clicker:get_wielded_item() + local name = clicker:get_player_name() + if tool:get_name() == 'bucket:bucket_empty' then + + if self.child == true then + return + end + if self.gotten == true then + minetest.chat_send_player(name,'Goat already milked!') + return + end + local inv = clicker:get_inventory() + tool:take_item() + clicker:set_wielded_item(tool) + if inv:room_for_item('main', {name = 'mobs:bucket_milk'}) then + clicker:get_inventory():add_item('main', 'mobs:bucket_milk') + else + local pos = self.object:get_pos() + pos.y = pos.y + 0.5 + minetest.add_item(pos, {name = 'mobs:bucket_milk'}) + end + self.gotten = true -- milked + return + end + end, +}) + +mobs:register_mob('farm_mobs:goat_he', { + type = 'animal', + passive = true, + attack_type = 'dogfight', + attack_npcs = false, + damage = 10, + hp_min = 5, hp_max = 15, armor = 200, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.75, 0.3}, + visual = 'mesh', + mesh = 'farm_mobs_he_goat.b3d', + textures = { + {'farm_mobs_goat_brown.png'}, + {'farm_mobs_goat_grey.png'}, + }, + blood_texture = 'mobs_blood.png', + visual_size = {x=2,y=2}, + makes_footstep_sound = true, + sounds = { + random = 'mobs_sheep', + }, + walk_velocity = 1, + run_velocity = 2, + jump = true, + stepheight = 1.1, + drops = { + {name = 'mobs:meat_raw', chance = 1, min = 1, max = 4}, + {name = 'mobs:leather', chance = 2, min = 1, max = 2}, + {name = 'bonemeal:bone', chance = 2, min = 1, max = 5}, + }, + water_damage = 0, + lava_damage = 5, + light_damage = 0, + animation = { + speed_normal = 30, speed_run = 45, + stand_start = 1, stand_end = 60, -- head down/up + walk_start = 122, walk_end = 182, -- walk + run_start = 122, run_end = 182, -- walk + punch_start = 246, punch_end = 330, -- attack + }, + follow = 'farming:wheat', + view_range = 7, + replace_rate = 7, + replace_what = { + {'group:flora', 'air', 0}, + {'group:grain', 'air', 0}, + {'group:veggie', 'air', 0}, + {'epic:poison', 'air', 0} + }, + on_replace = function(self, pos, oldnode, newnode) + if oldnode.name == 'epic:poison' then + self.health = 0 + end + end, + on_rightclick = function(self, clicker) + if mobs:protect(self, clicker) then return end + if mobs:feed_tame(self, clicker, 8, true, true) then + return + end + mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + end, + }) + +mobs:spawn({ + name = 'farm_mobs:goat_she', + nodes = {'default:dirt_with_grass', 'default:dirt_with_dry_grass', 'default:dirt'}, + min_height = -5, + max_height = 100, + interval = 63, + chance = 10000, + active_object_count = 5, +}) + +mobs:spawn({ + name = 'farm_mobs:goat_he', + nodes = {'default:dirt_with_grass', 'default:dirt_with_dry_grass', 'default:dirt'}, + min_height = -5, + max_height = 100, + interval = 64, + chance = 10000, + active_object_count = 5, +}) + +mobs:register_egg('farm_mobs:goat_she', 'She Goat', 'default_grass.png', 1) +mobs:register_egg('farm_mobs:goat_he', 'He Goat', 'default_grass.png', 1) diff --git a/mods/farm_mobs/init.lua b/mods/farm_mobs/init.lua new file mode 100644 index 0000000..3534516 --- /dev/null +++ b/mods/farm_mobs/init.lua @@ -0,0 +1,3 @@ +dofile(minetest.get_modpath('farm_mobs')..'/dog.lua') +dofile(minetest.get_modpath('farm_mobs')..'/german_shepherd.lua') +dofile(minetest.get_modpath('farm_mobs')..'/goat.lua') diff --git a/mods/farm_mobs/license.txt b/mods/farm_mobs/license.txt new file mode 100644 index 0000000..15e2bcc --- /dev/null +++ b/mods/farm_mobs/license.txt @@ -0,0 +1,2 @@ +Graphics and models by Nathan Salapat (NathanS21) CC by SA 4.0 +dog bark by jorickhoofd CC by SA 3.0 diff --git a/mods/farm_mobs/mod.conf b/mods/farm_mobs/mod.conf new file mode 100644 index 0000000..2bd9442 --- /dev/null +++ b/mods/farm_mobs/mod.conf @@ -0,0 +1,2 @@ +name = farm_mobs +depends = mobs diff --git a/mods/farm_mobs/models/farm_mobs_dog.b3d b/mods/farm_mobs/models/farm_mobs_dog.b3d new file mode 100644 index 0000000..66137de Binary files /dev/null and b/mods/farm_mobs/models/farm_mobs_dog.b3d differ diff --git a/mods/farm_mobs/models/farm_mobs_german_shepherd.b3d b/mods/farm_mobs/models/farm_mobs_german_shepherd.b3d new file mode 100644 index 0000000..5ac22cf Binary files /dev/null and b/mods/farm_mobs/models/farm_mobs_german_shepherd.b3d differ diff --git a/mods/farm_mobs/models/farm_mobs_he_goat.b3d b/mods/farm_mobs/models/farm_mobs_he_goat.b3d new file mode 100644 index 0000000..e7a9367 Binary files /dev/null and b/mods/farm_mobs/models/farm_mobs_he_goat.b3d differ diff --git a/mods/farm_mobs/models/farm_mobs_she_goat.b3d b/mods/farm_mobs/models/farm_mobs_she_goat.b3d new file mode 100644 index 0000000..0737af8 Binary files /dev/null and b/mods/farm_mobs/models/farm_mobs_she_goat.b3d differ diff --git a/mods/farm_mobs/readme.md b/mods/farm_mobs/readme.md new file mode 100644 index 0000000..9de133c --- /dev/null +++ b/mods/farm_mobs/readme.md @@ -0,0 +1,3 @@ +This mod adds a handful of animals to your worlds that you would commonly see on a typical farm. +Currently includes: dog, +Planned animals: Pig, Sheep, Cow, Bull, Skunk, Raccoon, Opossum, diff --git a/mods/farm_mobs/screenshot.png b/mods/farm_mobs/screenshot.png new file mode 100644 index 0000000..bcaa951 Binary files /dev/null and b/mods/farm_mobs/screenshot.png differ diff --git a/mods/farm_mobs/sounds/farm_mobs_dog.ogg b/mods/farm_mobs/sounds/farm_mobs_dog.ogg new file mode 100644 index 0000000..7ff5455 Binary files /dev/null and b/mods/farm_mobs/sounds/farm_mobs_dog.ogg differ diff --git a/mods/farm_mobs/textures/dog_base.png b/mods/farm_mobs/textures/dog_base.png new file mode 100644 index 0000000..d6d661b Binary files /dev/null and b/mods/farm_mobs/textures/dog_base.png differ diff --git a/mods/farm_mobs/textures/farm_mobs_dog.png b/mods/farm_mobs/textures/farm_mobs_dog.png new file mode 100644 index 0000000..c5b55a5 Binary files /dev/null and b/mods/farm_mobs/textures/farm_mobs_dog.png differ diff --git a/mods/farm_mobs/textures/farm_mobs_dog1.png b/mods/farm_mobs/textures/farm_mobs_dog1.png new file mode 100644 index 0000000..101639b Binary files /dev/null and b/mods/farm_mobs/textures/farm_mobs_dog1.png differ diff --git a/mods/farm_mobs/textures/farm_mobs_german_shepherd.png b/mods/farm_mobs/textures/farm_mobs_german_shepherd.png new file mode 100644 index 0000000..e550903 Binary files /dev/null and b/mods/farm_mobs/textures/farm_mobs_german_shepherd.png differ diff --git a/mods/farm_mobs/textures/farm_mobs_goat_brown.png b/mods/farm_mobs/textures/farm_mobs_goat_brown.png new file mode 100644 index 0000000..dff7bd4 Binary files /dev/null and b/mods/farm_mobs/textures/farm_mobs_goat_brown.png differ diff --git a/mods/farm_mobs/textures/farm_mobs_goat_grey.png b/mods/farm_mobs/textures/farm_mobs_goat_grey.png new file mode 100644 index 0000000..bcf5e03 Binary files /dev/null and b/mods/farm_mobs/textures/farm_mobs_goat_grey.png differ diff --git a/mods/farm_mobs/textures/mobs_german_shepherd.png b/mods/farm_mobs/textures/mobs_german_shepherd.png new file mode 100644 index 0000000..d2bbb45 Binary files /dev/null and b/mods/farm_mobs/textures/mobs_german_shepherd.png differ diff --git a/mods/farming/README.md b/mods/farming/README.md new file mode 100644 index 0000000..128bf76 --- /dev/null +++ b/mods/farming/README.md @@ -0,0 +1,67 @@ +# Farming Redo Mod +### by TenPlus1 + +https://forum.minetest.net/viewtopic.php?id=9019 + +Farming Redo is a simplified version of the built-in farming mod in minetest and comes with wheat, cotton, carrot, cucumber, potato and tomato to start out with which spawn throughout the map... new foods need only be planted on tilled soil so no seeds are required, original wheat and cotton will require seeds which are found inside normal and jungle grass... + +This mod works by adding your new plant to the {growing=1} group and numbering the stages from _1 to as many stages as you like, but the underscore MUST be used only once in the node name to separate plant from stage number e.g. + +"farming:cotton_1" through to "farming:cotton_8" +"farming:wheat_1" through to "farming:wheat_8" +"farming:cucumber_4" through to "farming:cucumber_4" + +### Changelog: + +- 1.43 - Scythe works on use instead of right-click, added seed=1 groups to actual seeds and seed=2 group for plantable food items. +- 1.42 - Soil needs water to be present within 3 blocks horizontally and 1 below to make wet soil, Jack 'o Lanterns now check protection, add chocolate block. +- 1.41 - Each crop has it's own spawn rate (can be changed in farming.conf) +- 1.40 - Added Mithril Scythe to quick harvest and replant crops on right-click. Added Hoe's for MoreOres with Toolrank support. +- 1.39 - Added Rice, Rye and Oats thanks to Ademants Grains mod. Added Jaffa Cake and multigrain bread. +- 1.38 - Pumpkin grows into block, use chopping board to cut into 4x slices, same with melon block, 2x2 slices makes a block, cocoa pods are no longer walkable +- 1.37 - Added custom 'growth_check(pos, nodename) function for crop nodes to use (check cocoa.lua for example) +- 1.36 - Added Beetroot, Beetroot Soup (6x beetroot, 1x bowl), fix register_plant() issue, add new recipes +- 1.35 - Deprecated bronze/mese/diamond hoe's, added hoe bomb and deprecated hoe's as lucky block prizes +- 1.34 - Added scarecrow Base (5x sticks in a cross shape) +- 1.33 - Added cooking utensils (wooden bowl, saucepan, cooking pot, baking tray, skillet, cutting board, mortar & pestle, juicer, glass mixing bowl) for easier food crafts. +- 1.32 - Added Pea plant (textures by Andrey01) - also added Wooden Bowl and Pea Soup crafts +- 1.31 - Added Pineapple which can be found growing in savannah areas (place pineapple in crafting to obtain 5x rings to eat and a top for re-planting), also Salt which is made from cooking a bucket of water, added food groups so it's more compatible with Ruben's food mods. +- 1.30 - Added Garlic, Pepper and Onions thanks to Grizzly Adam for sharing textures +- 1.29 - Updating functions so requires Minetest 0.4.16 and above to run +- 1.28 - Added chili peppers and bowl of chili, optimized code and fixed a few bugs, added porridge +- 1.27 - Added meshoptions to api and wheat plants, added farming.rarity setting to spawn more/less crops on map, have separate cotton/string items (4x cotton = 1x wool, 2x cotton = 2x string) +- 1.26 - Added support for [toolranks] mod when using hoe's +- 1.25 - Added check for farming.conf setting file to disable specific crops globally (inside mod folder) or world specific (inside world folder) +- 1.24 - Added Hemp which can be crafted into fibre, paper, string, rope and oil. +- 1.23 - Huge code tweak and tidy done and added barley seeds to be found in dry grass, barley can make flour for bread also. +- 1.22 - Added grape bushes at high climates which can be cultivated into grape vines using trellis (9 sticks). +- 1.21 - Added auto-refill code for planting crops (thanks crabman77), also fixed a few bugs +- 1.20b - Tidied code, made api compatible with new 0.4.13 changes and changed to soil texture overlays +- 1.20 - NEW growing routine added that allows crops to grow while player is away doing other things (thanks prestidigitator) +- 1.14 - Added Green Beans from Crops mod (thanks sofar), little bushels in the wild but need to be grown using beanpoles crafted with 4 sticks (2 either side) +- 1.13 - Fixed seed double-placement glitch. Mapgen now uses 0.4.12+ for plant generation +- 1.12 - Player cannot place seeds in protected area, also growing speeds changed to match defaults +- 1.11 - Added Straw Bale, streamlined growing abm a little, fixed melon rotation bug with screwdriver +- 1.10 - Added Blueberry Bush and Blueberry Muffins, also Pumpkin/Melon easier to pick up, added check for unloaded map +- 1.09 - Corn now uses single nodes instead of 1 ontop of the other, Ethanol recipe is more expensive (requires 5 corn) and some code cleanup. +- 1.08 - Added Farming Plus compatibility, plus can be removed and no more missing nodes +- 1.07 - Added Rhubarb and Rhubarb Pie +- 1.06 - register_hoe and register_plant added for compatibility with default farming mod, although any plants registered will use farming redo to grow +- 1.05 - Added Raspberry Bushels and Raspberry Smoothie +- 1.04 - Added Donuts... normal, chocolate and apple... and a few code cleanups and now compatible with jungletree's from MoreTrees mod +- 1.03 - Bug fixes and more compatibility as drop-in replacement for built-in farming mod +- 1.02 - Added farming.mod string to help other mods identify which farming mod is running, if it returns "redo" then you're using this one, "" empty is built-in mod +- 1.01 - Crafting coffee or ethanol returns empty bucket/bottle, also Cocoa spawns a little rarer +- 1.0 - Added Cocoa which randomly grows on jungle tree's, pods give cocoa beans which can be used to farm more pods on a jungle trunk or make Cookies which have been added (or other treats) +- 0.9 - Added Pumpkin, Jack 'O Lantern, Pumpkin Slice and Sugar (a huge thanks to painterly.net for allowing me to use their textures) +- 0.8 - Added Watermelon and Melon Slice +- 0.7 - Added Coffee, Coffee Beans, Drinking Cup, Cold and Hot Cup of Coffee +- 0.6 - Added Corn, Corn on the Cob... Also reworked Abm +- 0.5 - Added Carrot, Cucumber, Potato (and Baked Potato), Tomato +- 0.4 - Checks for Protection, also performance changes +- 0.3 - Added Diamond and Mese hoe +- 0.2 - Fixed check for wet soil +- 0.1 - Fixed growing bug +- 0.0 - Initial release + +### Lucky Blocks: 39 diff --git a/mods/farming/api.txt b/mods/farming/api.txt new file mode 100644 index 0000000..acec5a0 --- /dev/null +++ b/mods/farming/api.txt @@ -0,0 +1,64 @@ +Farming API +----------- + +The farming API allows you to easily register plants and hoes. + +`farming.register_hoe(name, hoe definition)` + * Register a new hoe, see [#hoe definition] + +`farming.register_plant(name, Plant definition)` + * Register a new growing plant, see [#Plant definition] + +`farming.registered_plants[name] = definition` + * Table of registered plants, indexed by plant name + 'crop' holds name of growing crop node minus _step-number at end + 'seed' has name of seed required to plant crop + 'minlight' min light level needed to grow + 'maxlight' max light level needed to grow + 'steps' number of steps crop has in growth cycle + +### Hoe Definition + + + { + description = "", -- Description for tooltip + inventory_image = "unknown_item.png", -- Image to be used as wield- and inventory image + max_uses = 30, -- Uses until destroyed + material = "", -- Material for recipes + recipe = { -- Craft recipe, if material isn't used + {"air", "air", "air"}, + {"", "group:stick"}, + {"", "group:stick"}, + } + } + +### Plant definition + + { + description = "", -- Description of seed item + inventory_image = "unknown_item.png", -- Image to be used as seed's wield- and inventory image + steps = 8, -- How many steps the plant has to grow, until it can be harvested + -- ^ Always provide a plant texture for each step, format: modname_plantname_i.png (i = stepnumber) + minlight = 13, -- Minimum light to grow + maxlight = default.LIGHT_MAX -- Maximum light to grow + } + +Note: Any crops registered with the above function will use the new growing routines, also if crops are manually added with the {growing=1} group they will also grow. + +### Crop functions + +If a mod registers nodes to be used as crops using the {growing=1} group then an additional function can be used for custom growth checks instead of the standard 'are we above wet soil'. + +growth_check = function(pos, node_name) + -- check surrounding for jungle tree + if minetest.find_node_near(pos, 1, {"default:jungletree"}) then + return false -- place next growth stage + end + return true -- condition not met, skip next growth stage until next check +end, + +### Scythe items that will not drop + +This is a function to add items to a list that scythes will not drop, e.g. farming:trellis or farming:beanpole. + +farming.add_to_scythe_not_drops(item_name) diff --git a/mods/farming/compatibility.lua b/mods/farming/compatibility.lua new file mode 100644 index 0000000..808000d --- /dev/null +++ b/mods/farming/compatibility.lua @@ -0,0 +1,172 @@ + +--= Helpers + +local eth = minetest.get_modpath("ethereal") +local alias = function(orig, new) + minetest.register_alias(orig, new) +end + +--= Overrides (add food_* group to apple and brown mushroom) + +minetest.override_item("default:apple", { + groups = {food_apple = 1, fleshy = 3, dig_immediate = 3, flammable = 2, + leafdecay = 3, leafdecay_drop = 1}, +}) + +if minetest.registered_nodes["flowers:mushroom_brown"] then +minetest.override_item("flowers:mushroom_brown", { + light_source = 1, + groups = {food_mushroom = 1, snappy = 3, attached_node = 1, flammable = 2}, +}) +end + +--= Aliases + +-- Banana +if eth then + alias("farming_plus:banana_sapling", "ethereal:banana_tree_sapling") + alias("farming_plus:banana_leaves", "ethereal:bananaleaves") + alias("farming_plus:banana", "ethereal:banana") +else + minetest.register_node(":ethereal:banana", { + description = "Banana", + drawtype = "torchlike", + tiles = {"banana_single.png"}, + inventory_image = "banana_single.png", + wield_image = "banana_single.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.2, -0.5, -0.2, 0.2, 0.2, 0.2} + }, + groups = {food_banana = 1, fleshy = 3, dig_immediate = 3, flammable = 2}, + on_use = minetest.item_eat(2), + sounds = default.node_sound_leaves_defaults(), + }) + + minetest.register_node(":ethereal:bananaleaves", { + description = "Banana Leaves", + tiles = {"banana_leaf.png"}, + inventory_image = "banana_leaf.png", + wield_image = "banana_leaf.png", + paramtype = "light", + waving = 1, + groups = {snappy = 3, leafdecay = 3, leaves = 1, flammable = 2}, + sounds = default.node_sound_leaves_defaults(), + }) + + alias("farming_plus:banana_sapling", "default:sapling") + alias("farming_plus:banana_leaves", "ethereal:bananaleaves") + alias("farming_plus:banana", "ethereal:banana") +end + +-- Carrot +alias("farming_plus:carrot_seed", "farming:carrot") +alias("farming_plus:carrot_1", "farming:carrot_1") +alias("farming_plus:carrot_2", "farming:carrot_4") +alias("farming_plus:carrot_3", "farming:carrot_6") +alias("farming_plus:carrot", "farming:carrot_8") +alias("farming_plus:carrot_item", "farming:carrot") + +-- Cocoa +alias("farming_plus:cocoa_sapling", "farming:cocoa_beans") +alias("farming_plus:cocoa_leaves", "default:leaves") +alias("farming_plus:cocoa", "default:apple") +alias("farming_plus:cocoa_bean", "farming:cocoa_beans") + +-- Orange +alias("farming_plus:orange_1", "farming:tomato_1") +alias("farming_plus:orange_2", "farming:tomato_4") +alias("farming_plus:orange_3", "farming:tomato_6") + +if eth then + alias("farming_plus:orange_item", "ethereal:orange") + alias("farming_plus:orange", "ethereal:orange") + alias("farming_plus:orange_seed", "ethereal:orange_tree_sapling") +else + minetest.register_node(":ethereal:orange", { + description = "Orange", + drawtype = "plantlike", + tiles = {"farming_orange.png"}, + inventory_image = "farming_orange.png", + wield_image = "farming_orange.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.2, -0.3, -0.2, 0.2, 0.2, 0.2} + }, + groups = {food_orange = 1, fleshy = 3, dig_immediate = 3, flammable = 2}, + on_use = minetest.item_eat(4), + sounds = default.node_sound_leaves_defaults(), + }) + + alias("farming_plus:orange_item", "ethereal:orange") + alias("farming_plus:orange", "ethereal:orange") + alias("farming_plus:orange_seed", "default:sapling") +end + +-- Potato +alias("farming_plus:potato_item", "farming:potato") +alias("farming_plus:potato_1", "farming:potato_1") +alias("farming_plus:potato_2", "farming:potato_2") +alias("farming_plus:potato", "farming:potato_3") +alias("farming_plus:potato_seed", "farming:potato") + +-- Pumpkin +alias("farming:pumpkin_seed", "farming:pumpkin_slice") +alias("farming:pumpkin_face", "farming:jackolantern") +alias("farming:pumpkin_face_light", "farming:jackolantern_on") +alias("farming:big_pumpkin", "farming:jackolantern") +alias("farming:big_pumpkin_side", "air") +alias("farming:big_pumpkin_top", "air") +alias("farming:big_pumpkin_corner", "air") +alias("farming:scarecrow", "farming:jackolantern") +alias("farming:scarecrow_light", "farming:jackolantern_on") +alias("farming:pumpkin_flour", "farming:pumpkin_dough") + +-- Rhubarb +alias("farming_plus:rhubarb_seed", "farming:rhubarb") +alias("farming_plus:rhubarb_1", "farming:rhubarb_1") +alias("farming_plus:rhubarb_2", "farming:rhubarb_2") +alias("farming_plus:rhubarb", "farming:rhubarb_3") +alias("farming_plus:rhubarb_item", "farming:rhubarb") + +-- Strawberry +if eth then + alias("farming_plus:strawberry_item", "ethereal:strawberry") + alias("farming_plus:strawberry_seed", "ethereal:strawberry") + alias("farming_plus:strawberry_1", "ethereal:strawberry_1") + alias("farming_plus:strawberry_2", "ethereal:strawberry_3") + alias("farming_plus:strawberry_3", "ethereal:strawberry_5") + alias("farming_plus:strawberry", "ethereal:strawberry_7") +else + minetest.register_craftitem(":ethereal:strawberry", { + description = "Strawberry", + inventory_image = "strawberry.png", + wield_image = "strawberry.png", + groups = {food_strawberry = 1, flammable = 2}, + on_use = minetest.item_eat(1), + }) + + alias("farming_plus:strawberry_item", "ethereal:strawberry") + alias("farming_plus:strawberry_seed", "ethereal:strawberry") + alias("farming_plus:strawberry_1", "farming:raspberry_1") + alias("farming_plus:strawberry_2", "farming:raspberry_2") + alias("farming_plus:strawberry_3", "farming:raspberry_3") + alias("farming_plus:strawberry", "farming:raspberry_4") +end + +-- Tomato +alias("farming_plus:tomato_seed", "farming:tomato") +alias("farming_plus:tomato_item", "farming:tomato") +alias("farming_plus:tomato_1", "farming:tomato_2") +alias("farming_plus:tomato_2", "farming:tomato_4") +alias("farming_plus:tomato_3", "farming:tomato_6") +alias("farming_plus:tomato", "farming:tomato_8") + +-- Weed +alias("farming:weed", "default:grass_2") diff --git a/mods/farming/crops/barley.lua b/mods/farming/crops/barley.lua new file mode 100644 index 0000000..d896031 --- /dev/null +++ b/mods/farming/crops/barley.lua @@ -0,0 +1,122 @@ + +local S = farming.intllib + +-- barley seeds +minetest.register_node("farming:seed_barley", { + description = S("Barley Seed"), + tiles = {"farming_barley_seed.png"}, + inventory_image = "farming_barley_seed.png", + wield_image = "farming_barley_seed.png", + drawtype = "signlike", + groups = {seed = 1, snappy = 3, attached_node = 1}, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + sunlight_propagates = true, + selection_box = farming.select, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:barley_1") + end, +}) + +-- harvested barley +minetest.register_craftitem("farming:barley", { + description = S("Barley"), + inventory_image = "farming_barley.png", + groups = {food_barley = 1, flammable = 2}, +}) + +-- flour +minetest.register_craft({ + type = "shapeless", + output = "farming:flour", + recipe = { + "farming:barley", "farming:barley", "farming:barley", + "farming:barley", "farming:mortar_pestle" + }, + replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}, +}) + +-- barley definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_barley_1.png"}, + paramtype = "light", + paramtype2 = "meshoptions", + place_param2 = 3, + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:barley_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_barley_2.png"} +minetest.register_node("farming:barley_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_barley_3.png"} +minetest.register_node("farming:barley_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_barley_4.png"} +minetest.register_node("farming:barley_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_barley_5.png"} +crop_def.drop = { + items = { + {items = {"farming:barley"}, rarity = 2}, + {items = {"farming:seed_barley"}, rarity = 2}, + } +} +minetest.register_node("farming:barley_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_barley_6.png"} +crop_def.drop = { + items = { + {items = {"farming:barley"}, rarity = 2}, + {items = {"farming:seed_barley"}, rarity = 1}, + } +} +minetest.register_node("farming:barley_6", table.copy(crop_def)) + +-- stage 7 (final) +crop_def.tiles = {"farming_barley_7.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:barley"}, rarity = 1}, + {items = {"farming:barley"}, rarity = 3}, + {items = {"farming:seed_barley"}, rarity = 1}, + {items = {"farming:seed_barley"}, rarity = 3}, + } +} +minetest.register_node("farming:barley_7", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:barley"] = { + crop = "farming:barley", + seed = "farming:seed_barley", + minlight = 13, + maxlight = 15, + steps = 7 +} + +-- Fuel + +minetest.register_craft({ + type = "fuel", + recipe = "farming:barley", + burntime = 1, +}) diff --git a/mods/farming/crops/beans.lua b/mods/farming/crops/beans.lua new file mode 100644 index 0000000..c35b2cf --- /dev/null +++ b/mods/farming/crops/beans.lua @@ -0,0 +1,258 @@ +--[[ + All textures by + (C) Auke Kok + CC-BY-SA-3.0 +]] + +local S = farming.intllib + +-- place beans +local function place_beans(itemstack, placer, pointed_thing, plantname) + + local pt = pointed_thing + + -- check if pointing at a node + if not pt or pt.type ~= "node" then + + return + end + + local under = minetest.get_node(pt.under) + + -- return if any of the nodes are not registered + if not minetest.registered_nodes[under.name] then + return + end + + -- am I right-clicking on something that has a custom on_place set? + -- thanks to Krock for helping with this issue :) + local def = minetest.registered_nodes[under.name] + if placer and itemstack and def and def.on_rightclick then + return def.on_rightclick(pt.under, under, placer, itemstack) + end + + -- is player planting crop? + local name = placer and placer:get_player_name() or "" + + -- check for protection + if minetest.is_protected(pt.under, name) then + return + end + + -- check if pointing at bean pole + if under.name ~= "farming:beanpole" then + return + end + + -- add the node and remove 1 item from the itemstack + minetest.set_node(pt.under, {name = plantname}) + + minetest.sound_play("default_place_node", {pos = pt.under, gain = 1.0}) + + if placer or not farming.is_creative(placer:get_player_name()) then + + itemstack:take_item() + + -- check for refill + if itemstack:get_count() == 0 then + + minetest.after(0.20, + farming.refill_plant, + placer, + "farming:beans", + placer:get_wield_index() + ) + end + end + + return itemstack +end + +-- beans +minetest.register_craftitem("farming:beans", { + description = S("Green Beans"), + inventory_image = "farming_beans.png", + groups = {seed = 2, food_beans = 1, flammable = 2}, + on_use = minetest.item_eat(1), + + on_place = function(itemstack, placer, pointed_thing) + return place_beans(itemstack, placer, pointed_thing, "farming:beanpole_1") + end, +}) + +-- beans can be used for green dye +minetest.register_craft({ + output = "dye:green", + recipe = { + {"farming:beans"}, + } +}) + +-- beanpole +minetest.register_node("farming:beanpole", { + description = S("Bean Pole (place on soil before planting beans)"), + drawtype = "plantlike", + tiles = {"farming_beanpole.png"}, + inventory_image = "farming_beanpole.png", + visual_scale = 1.90, -- 1.45, + paramtype = "light", + walkable = false, + buildable_to = true, + sunlight_propagates = true, + drop = "farming:beanpole", + selection_box = farming.select, + groups = {snappy = 3, flammable = 2, attached_node = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_place = function(itemstack, placer, pointed_thing) + + local pt = pointed_thing + + -- check if pointing at a node + if not pt or pt.type ~= "node" then + return + end + + local under = minetest.get_node(pt.under) + + -- return if any of the nodes are not registered + if not minetest.registered_nodes[under.name] then + return + end + + -- am I right-clicking on something that has a custom on_place set? + -- thanks to Krock for helping with this issue :) + local def = minetest.registered_nodes[under.name] + if def and def.on_rightclick then + return def.on_rightclick(pt.under, under, placer, itemstack) + end + + if minetest.is_protected(pt.above, placer:get_player_name()) then + return + end + + local nodename = under.name + + if minetest.get_item_group(nodename, "soil") < 2 then + return + end + + local top = { + x = pointed_thing.above.x, + y = pointed_thing.above.y + 1, + z = pointed_thing.above.z + } + + nodename = minetest.get_node(top).name + + if nodename ~= "air" then + return + end + + minetest.set_node(pointed_thing.above, {name = "farming:beanpole"}) + + if not farming.is_creative(placer:get_player_name()) then + itemstack:take_item() + end + + return itemstack + end +}) + +minetest.register_craft({ + output = "farming:beanpole", + recipe = { + {"", "", ""}, + {"default:stick", "", "default:stick"}, + {"default:stick", "", "default:stick"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:beanpole", + burntime = 10, +}) + +-- green bean definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_beanpole_1.png"}, + visual_scale = 1.90, -- 1.45, + paramtype = "light", + walkable = false, + buildable_to = true, + sunlight_propagates = true, + drop = { + items = { + {items = {"farming:beanpole"}, rarity = 1}, + } + }, + selection_box = farming.select, + groups = { + snappy = 3, flammable = 3, not_in_creative_inventory = 1, + attached_node = 1, growing = 1, plant = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:beanpole_1", table.copy(crop_def)) + +-- stage2 +crop_def.tiles = {"farming_beanpole_2.png"} +minetest.register_node("farming:beanpole_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_beanpole_3.png"} +minetest.register_node("farming:beanpole_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_beanpole_4.png"} +minetest.register_node("farming:beanpole_4", table.copy(crop_def)) + +-- stage 5 (final) +crop_def.tiles = {"farming_beanpole_5.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:beanpole"}, rarity = 1}, + {items = {"farming:beans 3"}, rarity = 1}, + {items = {"farming:beans 2"}, rarity = 2}, + {items = {"farming:beans 2"}, rarity = 3}, + } +} +minetest.register_node("farming:beanpole_5", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:beans"] = { + crop = "farming:beanpole", + seed = "farming:beans", + minlight = 13, + maxlight = 15, + steps = 5 +} + +-- wild green bean bush (this is what you find on the map) +minetest.register_node("farming:beanbush", { + drawtype = "plantlike", + tiles = {"farming_beanbush.png"}, + paramtype = "light", + waving = 1, + walkable = false, + buildable_to = true, + sunlight_propagates = true, + drop = { + items = { + {items = {"farming:beans 1"}, rarity = 1}, + {items = {"farming:beans 1"}, rarity = 2}, + {items = {"farming:beans 1"}, rarity = 3}, + } + }, + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory=1 + }, + sounds = default.node_sound_leaves_defaults(), +}) diff --git a/mods/farming/crops/beetroot.lua b/mods/farming/crops/beetroot.lua new file mode 100644 index 0000000..0a20d88 --- /dev/null +++ b/mods/farming/crops/beetroot.lua @@ -0,0 +1,94 @@ + +local S = farming.intllib + +-- beetroot +minetest.register_craftitem("farming:beetroot", { + description = S("Beetroot"), + inventory_image = "farming_beetroot.png", + groups = {seed = 2, food_beetroot = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:beetroot_1") + end, + on_use = minetest.item_eat(1), +}) + +-- beetroot soup +minetest.register_craftitem("farming:beetroot_soup", { + description = S("Beetroot Soup"), + inventory_image = "farming_beetroot_soup.png", + groups = {flammable = 2}, + on_use = minetest.item_eat(6, "farming:bowl"), +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:beetroot_soup", + recipe = { + "group:food_beetroot", "group:food_beetroot", + "group:food_beetroot", "group:food_beetroot", + "group:food_beetroot", "group:food_beetroot","group:food_bowl" + } +}) + +-- red dye +minetest.register_craft({ + type = "shapeless", + output = "dye:red", + recipe = {"group:food_beetroot"}, +}) + +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_beetroot_1.png"}, + paramtype = "light", +-- paramtype2 = "meshoptions", +-- place_param2 = 3, + sunlight_propagates = true, + waving = 1, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:beetroot_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_beetroot_2.png"} +minetest.register_node("farming:beetroot_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_beetroot_3.png"} +minetest.register_node("farming:beetroot_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_beetroot_4.png"} +minetest.register_node("farming:beetroot_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_beetroot_5.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + max_items = 4, items = { + {items = {"farming:beetroot"}, rarity = 1}, + {items = {"farming:beetroot"}, rarity = 2}, + {items = {"farming:beetroot"}, rarity = 3}, + {items = {"farming:beetroot"}, rarity = 4}, + } +} +minetest.register_node("farming:beetroot_5", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:beetroot"] = { + crop = "farming:beetroot", + seed = "farming:beetroot", + minlight = 13, + maxlight = 15, + steps = 5 +} diff --git a/mods/farming/crops/blueberry.lua b/mods/farming/crops/blueberry.lua new file mode 100644 index 0000000..fec0c12 --- /dev/null +++ b/mods/farming/crops/blueberry.lua @@ -0,0 +1,96 @@ + +local S = farming.intllib + +-- blueberries +minetest.register_craftitem("farming:blueberries", { + description = S("Blueberries"), + inventory_image = "farming_blueberries.png", + groups = {seed = 2, food_blueberries = 1, food_blueberry = 1, + food_berry = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:blueberry_1") + end, + on_use = minetest.item_eat(1), +}) + +-- blueberry muffin (thanks to sosogirl123 @ deviantart.com for muffin image) + +minetest.register_craftitem("farming:muffin_blueberry", { + description = S("Blueberry Muffin"), + inventory_image = "farming_blueberry_muffin.png", + on_use = minetest.item_eat(2), +}) + +minetest.register_craft({ + output = "farming:muffin_blueberry 2", + recipe = { + {"group:food_blueberries", "group:food_bread", "group:food_blueberries"}, + } +}) + +-- Blueberry Pie + +minetest.register_craftitem("farming:blueberry_pie", { + description = S("Blueberry Pie"), + inventory_image = "farming_blueberry_pie.png", + on_use = minetest.item_eat(6), +}) + +minetest.register_craft({ + output = "farming:blueberry_pie", + type = "shapeless", + recipe = { + "group:food_flour", "group:food_sugar", + "group:food_blueberries", "group:food_baking_tray" + }, + replacements = {{"group:food_baking_tray", "farming:baking_tray"}} +}) + +-- blueberry definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_blueberry_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:blueberry_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_blueberry_2.png"} +minetest.register_node("farming:blueberry_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_blueberry_3.png"} +minetest.register_node("farming:blueberry_3", table.copy(crop_def)) + +-- stage 4 (final) +crop_def.tiles = {"farming_blueberry_4.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:blueberries 2"}, rarity = 1}, + {items = {"farming:blueberries"}, rarity = 2}, + {items = {"farming:blueberries"}, rarity = 3}, + } +} +minetest.register_node("farming:blueberry_4", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:blueberries"] = { + crop = "farming:blueberry", + seed = "farming:blueberries", + minlight = 13, + maxlight = 15, + steps = 4 +} diff --git a/mods/farming/crops/carrot.lua b/mods/farming/crops/carrot.lua new file mode 100644 index 0000000..00ecb14 --- /dev/null +++ b/mods/farming/crops/carrot.lua @@ -0,0 +1,105 @@ + +--[[ + Original textures from PixelBox texture pack + https://forum.minetest.net/viewtopic.php?id=4990 +]] + +local S = farming.intllib + +-- carrot +minetest.register_craftitem("farming:carrot", { + description = S("Carrot"), + inventory_image = "farming_carrot.png", + groups = {seed = 2, food_carrot = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:carrot_1") + end, + on_use = minetest.item_eat(4), +}) + +-- golden carrot +minetest.register_craftitem("farming:carrot_gold", { + description = S("Golden Carrot"), + inventory_image = "farming_carrot_gold.png", + on_use = minetest.item_eat(6), +}) + +minetest.register_craft({ + output = "farming:carrot_gold", + recipe = { + {"", "default:gold_lump", ""}, + {"default:gold_lump", "group:food_carrot", "default:gold_lump"}, + {"", "default:gold_lump", ""}, + } +}) + +-- carrot definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_carrot_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + + +-- stage 1 +minetest.register_node("farming:carrot_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_carrot_2.png"} +minetest.register_node("farming:carrot_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_carrot_3.png"} +minetest.register_node("farming:carrot_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_carrot_4.png"} +minetest.register_node("farming:carrot_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_carrot_5.png"} +minetest.register_node("farming:carrot_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_carrot_6.png"} +minetest.register_node("farming:carrot_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_carrot_7.png"} +crop_def.drop = { + items = { + {items = {"farming:carrot"}, rarity = 1}, + {items = {"farming:carrot 2"}, rarity = 3}, + } +} +minetest.register_node("farming:carrot_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_carrot_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:carrot 2"}, rarity = 1}, + {items = {"farming:carrot 3"}, rarity = 2}, + } +} +minetest.register_node("farming:carrot_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:carrot"] = { + crop = "farming:carrot", + seed = "farming:carrot", + minlight = 13, + maxlight = 15, + steps = 8 +} diff --git a/mods/farming/crops/chili.lua b/mods/farming/crops/chili.lua new file mode 100644 index 0000000..b45c159 --- /dev/null +++ b/mods/farming/crops/chili.lua @@ -0,0 +1,101 @@ + +local S = farming.intllib + +-- chili pepper +minetest.register_craftitem("farming:chili_pepper", { + description = S("Chili Pepper"), + inventory_image = "farming_chili_pepper.png", + groups = {seed = 2, food_chili_pepper = 1, flammable = 4}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:chili_1") + end, + on_use = minetest.item_eat(2), +}) + +-- bowl of chili +minetest.register_craftitem("farming:chili_bowl", { + description = S("Bowl of Chili"), + inventory_image = "farming_chili_bowl.png", + on_use = minetest.item_eat(8, "farming:bowl"), +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:chili_bowl", + recipe = { + "group:food_chili_pepper", "group:food_barley", "group:food_pepper", + "group:food_tomato", "group:food_onion", "group:food_bowl" + }, +}) + +-- chili can be used for red dye +minetest.register_craft({ + output = "dye:red", + recipe = { + {"farming:chili_pepper"}, + } +}) + +-- chili definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_chili_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 4, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:chili_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_chili_2.png"} +minetest.register_node("farming:chili_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_chili_3.png"} +minetest.register_node("farming:chili_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_chili_4.png"} +minetest.register_node("farming:chili_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_chili_5.png"} +minetest.register_node("farming:chili_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_chili_6.png"} +minetest.register_node("farming:chili_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_chili_7.png"} +minetest.register_node("farming:chili_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_chili_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:chili_pepper 3"}, rarity = 1}, + {items = {"farming:chili_pepper 2"}, rarity = 2}, + } +} +minetest.register_node("farming:chili_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:chili_pepper"] = { + crop = "farming:chili", + seed = "farming:chili_pepper", + minlight = 13, + maxlight = 15, + steps = 8 +} diff --git a/mods/farming/crops/cocoa.lua b/mods/farming/crops/cocoa.lua new file mode 100644 index 0000000..243814b --- /dev/null +++ b/mods/farming/crops/cocoa.lua @@ -0,0 +1,244 @@ + +local S = farming.intllib + +-- place cocoa +local function place_cocoa(itemstack, placer, pointed_thing, plantname) + + local pt = pointed_thing + + -- check if pointing at a node + if not pt or pt.type ~= "node" then + return + end + + local under = minetest.get_node(pt.under) + + -- return if any of the nodes are not registered + if not minetest.registered_nodes[under.name] then + return + end + + -- am I right-clicking on something that has a custom on_place set? + -- thanks to Krock for helping with this issue :) + local def = minetest.registered_nodes[under.name] + if placer and itemstack and def and def.on_rightclick then + return def.on_rightclick(pt.under, under, placer, itemstack) + end + + -- check if pointing at jungletree + if under.name ~= "default:jungletree" + or minetest.get_node(pt.above).name ~= "air" then + return + end + + -- is player planting crop? + local name = placer and placer:get_player_name() or "" + + -- check for protection + if minetest.is_protected(pt.above, name) then + return + end + + -- add the node and remove 1 item from the itemstack + minetest.set_node(pt.above, {name = plantname}) + + minetest.sound_play("default_place_node", {pos = pt.above, gain = 1.0}) + + if placer and not farming.is_creative(placer:get_player_name()) then + + itemstack:take_item() + + -- check for refill + if itemstack:get_count() == 0 then + + minetest.after(0.20, + farming.refill_plant, + placer, + "farming:cocoa_beans", + placer:get_wield_index() + ) + end + end + + return itemstack +end + +-- cocoa beans +minetest.register_craftitem("farming:cocoa_beans", { + description = S("Cocoa Beans"), + inventory_image = "farming_cocoa_beans.png", + groups = {seed = 2, food_cocoa = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return place_cocoa(itemstack, placer, pointed_thing, "farming:cocoa_1") + end, +}) + +minetest.register_craft( { + output = "dye:brown 2", + recipe = { + { "farming:cocoa_beans" }, + } +}) + +-- chocolate cookie +minetest.register_craftitem("farming:cookie", { + description = S("Cookie"), + inventory_image = "farming_cookie.png", + on_use = minetest.item_eat(2), +}) + +minetest.register_craft( { + output = "farming:cookie 8", + recipe = { + {"group:food_wheat", "group:food_cocoa", "group:food_wheat" }, + } +}) + +-- bar of dark chocolate (thanks to Ice Pandora for her deviantart.com chocolate tutorial) +minetest.register_craftitem("farming:chocolate_dark", { + description = S("Bar of Dark Chocolate"), + inventory_image = "farming_chocolate_dark.png", + on_use = minetest.item_eat(3), +}) + +minetest.register_craft( { + output = "farming:chocolate_dark", + recipe = { + {"group:food_cocoa", "group:food_cocoa", "group:food_cocoa"}, + } +}) + +-- chocolate block +minetest.register_node("farming:chocolate_block", { + description = S("Chocolate Block"), + tiles = {"farming_chocolate_block.png"}, + is_ground_content = false, + groups = {cracky = 2, oddly_breakable_by_hand = 2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "farming:chocolate_block", + recipe = { + {"farming:chocolate_dark", "farming:chocolate_dark", "farming:chocolate_dark"}, + {"farming:chocolate_dark", "farming:chocolate_dark", "farming:chocolate_dark"}, + {"farming:chocolate_dark", "farming:chocolate_dark", "farming:chocolate_dark"}, + } +}) + +minetest.register_craft({ + output = "farming:chocolate_dark 9", + recipe = { + {"farming:chocolate_block"}, + } +}) + +-- cocoa definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_cocoa_1.png"}, + paramtype = "light", + walkable = false, + drop = { + items = { + {items = {"farming:cocoa_beans 1"}, rarity = 2}, + } + }, + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, 0.5, 0.3} + }, + groups = { + snappy = 3, flammable = 2, plant = 1, growing = 1, + not_in_creative_inventory=1, leafdecay = 1, leafdecay_drop = 1 + }, + sounds = default.node_sound_leaves_defaults(), + growth_check = function(pos, node_name) + if minetest.find_node_near(pos, 1, {"default:jungletree"}) then + return false + end + return true + end, +} + +-- stage 1 +minetest.register_node("farming:cocoa_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_cocoa_2.png"} +minetest.register_node("farming:cocoa_2", table.copy(crop_def)) + +-- stage3 +crop_def.tiles = {"farming_cocoa_3.png"} +crop_def.drop = { + items = { + {items = {"farming:cocoa_beans 1"}, rarity = 1}, + } +} +minetest.register_node("farming:cocoa_3", table.copy(crop_def)) + +-- stage 4 (final) +crop_def.tiles = {"farming_cocoa_4.png"} +crop_def.groups.growing = 0 +crop_def.growth_check = nil +crop_def.drop = { + items = { + {items = {"farming:cocoa_beans 2"}, rarity = 1}, + {items = {"farming:cocoa_beans 1"}, rarity = 2}, + {items = {"farming:cocoa_beans 1"}, rarity = 4}, + } +} +minetest.register_node("farming:cocoa_4", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:cocoa_beans"] = { + crop = "farming:cocoa", + seed = "farming:cocoa_beans", + minlight = 13, + maxlight = 15, + steps = 4 +} + +-- add random cocoa pods to jungle tree's +minetest.register_on_generated(function(minp, maxp) + + if maxp.y < 0 then + return + end + + local pos, dir + local cocoa = minetest.find_nodes_in_area(minp, maxp, "default:jungletree") + + for n = 1, #cocoa do + + pos = cocoa[n] + + if minetest.find_node_near(pos, 1, + {"default:jungleleaves", "moretrees:jungletree_leaves_green"}) then + + dir = math.random(1, 80) + + if dir == 1 then + pos.x = pos.x + 1 + elseif dir == 2 then + pos.x = pos.x - 1 + elseif dir == 3 then + pos.z = pos.z + 1 + elseif dir == 4 then + pos.z = pos.z -1 + end + + if dir < 5 + and minetest.get_node(pos).name == "air" + and minetest.get_node_light(pos) > 12 then + + --print ("Cocoa Pod added at " .. minetest.pos_to_string(pos)) + + minetest.swap_node(pos, { + name = "farming:cocoa_" .. tostring(math.random(1, 4)) + }) + end + + end + end +end) diff --git a/mods/farming/crops/coffee.lua b/mods/farming/crops/coffee.lua new file mode 100644 index 0000000..2e2ed73 --- /dev/null +++ b/mods/farming/crops/coffee.lua @@ -0,0 +1,97 @@ + +local S = farming.intllib + +-- coffee +minetest.register_craftitem("farming:coffee_beans", { + description = S("Coffee Beans"), + inventory_image = "farming_coffee_beans.png", + groups = {seed = 2, food_coffee = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:coffee_1") + end, +}) + +-- cold cup of coffee +minetest.register_node("farming:coffee_cup", { + description = S("Cup of Coffee"), + drawtype = "torchlike", --"plantlike", + tiles = {"farming_coffee_cup.png"}, + inventory_image = "farming_coffee_cup.png", + wield_image = "farming_coffee_cup.png", + paramtype = "light", + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.25, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + on_use = minetest.item_eat(2, "vessels:drinking_glass"), + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_alias("farming:coffee_cup_hot", "farming:coffee_cup") +minetest.register_alias("farming:drinking_cup", "vessels:drinking_glass") + +minetest.register_craft( { + output = "farming:coffee_cup", + type = "shapeless", + recipe = {"vessels:drinking_glass", "group:food_coffee", + "bucket:bucket_water", "group:food_saucepan"}, + replacements = { + {"bucket:bucket_water", "bucket:bucket_empty"}, + {"group:food_saucepan", "farming:saucepan"}, + } +}) + +-- coffee definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_coffee_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:coffee_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_coffee_2.png"} +minetest.register_node("farming:coffee_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_coffee_3.png"} +minetest.register_node("farming:coffee_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_coffee_4.png"} +minetest.register_node("farming:coffee_4", table.copy(crop_def)) + +-- stage 5 (final) +crop_def.tiles = {"farming_coffee_5.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:coffee_beans 2"}, rarity = 1}, + {items = {"farming:coffee_beans 2"}, rarity = 2}, + {items = {"farming:coffee_beans 2"}, rarity = 3}, + } +} +minetest.register_node("farming:coffee_5", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:coffee"] = { + crop = "farming:coffee", + seed = "farming:coffee_beans", + minlight = 13, + maxlight = 15, + steps = 5 +} diff --git a/mods/farming/crops/corn.lua b/mods/farming/crops/corn.lua new file mode 100644 index 0000000..eef547a --- /dev/null +++ b/mods/farming/crops/corn.lua @@ -0,0 +1,158 @@ + +--[[ + Original textures from GeMinecraft + http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/wip-mods/1440575-1-2-5-generation-minecraft-beta-1-2-farming-and +]] + +local S = farming.intllib + +-- corn +minetest.register_craftitem("farming:corn", { + description = S("Corn"), + inventory_image = "farming_corn.png", + groups = {seed = 2, food_corn = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:corn_1") + end, + on_use = minetest.item_eat(3), +}) + +-- corn on the cob (texture by TenPlus1) +minetest.register_craftitem("farming:corn_cob", { + description = S("Corn on the Cob"), + inventory_image = "farming_corn_cob.png", + groups = {food_corn_cooked = 1, flammable = 2}, + on_use = minetest.item_eat(5), +}) + +minetest.register_craft({ + type = "cooking", + cooktime = 10, + output = "farming:corn_cob", + recipe = "group:food_corn" +}) + +-- cornstarch +minetest.register_craftitem("farming:cornstarch", { + description = S("Cornstarch"), + inventory_image = "farming_cornstarch.png", + groups = {food_cornstarch = 1, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:cornstarch", + recipe = { + {"group:food_mortar_pestle", "group:food_corn_cooked", "group:food_baking_tray"}, + {"", "group:food_bowl", ""}, + }, + replacements = { + {"group:food_mortar_pestle", "farming:mortar_pestle"}, + {"group:food_baking_tray", "farming:baking_tray"}, + } +}) + +-- ethanol (thanks to JKMurray for this idea) +minetest.register_node("farming:bottle_ethanol", { + description = S("Bottle of Ethanol"), + drawtype = "plantlike", + tiles = {"farming_bottle_ethanol.png"}, + inventory_image = "farming_bottle_ethanol.png", + wield_image = "farming_bottle_ethanol.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_craft( { + output = "farming:bottle_ethanol", + recipe = { + { "vessels:glass_bottle", "group:food_corn", "group:food_corn"}, + { "group:food_corn", "group:food_corn", "group:food_corn"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:bottle_ethanol", + burntime = 80, --240, + replacements = {{ "farming:bottle_ethanol", "vessels:glass_bottle"}} +}) + +-- corn definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_corn_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:corn_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_corn_2.png"} +minetest.register_node("farming:corn_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_corn_3.png"} +minetest.register_node("farming:corn_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_corn_4.png"} +minetest.register_node("farming:corn_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_corn_5.png"} +minetest.register_node("farming:corn_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_corn_6.png"} +crop_def.visual_scale = 1.9 -- 1.45 +minetest.register_node("farming:corn_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_corn_7.png"} +crop_def.drop = { + items = { + {items = {"farming:corn"}, rarity = 1}, + {items = {"farming:corn"}, rarity = 2}, + {items = {"farming:corn"}, rarity = 3}, + } +} +minetest.register_node("farming:corn_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_corn_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:corn 2"}, rarity = 1}, + {items = {"farming:corn 2"}, rarity = 2}, + {items = {"farming:corn 2"}, rarity = 2}, + } +} +minetest.register_node("farming:corn_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:corn"] = { + crop = "farming:corn", + seed = "farming:corn", + minlight = 13, + maxlight = 15, + steps = 8 +} diff --git a/mods/farming/crops/cotton.lua b/mods/farming/crops/cotton.lua new file mode 100644 index 0000000..741a437 --- /dev/null +++ b/mods/farming/crops/cotton.lua @@ -0,0 +1,142 @@ + +local S = farming.intllib + +-- cotton seeds +minetest.register_node("farming:seed_cotton", { + description = S("Cotton Seed"), + tiles = {"farming_cotton_seed.png"}, + inventory_image = "farming_cotton_seed.png", + wield_image = "farming_cotton_seed.png", + drawtype = "signlike", + groups = {seed = 1, snappy = 3, attached_node = 1, flammable = 4}, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + sunlight_propagates = true, + selection_box = farming.select, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:cotton_1") + end, +}) + +-- cotton / string + +minetest.register_craftitem("farming:cotton", { + description = S("Cotton"), + inventory_image = "farming_cotton.png", + groups = {flammable = 4}, +}) + +minetest.register_craftitem("farming:string", { + description = S("String"), + inventory_image = "farming_string.png", + groups = {flammable = 2}, +}) + +-- can be used as fuel +minetest.register_craft({ + type = "fuel", + recipe = "farming:string", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:cotton", + burntime = 1, +}) + +-- cotton definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_cotton_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 4, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:cotton_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_cotton_2.png"} +minetest.register_node("farming:cotton_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_cotton_3.png"} +minetest.register_node("farming:cotton_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_cotton_4.png"} +minetest.register_node("farming:cotton_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_cotton_5.png"} +crop_def.drop = { + items = { + {items = {"farming:seed_cotton"}, rarity = 1}, + } +} +minetest.register_node("farming:cotton_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_cotton_6.png"} +crop_def.drop = { + items = { + {items = {"farming:cotton"}, rarity = 1}, + {items = {"farming:cotton"}, rarity = 2}, + } +} +minetest.register_node("farming:cotton_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_cotton_7.png"} +crop_def.drop = { + items = { + {items = {"farming:cotton"}, rarity = 1}, + {items = {"farming:cotton"}, rarity = 2}, + {items = {"farming:seed_cotton"}, rarity = 1}, + {items = {"farming:seed_cotton"}, rarity = 2}, + } +} +minetest.register_node("farming:cotton_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_cotton_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:cotton"}, rarity = 1}, + {items = {"farming:cotton"}, rarity = 2}, + {items = {"farming:cotton"}, rarity = 3}, + {items = {"farming:seed_cotton"}, rarity = 1}, + {items = {"farming:seed_cotton"}, rarity = 2}, + {items = {"farming:seed_cotton"}, rarity = 3}, + } +} +minetest.register_node("farming:cotton_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:cotton"] = { + crop = "farming:cotton", + seed = "farming:seed_cotton", + minlight = 13, + maxlight = 15, + steps = 8 +} + +--[[ Cotton (example, is already registered in cotton.lua) +farming.register_plant("farming:cotton", { + description = "Cotton seed", + inventory_image = "farming_cotton_seed.png", + groups = {flammable = 2}, + steps = 8, +})]] diff --git a/mods/farming/crops/cucumber.lua b/mods/farming/crops/cucumber.lua new file mode 100644 index 0000000..8bd679a --- /dev/null +++ b/mods/farming/crops/cucumber.lua @@ -0,0 +1,65 @@ + +--[[ + Original textures from DocFarming mod + https://forum.minetest.net/viewtopic.php?id=3948 +]] + +local S = farming.intllib + +-- cucumber +minetest.register_craftitem("farming:cucumber", { + description = S("Cucumber"), + inventory_image = "farming_cucumber.png", + groups = {seed = 2, food_cucumber = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:cucumber_1") + end, + on_use = minetest.item_eat(4), +}) + +-- cucumber definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_cucumber_1.png"}, + paramtype = "light", + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:cucumber_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_cucumber_2.png"} +minetest.register_node("farming:cucumber_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_cucumber_3.png"} +minetest.register_node("farming:cucumber_3", table.copy(crop_def)) + +-- stage 4 (final) +crop_def.tiles = {"farming_cucumber_4.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:cucumber 2"}, rarity = 1}, + {items = {"farming:cucumber 2"}, rarity = 2}, + } +} +minetest.register_node("farming:cucumber_4", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:cucumber"] = { + crop = "farming:cucumber", + seed = "farming:cucumber", + minlight = 13, + maxlight = 15, + steps = 4 +} diff --git a/mods/farming/crops/garlic.lua b/mods/farming/crops/garlic.lua new file mode 100644 index 0000000..ee841e5 --- /dev/null +++ b/mods/farming/crops/garlic.lua @@ -0,0 +1,137 @@ + +--[[ + Original textures from Crops Plus mod + Copyright (C) 2018 Grizzly Adam + https://forum.minetest.net/viewtopic.php?f=9&t=19488 +]] + +local S = farming.intllib + +-- potato +minetest.register_craftitem("farming:garlic_clove", { + description = S("Garlic clove"), + inventory_image = "crops_garlic_clove.png", + groups = {seed = 2, food_garlic_clove = 1, flammable = 3}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:garlic_1") + end, +}) + +-- garlic bulb +minetest.register_craftitem("farming:garlic", { + description = S("Garlic"), + inventory_image = "crops_garlic.png", + on_use = minetest.item_eat(1), + groups = {food_garlic = 1, flammable = 3}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:garlic_clove 8", + recipe = { "farming:garlic" } +}) + +minetest.register_craft({ + output = "farming:garlic", + recipe = { + {"farming:garlic_clove", "farming:garlic_clove", "farming:garlic_clove"}, + {"farming:garlic_clove", "", "farming:garlic_clove"}, + {"farming:garlic_clove", "farming:garlic_clove", "farming:garlic_clove"} + } +}) + +-- garlic braid +minetest.register_node("farming:garlic_braid", { + description = S("Garlic Braid"), + inventory_image = "crops_garlic_braid.png", + wield_image = "crops_garlic_braid.png", + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + tiles = { + "crops_garlic_braid_side.png","crops_garlic_braid.png", + "crops_garlic_braid_side.png^[transformFx","crops_garlic_braid_side.png", + "crops_garlic_braid.png","crops_garlic_braid.png" + }, + groups = {vessel = 1, dig_immediate = 3, flammable = 3}, + sounds = default.node_sound_leaves_defaults(), + node_box = { + type = "fixed", + fixed = { + {-0.13, -0.45, 0.5, 0.13, 0.45, 0.24}, + }, + } +}) + +minetest.register_craft({ + output = "farming:garlic_braid", + recipe = { + {"farming:garlic", "farming:garlic", "farming:garlic"}, + {"farming:garlic", "farming:garlic", "farming:garlic"}, + {"farming:garlic", "farming:garlic", "farming:garlic"} + } +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:garlic 9", + recipe = { "farming:garlic_braid" } +}) + +-- crop definition +local crop_def = { + drawtype = "plantlike", + tiles = {"crops_garlic_plant_1.png"}, + paramtype = "light", + paramtype2 = "meshoptions", + place_param2 = 3, + sunlight_propagates = true, + waving = 1, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 3, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:garlic_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"crops_garlic_plant_2.png"} +minetest.register_node("farming:garlic_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"crops_garlic_plant_3.png"} +minetest.register_node("farming:garlic_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"crops_garlic_plant_4.png"} +minetest.register_node("farming:garlic_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"crops_garlic_plant_5.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + max_items = 5, items = { + {items = {"farming:garlic"}, rarity = 1}, + {items = {"farming:garlic"}, rarity = 1}, + {items = {"farming:garlic"}, rarity = 1}, + {items = {"farming:garlic"}, rarity = 2}, + {items = {"farming:garlic"}, rarity = 5}, + } +} +minetest.register_node("farming:garlic_5", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:garlic"] = { + crop = "farming:garlic", + seed = "farming:garlic_clove", + minlight = 13, + maxlight = 15, + steps = 5 +} diff --git a/mods/farming/crops/grapes.lua b/mods/farming/crops/grapes.lua new file mode 100644 index 0000000..cc9d8aa --- /dev/null +++ b/mods/farming/crops/grapes.lua @@ -0,0 +1,265 @@ + +local S = farming.intllib + +-- place trellis +local function place_grapes(itemstack, placer, pointed_thing, plantname) + + local pt = pointed_thing + + -- check if pointing at a node + if not pt or pt.type ~= "node" then + + return + end + + local under = minetest.get_node(pt.under) + + -- return if any of the nodes are not registered + if not minetest.registered_nodes[under.name] then + return + end + + -- am I right-clicking on something that has a custom on_place set? + -- thanks to Krock for helping with this issue :) + local def = minetest.registered_nodes[under.name] + if placer and itemstack and def and def.on_rightclick then + return def.on_rightclick(pt.under, under, placer, itemstack) + end + + -- is player planting seed? + local name = placer and placer:get_player_name() or "" + + -- check for protection + if minetest.is_protected(pt.under, name) then + return + end + + -- check if pointing at trellis + if under.name ~= "farming:trellis" then + return + end + + -- add the node and remove 1 item from the itemstack + minetest.set_node(pt.under, {name = plantname}) + + minetest.sound_play("default_place_node", {pos = pt.under, gain = 1.0}) + + if placer and not farming.is_creative(placer:get_player_name()) then + + itemstack:take_item() + + -- check for refill + if itemstack:get_count() == 0 then + + minetest.after(0.20, + farming.refill_plant, + placer, + "farming:grapes", + placer:get_wield_index() + ) + end + end + + return itemstack +end + +-- grapes +minetest.register_craftitem("farming:grapes", { + description = S("Grapes"), + inventory_image = "farming_grapes.png", + on_use = minetest.item_eat(2), + groups = {seed = 2, food_grapes = 1, flammable = 3}, + + on_place = function(itemstack, placer, pointed_thing) + return place_grapes(itemstack, placer, pointed_thing, "farming:grapes_1") + end, +}) + +-- grapes can be used for violet dye +minetest.register_craft({ + output = "dye:violet", + recipe = { + {"farming:grapes"}, + } +}) + +-- trellis +minetest.register_node("farming:trellis", { + description = S("Trellis (place on soil before planting grapes)"), + drawtype = "plantlike", + tiles = {"farming_trellis.png"}, + inventory_image = "farming_trellis.png", + visual_scale = 1.9, -- 1.45, + paramtype = "light", + walkable = false, + buildable_to = true, + sunlight_propagates = true, + drop = "farming:trellis", + selection_box = farming.select, + groups = {snappy = 3, flammable = 2, attached_node = 1}, + sounds = default.node_sound_leaves_defaults(), + + on_place = function(itemstack, placer, pointed_thing) + + local pt = pointed_thing + + -- check if pointing at a node + if not pt or pt.type ~= "node" then + return + end + + local under = minetest.get_node(pt.under) + + -- return if any of the nodes are not registered + if not minetest.registered_nodes[under.name] then + return + end + + -- am I right-clicking on something that has a custom on_place set? + -- thanks to Krock for helping with this issue :) + local def = minetest.registered_nodes[under.name] + if def and def.on_rightclick then + return def.on_rightclick(pt.under, under, placer, itemstack) + end + + if minetest.is_protected(pt.above, placer:get_player_name()) then + return + end + + local nodename = under.name + + if minetest.get_item_group(nodename, "soil") < 2 then + return + end + + local top = { + x = pointed_thing.above.x, + y = pointed_thing.above.y + 1, + z = pointed_thing.above.z + } + + nodename = minetest.get_node(top).name + + if nodename ~= "air" then + return + end + + minetest.set_node(pointed_thing.above, {name = "farming:trellis"}) + + if not farming.is_creative(placer:get_player_name()) then + itemstack:take_item() + end + + return itemstack + end +}) + +minetest.register_craft({ + output = "farming:trellis", + recipe = { + {"default:stick", "default:stick", "default:stick"}, + {"default:stick", "default:stick", "default:stick"}, + {"default:stick", "default:stick", "default:stick"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:trellis", + burntime = 15, +}) + +-- grapes definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_grapes_1.png"}, + visual_scale = 1.9, -- 1.45, + paramtype = "light", + walkable = false, + buildable_to = true, + sunlight_propagates = true, + drop = { + items = { + {items = {"farming:trellis"}, rarity = 1}, + } + }, + selection_box = farming.select, + groups = { + snappy = 3, flammable = 3, not_in_creative_inventory = 1, + attached_node = 1, growing = 1, plant = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:grapes_1", table.copy(crop_def)) + +-- stage2 +crop_def.tiles = {"farming_grapes_2.png"} +minetest.register_node("farming:grapes_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_grapes_3.png"} +minetest.register_node("farming:grapes_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_grapes_4.png"} +minetest.register_node("farming:grapes_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_grapes_5.png"} +minetest.register_node("farming:grapes_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_grapes_6.png"} +minetest.register_node("farming:grapes_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_grapes_7.png"} +minetest.register_node("farming:grapes_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_grapes_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:trellis"}, rarity = 1}, + {items = {"farming:grapes 3"}, rarity = 1}, + {items = {"farming:grapes 1"}, rarity = 2}, + {items = {"farming:grapes 1"}, rarity = 3}, + } +} +minetest.register_node("farming:grapes_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:grapes"] = { + crop = "farming:grapes", + seed = "farming:grapes", + minlight = 13, + maxlight = 15, + steps = 8 +} + +-- wild grape vine (this is what you find on the map) +minetest.register_node("farming:grapebush", { + drawtype = "plantlike", + tiles = {"farming_grapebush.png"}, + paramtype = "light", + waving = 1, + walkable = false, + buildable_to = true, + sunlight_propagates = true, + drop = { + items = { + {items = {"farming:grapes 1"}, rarity = 1}, + {items = {"farming:grapes 1"}, rarity = 2}, + {items = {"farming:grapes 1"}, rarity = 3}, + } + }, + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory=1 + }, + sounds = default.node_sound_leaves_defaults(), +}) diff --git a/mods/farming/crops/hemp.lua b/mods/farming/crops/hemp.lua new file mode 100644 index 0000000..8743b9c --- /dev/null +++ b/mods/farming/crops/hemp.lua @@ -0,0 +1,250 @@ + +local S = farming.intllib + +-- hemp seeds +minetest.register_node("farming:seed_hemp", { + description = S("Hemp Seed"), + tiles = {"farming_hemp_seed.png"}, + inventory_image = "farming_hemp_seed.png", + wield_image = "farming_hemp_seed.png", + drawtype = "signlike", + groups = {seed = 1, snappy = 3, attached_node = 1}, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + sunlight_propagates = true, + selection_box = farming.select, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:hemp_1") + end, +}) + +-- harvested hemp +minetest.register_craftitem("farming:hemp_leaf", { + description = S("Hemp Leaf"), + inventory_image = "farming_hemp_leaf.png", +}) + +-- hemp oil +minetest.register_node("farming:hemp_oil", { + description = S("Bottle of Hemp Oil"), + drawtype = "plantlike", + tiles = {"farming_hemp_oil.png"}, + inventory_image = "farming_hemp_oil.png", + wield_image = "farming_hemp_oil.png", + paramtype = "light", + is_ground_content = false, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + groups = {food_oil = 1, vessel = 1, dig_immediate = 3, attached_node = 1}, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_craft( { + output = "farming:hemp_oil", + recipe = { + {"farming:hemp_leaf", "farming:hemp_leaf", "farming:hemp_leaf"}, + {"farming:hemp_leaf", "farming:hemp_leaf", "farming:hemp_leaf"}, + {"", "vessels:glass_bottle", ""} + } +}) + +minetest.register_craft( { + output = "farming:hemp_oil", + recipe = { + {"farming:seed_hemp", "farming:seed_hemp", "farming:seed_hemp"}, + {"farming:seed_hemp", "farming:seed_hemp", "farming:seed_hemp"}, + {"farming:seed_hemp", "vessels:glass_bottle", "farming:seed_hemp"} + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:hemp_oil", + burntime = 20, + replacements = {{ "farming:hemp_oil", "vessels:glass_bottle"}} +}) + +-- hemp fibre +minetest.register_craftitem("farming:hemp_fibre", { + description = S("Hemp Fibre"), + inventory_image = "farming_hemp_fibre.png", +}) + +minetest.register_craft( { + output = "farming:hemp_fibre 8", + recipe = { + {"farming:hemp_leaf", "farming:hemp_leaf", "farming:hemp_leaf"}, + {"farming:hemp_leaf", "bucket:bucket_water", "farming:hemp_leaf"}, + {"farming:hemp_leaf", "farming:hemp_leaf", "farming:hemp_leaf"} + }, + replacements = {{ "bucket:bucket_water", "bucket:bucket_empty"}} +}) + +minetest.register_craft( { + output = "farming:hemp_fibre 8", + recipe = { + {"farming:hemp_leaf", "farming:hemp_leaf", "farming:hemp_leaf"}, + {"farming:hemp_leaf", "bucket:bucket_river_water", "farming:hemp_leaf"}, + {"farming:hemp_leaf", "farming:hemp_leaf", "farming:hemp_leaf"} + }, + replacements = {{ "bucket:bucket_river_water", "bucket:bucket_empty"}} +}) + +-- hemp block +minetest.register_node("farming:hemp_block", { + description = S("Hemp Block"), + tiles = {"farming_hemp_block.png"}, + paramtype = "light", + groups = {snappy = 1, oddly_breakable_by_hand = 1, flammable = 2} +}) + +minetest.register_craft( { + output = "farming:hemp_block", + recipe = { + {"farming:hemp_fibre", "farming:hemp_fibre", "farming:hemp_fibre"}, + {"farming:hemp_fibre", "farming:hemp_fibre", "farming:hemp_fibre"}, + {"farming:hemp_fibre", "farming:hemp_fibre", "farming:hemp_fibre"} + }, +}) + +-- check and register stairs +if minetest.global_exists("stairs") then + + if stairs.mod and stairs.mod == "redo" then + + stairs.register_all("hemp_block", "farming:hemp_block", + {snappy = 1, flammable = 2}, + {"farming_hemp_block.png"}, + "Hemp Block", + default.node_sound_leaves_defaults()) + else + + stairs.register_stair_and_slab("hemp_block", "farming:hemp_block", + {snappy = 1, flammable = 2}, + {"farming_hemp_block.png"}, + "Hemp Block Stair", + "Hemp Block Slab", + default.node_sound_leaves_defaults()) + end +end + +-- paper +minetest.register_craft( { + output = "default:paper", + recipe = { + {"farming:hemp_fibre", "farming:hemp_fibre", "farming:hemp_fibre"}, + } +}) + +-- hemp rope +minetest.register_node("farming:hemp_rope", { + description = S("Hemp Rope"), + walkable = false, + climbable = true, + sunlight_propagates = true, + paramtype = "light", + tiles = {"farming_hemp_rope.png"}, + wield_image = "farming_hemp_rope.png", + inventory_image = "farming_hemp_rope.png", + drawtype = "plantlike", + groups = {flammable = 2, choppy = 3, oddly_breakable_by_hand = 3}, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-1/7, -1/2, -1/7, 1/7, 1/2, 1/7}, + }, +}) + +-- string +minetest.register_craft( { + output = "farming:hemp_rope 6", + recipe = { + {"farming:hemp_fibre", "farming:hemp_fibre", "farming:hemp_fibre"}, + {"farming:cotton", "farming:cotton", "farming:cotton"}, + {"farming:hemp_fibre", "farming:hemp_fibre", "farming:hemp_fibre"}, + } +}) + +-- hemp definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_hemp_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:hemp_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_hemp_2.png"} +minetest.register_node("farming:hemp_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_hemp_3.png"} +minetest.register_node("farming:hemp_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_hemp_4.png"} +minetest.register_node("farming:hemp_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_hemp_5.png"} +minetest.register_node("farming:hemp_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_hemp_6.png"} +crop_def.drop = { + items = { + {items = {"farming:hemp_leaf"}, rarity = 2}, + {items = {"farming:seed_hemp"}, rarity = 1}, + } +} +minetest.register_node("farming:hemp_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_hemp_7.png"} +crop_def.drop = { + items = { + {items = {"farming:hemp_leaf"}, rarity = 1}, + {items = {"farming:hemp_leaf"}, rarity = 3}, + {items = {"farming:seed_hemp"}, rarity = 1}, + {items = {"farming:seed_hemp"}, rarity = 3}, + } +} +minetest.register_node("farming:hemp_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_hemp_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:hemp_leaf 2"}, rarity = 1}, + {items = {"farming:hemp_leaf"}, rarity = 2}, + {items = {"farming:seed_hemp"}, rarity = 1}, + {items = {"farming:seed_hemp"}, rarity = 2}, + } +} +minetest.register_node("farming:hemp_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:hemp"] = { + crop = "farming:hemp", + seed = "farming:seed_hemp", + minlight = 13, + maxlight = 15, + steps = 8 +} diff --git a/mods/farming/crops/melon.lua b/mods/farming/crops/melon.lua new file mode 100644 index 0000000..3fda9f6 --- /dev/null +++ b/mods/farming/crops/melon.lua @@ -0,0 +1,95 @@ + +local S = farming.intllib + +-- melon +minetest.register_craftitem("farming:melon_slice", { + description = S("Melon Slice"), + inventory_image = "farming_melon_slice.png", + groups = {seed = 2, food_melon_slice = 1, flammable = 3}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:melon_1") + end, + on_use = minetest.item_eat(2), +}) + +minetest.register_craft({ + output = "farming:melon_8", + recipe = { + {"farming:melon_slice", "farming:melon_slice"}, + {"farming:melon_slice", "farming:melon_slice"}, + } +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:melon_slice 4", + recipe = {"farming:melon_8", "farming:cutting_board"}, + replacements = {{"farming:cutting_board", "farming:cutting_board"}}, +}) + +-- melon definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_melon_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:melon_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_melon_2.png"} +minetest.register_node("farming:melon_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_melon_3.png"} +minetest.register_node("farming:melon_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_melon_4.png"} +minetest.register_node("farming:melon_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_melon_5.png"} +minetest.register_node("farming:melon_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_melon_6.png"} +minetest.register_node("farming:melon_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_melon_7.png"} +minetest.register_node("farming:melon_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.drawtype = "nodebox" +crop_def.description = S("Melon") +crop_def.tiles = {"farming_melon_top.png", "farming_melon_top.png", "farming_melon_side.png"} +crop_def.selection_box = {-.5, -.5, -.5, .5, .5, .5} +crop_def.walkable = true +crop_def.groups = { + food_melon = 1, snappy = 1, oddly_breakable_by_hand = 1, + flammable = 2, plant = 1 +} +--crop_def.drop = "farming:melon_slice 9" +crop_def.drop = "farming:melon_8" +minetest.register_node("farming:melon_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:melon"] = { + crop = "farming:melon", + seed = "farming:melon_slice", + minlight = 13, + maxlight = 15, + steps = 8 +} diff --git a/mods/farming/crops/onion.lua b/mods/farming/crops/onion.lua new file mode 100644 index 0000000..72a425e --- /dev/null +++ b/mods/farming/crops/onion.lua @@ -0,0 +1,77 @@ + +--[[ + Original textures from Crops Plus mod + Copyright (C) 2018 Grizzly Adam + https://forum.minetest.net/viewtopic.php?f=9&t=19488 +]] + +local S = farming.intllib + +-- potato +minetest.register_craftitem("farming:onion", { + description = S("Onion"), + inventory_image = "crops_onion.png", + groups = {seed = 2, food_onion = 1, flammable = 3}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:onion_1") + end, + on_use = minetest.item_eat(1), +}) + +-- crop definition +local crop_def = { + drawtype = "plantlike", + tiles = {"crops_onion_plant_1.png"}, + paramtype = "light", + paramtype2 = "meshoptions", + place_param2 = 3, + sunlight_propagates = true, + waving = 1, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 3, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:onion_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"crops_onion_plant_2.png"} +minetest.register_node("farming:onion_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"crops_onion_plant_3.png"} +minetest.register_node("farming:onion_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"crops_onion_plant_4.png"} +minetest.register_node("farming:onion_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"crops_onion_plant_5.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + max_items = 5, items = { + {items = {"farming:onion"}, rarity = 1}, + {items = {"farming:onion"}, rarity = 1}, + {items = {"farming:onion"}, rarity = 2}, + {items = {"farming:onion"}, rarity = 2}, + {items = {"farming:onion"}, rarity = 5}, + } +} +minetest.register_node("farming:onion_5", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:onion"] = { + crop = "farming:onion", + seed = "farming:onion", + minlight = 13, + maxlight = 15, + steps = 5 +} diff --git a/mods/farming/crops/peas.lua b/mods/farming/crops/peas.lua new file mode 100644 index 0000000..ffe21b3 --- /dev/null +++ b/mods/farming/crops/peas.lua @@ -0,0 +1,97 @@ + +local S = farming.intllib + +-- Textures for Pea crop and Peas were done by Andrey01 + +-- pea pod +minetest.register_craftitem("farming:pea_pod", { + description = S("Pea Pod"), + inventory_image = "farming_pea_pod.png", + groups = {seed = 2, food_pea_pod = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:pea_1") + end +}) + +minetest.register_craftitem("farming:peas", { + description = S("Peas"), + inventory_image = "farming_pea_peas.png", + groups = {food_peas = 1, flammable = 2}, + on_use = minetest.item_eat(1) +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:peas", + recipe = {"farming:pea_pod"} +}) + +-- pea soup +minetest.register_craftitem("farming:pea_soup", { + description = S("Pea Soup"), + inventory_image = "farming_pea_soup.png", + groups = {flammable = 2}, + on_use = minetest.item_eat(4, "farming:bowl"), +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:pea_soup", + recipe = {"group:food_peas", "group:food_peas", "group:food_bowl"} +}) + +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_pea_1.png"}, + paramtype = "light", + paramtype2 = "meshoptions", + place_param2 = 3, + sunlight_propagates = true, + waving = 1, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:pea_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_pea_2.png"} +minetest.register_node("farming:pea_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_pea_3.png"} +minetest.register_node("farming:pea_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_pea_4.png"} +minetest.register_node("farming:pea_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_pea_5.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + max_items = 5, items = { + {items = {"farming:pea_pod"}, rarity = 1}, + {items = {"farming:pea_pod"}, rarity = 2}, + {items = {"farming:pea_pod"}, rarity = 3}, + {items = {"farming:pea_pod"}, rarity = 5}, + } +} +minetest.register_node("farming:pea_5", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:pea_pod"] = { + crop = "farming:pea", + seed = "farming:pea_pod", + minlight = 13, + maxlight = 15, + steps = 5 +} diff --git a/mods/farming/crops/pepper.lua b/mods/farming/crops/pepper.lua new file mode 100644 index 0000000..6770888 --- /dev/null +++ b/mods/farming/crops/pepper.lua @@ -0,0 +1,115 @@ + +--[[ + Original textures from Crops Plus mod + Copyright (C) 2018 Grizzly Adam + https://forum.minetest.net/viewtopic.php?f=9&t=19488 +]] + +local S = farming.intllib + +-- peppercorn (seed) +minetest.register_craftitem("farming:peppercorn", { + description = S("Peppercorn"), + inventory_image = "crops_peppercorn.png", + groups = {seed = 1, food_peppercorn = 1, flammable = 3}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:pepper_1") + end, +}) + +-- green pepper +minetest.register_craftitem("farming:pepper", { + description = S("Pepper"), + inventory_image = "crops_pepper.png", + on_use = minetest.item_eat(2), + groups = {food_pepper = 1, flammable = 3}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:peppercorn", + recipe = {"farming:pepper"} +}) + +-- ground pepper +minetest.register_node("farming:pepper_ground", { + description = ("Ground Pepper"), + inventory_image = "crops_pepper_ground.png", + wield_image = "crops_pepper_ground.png", + drawtype = "plantlike", + visual_scale = 0.8, + paramtype = "light", + tiles = {"crops_pepper_ground.png"}, + groups = { + vessel = 1, food_pepper_ground = 1, + dig_immediate = 3, attached_node = 1 + }, + sounds = default.node_sound_defaults(), + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, +}) + +minetest.register_craft( { + output = "farming:pepper_ground", + type = "shapeless", + recipe = {"group:food_peppercorn", "vessels:glass_bottle", "farming:mortar_pestle"}, + replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}, +}) + +-- crop definition +local crop_def = { + drawtype = "plantlike", + tiles = {"crops_pepper_plant_1.png"}, + paramtype = "light", + paramtype2 = "meshoptions", + place_param2 = 1, + sunlight_propagates = true, + waving = 1, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 3, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:pepper_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"crops_pepper_plant_2.png"} +minetest.register_node("farming:pepper_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"crops_pepper_plant_3.png"} +minetest.register_node("farming:pepper_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"crops_pepper_plant_4.png"} +minetest.register_node("farming:pepper_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"crops_pepper_plant_5.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + max_items = 2, items = { + {items = {"farming:pepper 2"}, rarity = 1}, + {items = {"farming:pepper"}, rarity = 2}, + {items = {"farming:pepper"}, rarity = 3}, + } +} +minetest.register_node("farming:pepper_5", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:pepper"] = { + crop = "farming:pepper", + seed = "farming:peppercorn", + minlight = 13, + maxlight = 15, + steps = 5 +} diff --git a/mods/farming/crops/pineapple.lua b/mods/farming/crops/pineapple.lua new file mode 100644 index 0000000..0ca1c34 --- /dev/null +++ b/mods/farming/crops/pineapple.lua @@ -0,0 +1,109 @@ + +local S = farming.intllib + +-- pineapple top +minetest.register_craftitem("farming:pineapple_top", { + description = S("Pineapple Top"), + inventory_image = "farming_pineapple_top.png", + groups = {seed = 2, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:pineapple_1") + end, +}) + +-- pineapple +minetest.register_node("farming:pineapple", { + description = S("Pineapple"), + drawtype = "plantlike", + tiles = {"farming_pineapple.png"}, + inventory_image = "farming_pineapple.png", + wield_image = "farming_pineapple.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-0.27, -0.37, -0.27, 0.27, 0.44, 0.27} + }, + groups = {food_pineapple = 1, fleshy = 3, dig_immediate = 3, flammable = 2}, +}) + +-- pineapple +minetest.register_craftitem("farming:pineapple_ring", { + description = S("Pineapple Ring"), + inventory_image = "farming_pineapple_ring.png", + groups = {food_pineapple_ring = 1, flammable = 2}, + on_use = minetest.item_eat(1), +}) + +minetest.register_craft( { + output = "farming:pineapple_ring 5", + type = "shapeless", + recipe = {"group:food_pineapple"}, + replacements = {{"farming:pineapple", "farming:pineapple_top"}} +}) + +-- crop definition +local crop_def = { + drawtype = "plantlike", + visual_scale = 1.5, + tiles = {"farming_pineapple_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:pineapple_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_pineapple_2.png"} +minetest.register_node("farming:pineapple_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_pineapple_3.png"} +minetest.register_node("farming:pineapple_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_pineapple_4.png"} +minetest.register_node("farming:pineapple_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_pineapple_5.png"} +minetest.register_node("farming:pineapple_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_pineapple_6.png"} +minetest.register_node("farming:pineapple_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_pineapple_7.png"} +minetest.register_node("farming:pineapple_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_pineapple_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:pineapple"}, rarity = 1}, + {items = {"farming:pineapple"}, rarity = 15}, + } +} +minetest.register_node("farming:pineapple_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:pineapple"] = { + crop = "farming:pineapple", + seed = "farming:pineapple_top", + minlight = 13, + maxlight = 15, + steps = 8 +} diff --git a/mods/farming/crops/potato.lua b/mods/farming/crops/potato.lua new file mode 100644 index 0000000..d9f3e14 --- /dev/null +++ b/mods/farming/crops/potato.lua @@ -0,0 +1,112 @@ + +--[[ + Original textures from DocFarming mod + https://forum.minetest.net/viewtopic.php?id=3948 +]] + +local S = farming.intllib + +-- potato +minetest.register_craftitem("farming:potato", { + description = S("Potato"), + inventory_image = "farming_potato.png", + groups = {seed = 2, food_potato = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:potato_1") + end, +-- on_use = minetest.item_eat(1), + on_use = function(itemstack, user, pointed_thing) + if user then + if math.random(1, 3) == 1 then + return minetest.do_item_eat(-1, nil, itemstack, user, pointed_thing) + else + return minetest.do_item_eat(1, nil, itemstack, user, pointed_thing) + end + end + end, +}) + +-- baked potato +minetest.register_craftitem("farming:baked_potato", { + description = S("Baked Potato"), + inventory_image = "farming_baked_potato.png", + on_use = minetest.item_eat(6), +}) + +minetest.register_craft({ + type = "cooking", + cooktime = 10, + output = "farming:baked_potato", + recipe = "group:food_potato" +}) + +-- Potato and cucumber Salad +minetest.register_craftitem("farming:potato_salad", { + description = S("Cucumber and Potato Salad"), + inventory_image = "farming_potato_salad.png", + on_use = minetest.item_eat(10, "farming:bowl"), +}) + +minetest.register_craft({ + output = "farming:potato_salad", + recipe = { + {"group:food_cucumber"}, + {"farming:baked_potato"}, + {"group:food_bowl"}, + } +}) + +-- potato definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_potato_1.png"}, + paramtype = "light", + sunlight_propagates = true, + waving = 1, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:potato_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_potato_2.png"} +minetest.register_node("farming:potato_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_potato_3.png"} +crop_def.drop = { + items = { + {items = {"farming:potato"}, rarity = 1}, + {items = {"farming:potato"}, rarity = 3}, + } +} +minetest.register_node("farming:potato_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_potato_4.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:potato 2"}, rarity = 1}, + {items = {"farming:potato 3"}, rarity = 2}, + } +} +minetest.register_node("farming:potato_4", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:potato"] = { + crop = "farming:potato", + seed = "farming:potato", + minlight = 13, + maxlight = 15, + steps = 4 +} diff --git a/mods/farming/crops/pumpkin.lua b/mods/farming/crops/pumpkin.lua new file mode 100644 index 0000000..1e937db --- /dev/null +++ b/mods/farming/crops/pumpkin.lua @@ -0,0 +1,221 @@ + +--[[ + Big thanks to PainterlyPack.net for allowing me to use these textures +]] + +local S = farming.intllib + +-- pumpkin slice +minetest.register_craftitem("farming:pumpkin_slice", { + description = S("Pumpkin Slice"), + inventory_image = "farming_pumpkin_slice.png", + groups = {seed = 2, food_pumpkin_slice = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:pumpkin_1") + end, + on_use = minetest.item_eat(2), +}) + +minetest.register_craft({ + output = "farming:pumpkin", + recipe = { + {"farming:pumpkin_slice", "farming:pumpkin_slice"}, + {"farming:pumpkin_slice", "farming:pumpkin_slice"}, + } +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:pumpkin_slice 4", + recipe = {"farming:pumpkin", "farming:cutting_board"}, + replacements = {{"farming:cutting_board", "farming:cutting_board"}}, +}) + +-- jack 'o lantern +minetest.register_node("farming:jackolantern", { + description = S("Jack 'O Lantern (punch to turn on and off)"), + tiles = { + "farming_pumpkin_top.png", + "farming_pumpkin_top.png", + "farming_pumpkin_side.png", + "farming_pumpkin_side.png", + "farming_pumpkin_side.png", + "farming_pumpkin_face_off.png" + }, + paramtype2 = "facedir", + groups = {choppy = 1, oddly_breakable_by_hand = 1, flammable = 2}, + sounds = default.node_sound_wood_defaults(), + on_punch = function(pos, node, puncher) + local name = puncher:get_player_name() or "" + if minetest.is_protected(pos, name) then return end + node.name = "farming:jackolantern_on" + minetest.swap_node(pos, node) + end, +}) + +minetest.register_node("farming:jackolantern_on", { + tiles = { + "farming_pumpkin_top.png", + "farming_pumpkin_top.png", + "farming_pumpkin_side.png", + "farming_pumpkin_side.png", + "farming_pumpkin_side.png", + "farming_pumpkin_face_on.png" + }, + light_source = default.LIGHT_MAX - 1, + paramtype2 = "facedir", + groups = { + choppy = 1, oddly_breakable_by_hand = 1, flammable = 2, + not_in_creative_inventory = 1 + }, + sounds = default.node_sound_wood_defaults(), + drop = "farming:jackolantern", + on_punch = function(pos, node, puncher) + local name = puncher:get_player_name() or "" + if minetest.is_protected(pos, name) then return end + node.name = "farming:jackolantern" + minetest.swap_node(pos, node) + end, +}) + +minetest.register_craft({ + output = "farming:jackolantern", + recipe = { + {"default:torch"}, + {"group:food_pumpkin"}, + } +}) + +--- wooden scarecrow base +minetest.register_node("farming:scarecrow_bottom", { + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "facedir", + tiles = {"default_wood.png"}, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-1/16, -8/16, -1/16, 1/16, 8/16, 1/16}, + {-12/16, 4/16, -1/16, 12/16, 2/16, 1/16}, + }, + }, + groups = {snappy = 3, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:scarecrow_bottom", + recipe = { + {"", "group:stick", "",}, + {"group:stick", "group:stick", "group:stick",}, + {"", "group:stick", "",} + } +}) + +-- pumpkin bread +minetest.register_craftitem("farming:pumpkin_bread", { + description = S("Pumpkin Bread"), + inventory_image = "farming_pumpkin_bread.png", + on_use = minetest.item_eat(8), + groups = {food_bread = 1, flammable = 2}, +}) + +minetest.register_craftitem("farming:pumpkin_dough", { + description = S("Pumpkin Dough"), + inventory_image = "farming_pumpkin_dough.png", +}) + +minetest.register_craft({ + output = "farming:pumpkin_dough", + type = "shapeless", + recipe = {"group:food_flour", "group:food_pumpkin_slice", "group:food_pumpkin_slice"} +}) + +minetest.register_craft({ + type = "cooking", + output = "farming:pumpkin_bread", + recipe = "farming:pumpkin_dough", + cooktime = 10 +}) + +-- pumpkin definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_pumpkin_1.png"}, + paramtype = "light", + sunlight_propagates = true, + waving = 1, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:pumpkin_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_pumpkin_2.png"} +minetest.register_node("farming:pumpkin_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_pumpkin_3.png"} +minetest.register_node("farming:pumpkin_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_pumpkin_4.png"} +minetest.register_node("farming:pumpkin_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_pumpkin_5.png"} +minetest.register_node("farming:pumpkin_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_pumpkin_6.png"} +minetest.register_node("farming:pumpkin_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_pumpkin_7.png"} +minetest.register_node("farming:pumpkin_7", table.copy(crop_def)) + +-- stage 8 (final) +--[[ +crop_def.tiles = {"farming_pumpkin_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:pumpkin_slice 9"}, rarity = 1}, + } +} +minetest.register_node("farming:pumpkin_8", table.copy(crop_def)) +]] + +minetest.register_node("farming:pumpkin_8", { + description = S("Pumpkin"), + tiles = { + "farming_pumpkin_top.png", + "farming_pumpkin_top.png", + "farming_pumpkin_side.png" + }, + groups = { + food_pumpkin = 1, choppy = 1, oddly_breakable_by_hand = 1, + flammable = 2, plant = 1 + }, + sounds = default.node_sound_wood_defaults(), +}) + +minetest.register_alias("farming:pumpkin", "farming:pumpkin_8") + +-- add to registered_plants +farming.registered_plants["farming:pumpkin"] = { + crop = "farming:pumpkin", + seed = "farming:pumpkin_slice", + minlight = 13, + maxlight = 15, + steps = 8 +} diff --git a/mods/farming/crops/raspberry.lua b/mods/farming/crops/raspberry.lua new file mode 100644 index 0000000..8c909e4 --- /dev/null +++ b/mods/farming/crops/raspberry.lua @@ -0,0 +1,80 @@ + +local S = farming.intllib + +-- raspberries +minetest.register_craftitem("farming:raspberries", { + description = S("Raspberries"), + inventory_image = "farming_raspberries.png", + groups = {seed = 2, food_raspberries = 1, food_raspberry = 1, + food_berry = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:raspberry_1") + end, + on_use = minetest.item_eat(1), +}) + +-- raspberry smoothie +minetest.register_craftitem("farming:smoothie_raspberry", { + description = S("Raspberry Smoothie"), + inventory_image = "farming_raspberry_smoothie.png", + on_use = minetest.item_eat(2, "vessels:drinking_glass"), + groups = {vessel = 1}, +}) + +minetest.register_craft({ + output = "farming:smoothie_raspberry", + recipe = { + {"default:snow"}, + {"group:food_raspberries"}, + {"vessels:drinking_glass"}, + } +}) + +-- raspberries definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_raspberry_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:raspberry_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_raspberry_2.png"} +minetest.register_node("farming:raspberry_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_raspberry_3.png"} +minetest.register_node("farming:raspberry_3", table.copy(crop_def)) + +-- stage 4 (final) +crop_def.tiles = {"farming_raspberry_4.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:raspberries 2"}, rarity = 1}, + {items = {"farming:raspberries"}, rarity = 2}, + {items = {"farming:raspberries"}, rarity = 3}, + } +} +minetest.register_node("farming:raspberry_4", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:raspberries"] = { + crop = "farming:raspberry", + seed = "farming:raspberries", + minlight = 13, + maxlight = 15, + steps = 4 +} diff --git a/mods/farming/crops/rhubarb.lua b/mods/farming/crops/rhubarb.lua new file mode 100644 index 0000000..dafb7e7 --- /dev/null +++ b/mods/farming/crops/rhubarb.lua @@ -0,0 +1,75 @@ + +local S = farming.intllib + +-- rhubarb +minetest.register_craftitem("farming:rhubarb", { + description = S("Rhubarb"), + inventory_image = "farming_rhubarb.png", + groups = {seed = 2, food_rhubarb = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:rhubarb_1") + end, + on_use = minetest.item_eat(1), +}) + +-- rhubarb pie +minetest.register_craftitem("farming:rhubarb_pie", { + description = S("Rhubarb Pie"), + inventory_image = "farming_rhubarb_pie.png", + on_use = minetest.item_eat(6), +}) + +minetest.register_craft({ + output = "farming:rhubarb_pie", + recipe = { + {"farming:baking_tray", "group:food_sugar", ""}, + {"group:food_rhubarb", "group:food_rhubarb", "group:food_rhubarb"}, + {"group:food_wheat", "group:food_wheat", "group:food_wheat"}, + }, + replacements = {{"group:food_baking_tray", "farming:baking_tray"}} +}) + +-- rhubarb definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_rhubarb_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:rhubarb_1", table.copy(crop_def)) + +-- stage2 +crop_def.tiles = {"farming_rhubarb_2.png"} +minetest.register_node("farming:rhubarb_2", table.copy(crop_def)) + +-- stage 3 (final) +crop_def.tiles = {"farming_rhubarb_3.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:rhubarb 2"}, rarity = 1}, + {items = {"farming:rhubarb"}, rarity = 2}, + {items = {"farming:rhubarb"}, rarity = 3}, + } +} +minetest.register_node("farming:rhubarb_3", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:rhubarb"] = { + crop = "farming:rhubarb", + seed = "farming:rhubarb", + minlight = 13, + maxlight = 15, + steps = 3 +} diff --git a/mods/farming/crops/ryeoatrice.lua b/mods/farming/crops/ryeoatrice.lua new file mode 100644 index 0000000..d064626 --- /dev/null +++ b/mods/farming/crops/ryeoatrice.lua @@ -0,0 +1,162 @@ + +local S = farming.intllib + +--= A nice addition from Ademant's grain mod :) + +-- Rye + +farming.register_plant("farming:rye", { + description = "Rye seed", + paramtype2 = "meshoptions", + inventory_image = "farming_rye_seed.png", + steps = 8, + place_param2 = 3, +}) + +minetest.override_item("farming:rye", { + groups = {food_rye = 1, flammable = 4} +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:flour", + recipe = { + "farming:rye", "farming:rye", "farming:rye", "farming:rye", + "farming:mortar_pestle" + }, + replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}, +}) + +-- Oats + +farming.register_plant("farming:oat", { + description = "Oat seed", + paramtype2 = "meshoptions", + inventory_image = "farming_oat_seed.png", + steps = 8, + place_param2 = 3, +}) + +minetest.override_item("farming:oat", { + groups = {food_oats = 1, flammable = 4} +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:flour", + recipe = { + "farming:oat", "farming:oat", "farming:oat", "farming:oat", + "farming:mortar_pestle" + }, + replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}, +}) + +-- Rice + +farming.register_plant("farming:rice", { + description = "Rice grains", + paramtype2 = "meshoptions", + inventory_image = "farming_rice_seed.png", + steps = 8, + place_param2 = 3, +}) + +minetest.override_item("farming:rice", { + groups = {food_rice = 1, flammable = 4} +}) + +minetest.register_craftitem("farming:rice_bread", { + description = "Rice Bread", + inventory_image = "farming_rice_bread.png", + on_use = minetest.item_eat(5), + groups = {food_rice_bread = 1, flammable = 2}, +}) + +minetest.register_craftitem("farming:rice_flour", { + description = "Rice Flour", + inventory_image = "farming_rice_flour.png", + groups = {food_rice_flour = 1, flammable = 1}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:rice_flour", + recipe = { + "farming:rice", "farming:rice", "farming:rice", "farming:rice", + "farming:mortar_pestle" + }, + replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}, +}) + +minetest.register_craft({ + type = "cooking", + cooktime = 15, + output = "farming:rice_bread", + recipe = "farming:rice_flour" +}) + +-- Multigrain flour + +minetest.register_craftitem("farming:flour_multigrain", { + description = S("Multigrain Flour"), + inventory_image = "farming_flour_multigrain.png", + groups = {food_flour = 1, flammable = 1}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:flour_multigrain", + recipe = { + "farming:wheat", "farming:barley", "farming:oat", + "farming:rye", "farming:mortar_pestle" + }, + replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}, +}) + +-- Multigrain bread + +minetest.register_craftitem("farming:bread_multigrain", { + description = S("Multigrain Bread"), + inventory_image = "farming_bread_multigrain.png", + on_use = minetest.item_eat(7), + groups = {food_bread = 1, flammable = 2}, +}) + +minetest.register_craft({ + type = "cooking", + cooktime = 15, + output = "farming:bread_multigrain", + recipe = "farming:flour_multigrain" +}) + +-- Fuels + +minetest.register_craft({ + type = "fuel", + recipe = "farming:rice_bread", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:bread_multigrain", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:rye", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:oat", + burntime = 1, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:rice", + burntime = 1, +}) diff --git a/mods/farming/crops/tomato.lua b/mods/farming/crops/tomato.lua new file mode 100644 index 0000000..c082328 --- /dev/null +++ b/mods/farming/crops/tomato.lua @@ -0,0 +1,88 @@ + +--[[ + Textures edited from: + http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/1288375-food-plus-mod-more-food-than-you-can-imagine-v2-9) +]] + +local S = farming.intllib + +-- tomato +minetest.register_craftitem("farming:tomato", { + description = S("Tomato"), + inventory_image = "farming_tomato.png", + groups = {seed = 2, food_tomato = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:tomato_1") + end, + on_use = minetest.item_eat(4), +}) + +-- tomato definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_tomato_1.png"}, + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 2, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:tomato_1", table.copy(crop_def)) + +-- stage2 +crop_def.tiles = {"farming_tomato_2.png"} +minetest.register_node("farming:tomato_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_tomato_3.png"} +minetest.register_node("farming:tomato_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_tomato_4.png"} +minetest.register_node("farming:tomato_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_tomato_5.png"} +minetest.register_node("farming:tomato_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_tomato_6.png"} +minetest.register_node("farming:tomato_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_tomato_7.png"} +crop_def.drop = { + items = { + {items = {"farming:tomato"}, rarity = 1}, + {items = {"farming:tomato"}, rarity = 3}, + } +} +minetest.register_node("farming:tomato_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_tomato_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:tomato 3"}, rarity = 1}, + {items = {"farming:tomato 3"}, rarity = 2}, + } +} +minetest.register_node("farming:tomato_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:tomato"] = { + crop = "farming:tomato", + seed = "farming:tomato", + minlight = 13, + maxlight = 15, + steps = 8 +} diff --git a/mods/farming/crops/wheat.lua b/mods/farming/crops/wheat.lua new file mode 100644 index 0000000..b047561 --- /dev/null +++ b/mods/farming/crops/wheat.lua @@ -0,0 +1,253 @@ + +local S = farming.intllib + +-- wheat seeds +minetest.register_node("farming:seed_wheat", { + description = S("Wheat Seed"), + tiles = {"farming_wheat_seed.png"}, + inventory_image = "farming_wheat_seed.png", + wield_image = "farming_wheat_seed.png", + drawtype = "signlike", + groups = {seed = 1, snappy = 3, attached_node = 1, flammable = 4}, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + sunlight_propagates = true, + selection_box = farming.select, + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, pointed_thing, "farming:wheat_1") + end, +}) + +-- harvested wheat +minetest.register_craftitem("farming:wheat", { + description = S("Wheat"), + inventory_image = "farming_wheat.png", + groups = {food_wheat = 1, flammable = 4}, +}) + +-- straw +minetest.register_node("farming:straw", { + description = S("Straw"), + tiles = {"farming_straw.png"}, + is_ground_content = false, + groups = {snappy = 3, flammable = 4, fall_damage_add_percent = -30}, + sounds = default.node_sound_leaves_defaults(), +}) + +minetest.register_craft({ + output = "farming:straw 3", + recipe = { + {"farming:wheat", "farming:wheat", "farming:wheat"}, + {"farming:wheat", "farming:wheat", "farming:wheat"}, + {"farming:wheat", "farming:wheat", "farming:wheat"}, + } +}) + +minetest.register_craft({ + output = "farming:wheat 3", + recipe = { + {"farming:straw"}, + } +}) + +-- check and register stairs +if minetest.global_exists("stairs") then + + if stairs.mod and stairs.mod == "redo" then + + stairs.register_all("straw", "farming:straw", + {snappy = 3, flammable = 4}, + {"farming_straw.png"}, + "Straw", + default.node_sound_leaves_defaults()) + else + + stairs.register_stair_and_slab("straw", "farming:straw", + {snappy = 3, flammable = 4}, + {"farming_straw.png"}, + "Straw Stair", + "Straw Slab", + default.node_sound_leaves_defaults()) + end +end + +-- flour +minetest.register_craftitem("farming:flour", { + description = S("Flour"), + inventory_image = "farming_flour.png", + groups = {food_flour = 1, flammable = 1}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:flour", + recipe = { + "farming:wheat", "farming:wheat", "farming:wheat", + "farming:wheat", "farming:mortar_pestle" + }, + replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}}, +}) + +-- bread +minetest.register_craftitem("farming:bread", { + description = S("Bread"), + inventory_image = "farming_bread.png", + on_use = minetest.item_eat(5), + groups = {food_bread = 1, flammable = 2}, +}) + +minetest.register_craft({ + type = "cooking", + cooktime = 15, + output = "farming:bread", + recipe = "farming:flour" +}) + +-- sliced bread +minetest.register_craftitem("farming:bread_slice", { + description = S("Sliced Bread"), + inventory_image = "farming_bread_slice.png", + on_use = minetest.item_eat(1), + groups = {food_bread_slice = 1, flammable = 2}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:bread_slice 5", + recipe = {"farming:bread", "group:food_cutting_board"}, + replacements = {{"group:food_cutting_board", "farming:cutting_board"}}, +}) + +-- toast +minetest.register_craftitem("farming:toast", { + description = S("Toast"), + inventory_image = "farming_toast.png", + on_use = minetest.item_eat(1), + groups = {food_toast = 1, flammable = 2}, +}) + +minetest.register_craft({ + type = "cooking", + cooktime = 3, + output = "farming:toast", + recipe = "farming:bread_slice" +}) + +-- toast sandwich +minetest.register_craftitem("farming:toast_sandwich", { + description = S("Toast Sandwich"), + inventory_image = "farming_toast_sandwich.png", + on_use = minetest.item_eat(4), + groups = {flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:toast_sandwich", + recipe = { + {"farming:bread_slice"}, + {"farming:toast"}, + {"farming:bread_slice"}, + } +}) + +-- wheat definition +local crop_def = { + drawtype = "plantlike", + tiles = {"farming_wheat_1.png"}, + paramtype = "light", + paramtype2 = "meshoptions", + place_param2 = 3, + sunlight_propagates = true, + walkable = false, + buildable_to = true, + drop = "", + selection_box = farming.select, + groups = { + snappy = 3, flammable = 4, plant = 1, attached_node = 1, + not_in_creative_inventory = 1, growing = 1 + }, + sounds = default.node_sound_leaves_defaults() +} + +-- stage 1 +minetest.register_node("farming:wheat_1", table.copy(crop_def)) + +-- stage 2 +crop_def.tiles = {"farming_wheat_2.png"} +minetest.register_node("farming:wheat_2", table.copy(crop_def)) + +-- stage 3 +crop_def.tiles = {"farming_wheat_3.png"} +minetest.register_node("farming:wheat_3", table.copy(crop_def)) + +-- stage 4 +crop_def.tiles = {"farming_wheat_4.png"} +minetest.register_node("farming:wheat_4", table.copy(crop_def)) + +-- stage 5 +crop_def.tiles = {"farming_wheat_5.png"} +crop_def.drop = { + items = { + {items = {"farming:wheat"}, rarity = 2}, + {items = {"farming:seed_wheat"}, rarity = 2}, + } +} +minetest.register_node("farming:wheat_5", table.copy(crop_def)) + +-- stage 6 +crop_def.tiles = {"farming_wheat_6.png"} +crop_def.drop = { + items = { + {items = {"farming:wheat"}, rarity = 2}, + {items = {"farming:seed_wheat"}, rarity = 1}, + } +} +minetest.register_node("farming:wheat_6", table.copy(crop_def)) + +-- stage 7 +crop_def.tiles = {"farming_wheat_7.png"} +crop_def.drop = { + items = { + {items = {"farming:wheat"}, rarity = 1}, + {items = {"farming:wheat"}, rarity = 3}, + {items = {"farming:seed_wheat"}, rarity = 1}, + {items = {"farming:seed_wheat"}, rarity = 3}, + } +} +minetest.register_node("farming:wheat_7", table.copy(crop_def)) + +-- stage 8 (final) +crop_def.tiles = {"farming_wheat_8.png"} +crop_def.groups.growing = 0 +crop_def.drop = { + items = { + {items = {"farming:wheat"}, rarity = 1}, + {items = {"farming:wheat"}, rarity = 3}, + {items = {"farming:seed_wheat"}, rarity = 1}, + {items = {"farming:seed_wheat"}, rarity = 3}, + } +} +minetest.register_node("farming:wheat_8", table.copy(crop_def)) + +-- add to registered_plants +farming.registered_plants["farming:wheat"] = { + crop = "farming:wheat", + seed = "farming:seed_wheat", + minlight = 13, + maxlight = 15, + steps = 8 +} + +-- fuels +minetest.register_craft({ + type = "fuel", + recipe = "farming:straw", + burntime = 3, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:wheat", + burntime = 1, +}) diff --git a/mods/farming/depends.txt b/mods/farming/depends.txt new file mode 100644 index 0000000..650885b --- /dev/null +++ b/mods/farming/depends.txt @@ -0,0 +1,5 @@ +default +stairs? +intllib? +lucky_block? +toolranks? diff --git a/mods/farming/description.txt b/mods/farming/description.txt new file mode 100644 index 0000000..58bdc81 --- /dev/null +++ b/mods/farming/description.txt @@ -0,0 +1 @@ +Adds many plants and food to Minetest \ No newline at end of file diff --git a/mods/farming/farming.conf_example b/mods/farming/farming.conf_example new file mode 100644 index 0000000..c2c5de0 --- /dev/null +++ b/mods/farming/farming.conf_example @@ -0,0 +1,35 @@ + +--[[ + Farming settings can be changed here and kept inside mod folder + even after the mod has been updated, or you can place inside + world folder for map specific settings. +--]] + +-- true to enable crop/food in-game and on mapgen set spawn rarety +farming.carrot = 0.001 +farming.potato = 0.001 +farming.tomato = 0.001 +farming.cucumber = 0.001 +farming.corn = 0.001 +farming.coffee = 0.001 +farming.melon = 0.001 +farming.pumpkin = 0.001 +farming.cocoa = true -- true or false only +farming.raspberry = 0.001 +farming.blueberry = 0.001 +farming.rhubarb = 0.001 +farming.beans = 0.001 +farming.grapes = 0.001 +farming.barley = true -- true or false only +farming.chili = 0.003 +farming.hemp = 0.003 +farming.garlic = 0.001 +farming.onion = 0.001 +farming.pepper = 0.002 +farming.pineapple = 0.001 +farming.peas = 0.001 +farming.beetroot = 0.001 +farming.grains = true -- true or false only + +-- default rarety of crops on map (higher number = more crops) +farming.rarety = 0.002 diff --git a/mods/farming/food.lua b/mods/farming/food.lua new file mode 100644 index 0000000..00f3267 --- /dev/null +++ b/mods/farming/food.lua @@ -0,0 +1,220 @@ + +local S = farming.intllib + +--= Sugar + +minetest.register_craftitem("farming:sugar", { + description = S("Sugar"), + inventory_image = "farming_sugar.png", + groups = {food_sugar = 1, flammable = 3}, +}) + +minetest.register_craft({ + type = "cooking", + cooktime = 3, + output = "farming:sugar 2", + recipe = "default:papyrus", +}) + + +--= Salt + +minetest.register_node("farming:salt", { + description = ("Salt"), + inventory_image = "farming_salt.png", + wield_image = "farming_salt.png", + drawtype = "plantlike", + visual_scale = 0.8, + paramtype = "light", + tiles = {"farming_salt.png"}, + groups = {food_salt = 1, vessel = 1, dig_immediate = 3, + attached_node = 1}, + sounds = default.node_sound_defaults(), + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, +}) + +minetest.register_craft({ + type = "cooking", + cooktime = 15, + output = "farming:salt", + recipe = "bucket:bucket_water", + replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}} +}) + +--= Rose Water + +minetest.register_node("farming:rose_water", { + description = ("Rose Water"), + inventory_image = "farming_rose_water.png", + wield_image = "farming_rose_water.png", + drawtype = "plantlike", + visual_scale = 0.8, + paramtype = "light", + tiles = {"farming_rose_water.png"}, + groups = {food_rose_water = 1, vessel = 1, dig_immediate = 3, + attached_node = 1}, + sounds = default.node_sound_defaults(), + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, +}) + +minetest.register_craft({ + output = "farming:rose_water", + recipe = { + {"flowers:rose", "flowers:rose", "flowers:rose"}, + {"flowers:rose", "flowers:rose", "flowers:rose"}, + {"bucket:bucket_water", "group:food_pot", "vessels:glass_bottle"}, + }, + replacements = { + {"bucket:bucket_water", "bucket:bucket_empty"}, + {"group:food_pot", "farming:pot"}, + } +}) + +--= Turkish Delight + +minetest.register_craftitem("farming:turkish_delight", { + description = S("Turkish Delight"), + inventory_image = "farming_turkish_delight.png", + groups = {flammable = 3}, + on_use = minetest.item_eat(2), +}) + +minetest.register_craft({ + output = "farming:turkish_delight 4", + recipe = { + {"group:food_gelatin", "group:food_sugar", "group:food_gelatin"}, + {"group:food_sugar", "group:food_rose_water", "group:food_sugar"}, + {"group:food_cornstarch", "group:food_sugar", "dye:pink"}, + }, + replacements = { + {"group:food_cornstarch", "farming:bowl"}, + {"group:food_rose_water", "vessels:glass_bottle"}, + }, +}) + +--= Garlic Bread + +minetest.register_craftitem("farming:garlic_bread", { + description = S("Garlic Bread"), + inventory_image = "farming_garlic_bread.png", + groups = {flammable = 3}, + on_use = minetest.item_eat(2), +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:garlic_bread", + recipe = {"group:food_toast", "group:food_garlic_clove", "group:food_garlic_clove"}, +}) + +--= Donuts (thanks to Bockwurst for making the donut images) + +minetest.register_craftitem("farming:donut", { + description = S("Donut"), + inventory_image = "farming_donut.png", + on_use = minetest.item_eat(4), +}) + +minetest.register_craft({ + output = "farming:donut 3", + recipe = { + {"", "group:food_wheat", ""}, + {"group:food_wheat", "group:food_sugar", "group:food_wheat"}, + {"", "group:food_wheat", ""}, + } +}) + +minetest.register_craftitem("farming:donut_chocolate", { + description = S("Chocolate Donut"), + inventory_image = "farming_donut_chocolate.png", + on_use = minetest.item_eat(6), +}) + +minetest.register_craft({ + output = "farming:donut_chocolate", + recipe = { + {"group:food_cocoa"}, + {"farming:donut"}, + } +}) + +minetest.register_craftitem("farming:donut_apple", { + description = S("Apple Donut"), + inventory_image = "farming_donut_apple.png", + on_use = minetest.item_eat(6), +}) + +minetest.register_craft({ + output = "farming:donut_apple", + recipe = { + {"default:apple"}, + {"farming:donut"}, + } +}) + +--= Porridge Oats + +minetest.register_craftitem("farming:porridge", { + description = S("Porridge"), + inventory_image = "farming_porridge.png", + on_use = minetest.item_eat(6, "farming:bowl"), +}) + +minetest.after(0, function() + + local fluid = "bucket:bucket_water" + local fluid_return = "bucket:bucket_water" + + if minetest.get_modpath("mobs") and mobs and mobs.mod == "redo" then + fluid = "group:food_milk" + fluid_return = "mobs:bucket_milk" + end + + minetest.register_craft({ + type = "shapeless", + output = "farming:porridge", + recipe = { + "group:food_barley", "group:food_barley", "group:food_wheat", + "group:food_wheat", "group:food_bowl", fluid + }, + replacements = {{fluid_return, "bucket:bucket_empty"}} + }) + + minetest.register_craft({ + type = "shapeless", + output = "farming:porridge", + recipe = { + "group:food_oats", "group:food_oats", "group:food_oats", + "group:food_oats", "group:food_bowl", fluid + }, + replacements = {{fluid_return, "bucket:bucket_empty"}} + }) +end) + +--= Jaffa Cake + +minetest.register_craftitem("farming:jaffa_cake", { + description = S("Jaffa Cake"), + inventory_image = "farming_jaffa_cake.png", + on_use = minetest.item_eat(6), +}) + +minetest.register_craft({ + type = "shapeless", + output = "farming:jaffa_cake", + recipe = { + "farming:baking_tray", "group:food_egg", "group:food_sugar", + "group:food_flour", "group:food_cocoa", "group:food_orange", + "group:food_milk" + }, + replacements = { + {"farming:baking_tray", "farming:baking_tray"}, + {"mobs:bucket_milk", "bucket:bucket_empty"} + } +}) diff --git a/mods/farming/grass.lua b/mods/farming/grass.lua new file mode 100644 index 0000000..6a9e94f --- /dev/null +++ b/mods/farming/grass.lua @@ -0,0 +1,46 @@ + +for i = 4, 5 do + + -- Override default grass and have it drop Wheat Seeds + + minetest.override_item("default:grass_" .. i, { + drop = { + max_items = 1, + items = { + {items = {"farming:seed_wheat"}, rarity = 5}, + {items = {"farming:seed_oat"},rarity = 5}, + {items = {"default:grass_1"}}, + } + }, + }) + + -- Override default dry grass and have it drop Barley Seeds + + if minetest.registered_nodes["default:dry_grass_1"] then + + minetest.override_item("default:dry_grass_" .. i, { + drop = { + max_items = 1, + items = { + {items = {"farming:seed_barley"}, rarity = 5}, + {items = {"farming:seed_rye"},rarity = 5}, + {items = {"default:dry_grass_1"}}, + } + }, + }) + end + +end + +-- Override default Jungle Grass and have it drop Cotton Seeds + +minetest.override_item("default:junglegrass", { + drop = { + max_items = 1, + items = { + {items = {"farming:seed_cotton"}, rarity = 8}, + {items = {"farming:seed_rice"},rarity = 8}, + {items = {"default:junglegrass"}}, + } + }, +}) diff --git a/mods/farming/hoes.lua b/mods/farming/hoes.lua new file mode 100644 index 0000000..9f0af8e --- /dev/null +++ b/mods/farming/hoes.lua @@ -0,0 +1,355 @@ + +local S = farming.intllib +local tr = minetest.get_modpath("toolranks") + +-- Hoe registration function + +farming.register_hoe = function(name, def) + + -- Check for : prefix (register new hoes in your mod's namespace) + if name:sub(1,1) ~= ":" then + name = ":" .. name + end + + -- Check def table + if def.description == nil then + def.description = S("Hoe") + end + + if def.inventory_image == nil then + def.inventory_image = "unknown_item.png" + end + + if def.max_uses == nil then + def.max_uses = 30 + end + + -- add hoe group + def.groups = def.groups or {} + def.groups.hoe = 1 + + -- Register the tool + minetest.register_tool(name, { + description = def.description, + inventory_image = def.inventory_image, + on_use = function(itemstack, user, pointed_thing) + return farming.hoe_on_use(itemstack, user, pointed_thing, def.max_uses) + end, + groups = def.groups, + sound = {breaks = "default_tool_breaks"}, + }) + + -- Register its recipe + if def.recipe then + minetest.register_craft({ + output = name:sub(2), + recipe = def.recipe + }) + elseif def.material then + minetest.register_craft({ + output = name:sub(2), + recipe = { + {def.material, def.material, ""}, + {"", "group:stick", ""}, + {"", "group:stick", ""} + } + }) + end +end + +-- Turns dirt with group soil=1 into soil + +function farming.hoe_on_use(itemstack, user, pointed_thing, uses) + local pt = pointed_thing + -- check if pointing at a node + if not pt or pt.type ~= "node" then + return + end + local under = minetest.get_node(pt.under) + local upos = pointed_thing.under + if minetest.is_protected(upos, user:get_player_name()) then + minetest.record_protection_violation(upos, user:get_player_name()) + return + end + local p = {x = pt.under.x, y = pt.under.y + 1, z = pt.under.z} + local above = minetest.get_node(p) + -- return if any of the nodes is not registered + if not minetest.registered_nodes[under.name] + or not minetest.registered_nodes[above.name] then + return + end + -- check if the node above the pointed thing is air + if above.name ~= "air" then + return + end + -- check if pointing at dirt + if minetest.get_item_group(under.name, "soil") ~= 1 then + return + end + -- turn the node into soil, wear out item and play sound + minetest.set_node(pt.under, {name = "farming:soil"}) + minetest.sound_play("default_dig_crumbly", {pos = pt.under, gain = 0.5}) + local wear = 65535 / (uses -1) + if farming.is_creative(user:get_player_name()) then + if tr then + wear = 1 + else + wear = 0 + end + end + if tr then + itemstack = toolranks.new_afteruse(itemstack, user, under, {wear = wear}) + else + itemstack:add_wear(wear) + end + return itemstack +end + +-- Define Hoes + +farming.register_hoe(":farming:hoe_wood", { + description = S("Wooden Hoe"), + inventory_image = "farming_tool_woodhoe.png", + max_uses = 30, + material = "group:wood" +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:hoe_wood", + burntime = 5, +}) + +farming.register_hoe(":farming:hoe_stone", { + description = S("Stone Hoe"), + inventory_image = "farming_tool_stonehoe.png", + max_uses = 90, + material = "group:stone" +}) + +farming.register_hoe(":farming:hoe_steel", { + description = S("Steel Hoe"), + inventory_image = "farming_tool_steelhoe.png", + max_uses = 200, + material = "default:steel_ingot" +}) + +farming.register_hoe(":farming:hoe_bronze", { + description = S("Bronze Hoe"), + inventory_image = "farming_tool_bronzehoe.png", + max_uses = 500, + groups = {not_in_creative_inventory = 1}, +}) + +farming.register_hoe(":farming:hoe_mese", { + description = S("Mese Hoe"), + inventory_image = "farming_tool_mesehoe.png", + max_uses = 350, + groups = {not_in_creative_inventory = 1}, +}) + +farming.register_hoe(":farming:hoe_diamond", { + description = S("Diamond Hoe"), + inventory_image = "farming_tool_diamondhoe.png", + max_uses = 500, + groups = {not_in_creative_inventory = 1}, +}) + +-- hoe bomb function +local function hoe_area(pos, player) + -- check for protection + if minetest.is_protected(pos, player:get_player_name()) then + minetest.record_protection_violation(pos, player:get_player_name()) + return + end + local r = 5 -- radius + -- remove flora (grass, flowers etc.) + local res = minetest.find_nodes_in_area( + {x = pos.x - r, y = pos.y - 1, z = pos.z - r}, + {x = pos.x + r, y = pos.y + 2, z = pos.z + r}, + {"group:flora"}) + for n = 1, #res do + minetest.swap_node(res[n], {name = "air"}) + end + -- replace dirt with tilled soil + res = nil + res = minetest.find_nodes_in_area_under_air( + {x = pos.x - r, y = pos.y - 1, z = pos.z - r}, + {x = pos.x + r, y = pos.y + 2, z = pos.z + r}, + {"group:soil"}) + for n = 1, #res do + minetest.swap_node(res[n], {name = "farming:soil"}) + end +end + + +-- throwable hoe bomb +minetest.register_entity("farming:hoebomb_entity", { + physical = true, + visual = "sprite", + visual_size = {x = 1.0, y = 1.0}, + textures = {"farming_hoe_bomb.png"}, + collisionbox = {0,0,0,0,0,0}, + lastpos = {}, + player = "", + on_step = function(self, dtime) + if not self.player then + self.object:remove() + return + end + local pos = self.object:get_pos() + if self.lastpos.x ~= nil then + local vel = self.object:getvelocity() + -- only when potion hits something physical + if vel.x == 0 + or vel.y == 0 + or vel.z == 0 then + if self.player ~= "" then + -- round up coords to fix glitching through doors + self.lastpos = vector.round(self.lastpos) + hoe_area(self.lastpos, self.player) + end + self.object:remove() + return + end + end + self.lastpos = pos + end +}) + + +-- actual throwing function +local function throw_potion(itemstack, player) + local playerpos = player:get_pos() + local obj = minetest.add_entity({ + x = playerpos.x, + y = playerpos.y + 1.5, + z = playerpos.z + }, "farming:hoebomb_entity") + local dir = player:get_look_dir() + local velocity = 20 + obj:setvelocity({ + x = dir.x * velocity, + y = dir.y * velocity, + z = dir.z * velocity + }) + obj:setacceleration({ + x = dir.x * -3, + y = -9.5, + z = dir.z * -3 + }) + obj:get_luaentity().player = player +end + + +-- hoe bomb item +minetest.register_craftitem("farming:hoe_bomb", { + description = S("Hoe Bomb (use or throw on grassy areas to hoe land"), + inventory_image = "farming_hoe_bomb.png", + groups = {flammable = 2, not_in_creative_inventory = 1}, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + hoe_area(pointed_thing.above, user) + else + throw_potion(itemstack, user) + if not farming.is_creative(user:get_player_name()) then + itemstack:take_item() + return itemstack + end + end + end, +}) + +-- Mithril Scythe (special item) + +farming.scythe_not_drops = {"farming:trellis", "farming:beanpole"} + +farming.add_to_scythe_not_drops = function(item) + table.insert(farming.scythe_not_drops, item) +end + +minetest.register_tool("farming:scythe", { + description = "Scythe (Use to harvest and replant crops)", + inventory_image = "farming_scythe.png", + sound = {breaks = "default_tool_breaks"}, + on_use = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return + end + local pos = pointed_thing.under + local name = placer:get_player_name() + if minetest.is_protected(pos, name) then + return + end + local node = minetest.get_node_or_nil(pos) + if not node then + return + end + local def = minetest.registered_nodes[node.name] + if not def then + return + end + if not def.drop then + return + end + if not def.groups + or not def.groups.plant then + return + end + local drops = minetest.get_node_drops(node.name, "") + if not drops + or #drops == 0 + or (#drops == 1 and drops[1] == "") then + return + end + -- get crop name + local mname = node.name:split(":")[1] + local pname = node.name:split(":")[2] + local sname = tonumber(pname:split("_")[2]) + pname = pname:split("_")[1] + if not sname then + return + end + -- add dropped items + for _, dropped_item in pairs(drops) do + -- dont drop items on this list + for _, not_item in pairs(farming.scythe_not_drops) do + if dropped_item == not_item then + dropped_item = nil + end + end + if dropped_item then + local player_inv = placer:get_inventory() + if player_inv:room_for_item('main', dropped_item) then + player_inv:add_item('main', dropped_item) + else + local obj = minetest.add_item(pos, dropped_item) + if obj then + obj:set_velocity({ + x = math.random(-10, 10) / 9, + y = 3, + z = math.random(-10, 10) / 9, + }) + end + end + end + end + -- Run script hook + for _, callback in pairs(core.registered_on_dignodes) do + callback(pos, node, placer) + end + -- play sound + minetest.sound_play("default_grass_footstep", {pos = pos, gain = 1.0}) + local replace = mname .. ":" .. pname .. "_1" + if minetest.registered_nodes[replace] then + local p2 = minetest.registered_nodes[replace].place_param2 or 1 + minetest.set_node(pos, {name = replace, param2 = p2}) + else + minetest.set_node(pos, {name = "air"}) + end + if not farming.is_creative(name) then + itemstack:add_wear(65535 / 150) -- 150 uses + return itemstack + end + end, +}) diff --git a/mods/farming/init.lua b/mods/farming/init.lua new file mode 100644 index 0000000..1b89817 --- /dev/null +++ b/mods/farming/init.lua @@ -0,0 +1,693 @@ +--[[ + Farming Redo Mod + by TenPlus1 + NEW growing routine by prestidigitator + auto-refill by crabman77 +]] + +farming = { + mod = "redo", + version = "20191202", + path = minetest.get_modpath("farming"), + select = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5} + }, + registered_plants = {} +} + + +local creative_mode_cache = minetest.settings:get_bool("creative_mode") + +function farming.is_creative(name) + return creative_mode_cache or minetest.check_player_privs(name, {creative = true}) +end + + +local statistics = dofile(farming.path .. "/statistics.lua") + +-- Intllib +local S = dofile(farming.path .. "/intllib.lua") +farming.intllib = S + + +-- Utility Function +local time_speed = tonumber(minetest.settings:get("time_speed")) or 72 +local SECS_PER_CYCLE = (time_speed > 0 and (24 * 60 * 60) / time_speed) or 0 +local function clamp(x, min, max) + return (x < min and min) or (x > max and max) or x +end + + +-- return amount of day or night that has elapsed +-- dt is time elapsed, count_day if true counts day, otherwise night +local function day_or_night_time(dt, count_day) + + local t_day = minetest.get_timeofday() + local t1_day = t_day - dt / SECS_PER_CYCLE + local t1_c, t2_c -- t1_c < t2_c and t2_c always in [0, 1) + + if count_day then + + if t_day < 0.25 then + t1_c = t1_day + 0.75 -- Relative to sunup, yesterday + t2_c = t_day + 0.75 + else + t1_c = t1_day - 0.25 -- Relative to sunup, today + t2_c = t_day - 0.25 + end + else + if t_day < 0.75 then + t1_c = t1_day + 0.25 -- Relative to sundown, yesterday + t2_c = t_day + 0.25 + else + t1_c = t1_day - 0.75 -- Relative to sundown, today + t2_c = t_day - 0.75 + end + end + + local dt_c = clamp(t2_c, 0, 0.5) - clamp(t1_c, 0, 0.5) -- this cycle + + if t1_c < -0.5 then + local nc = math.floor(-t1_c) + t1_c = t1_c + nc + dt_c = dt_c + 0.5 * nc + clamp(-t1_c - 0.5, 0, 0.5) + end + + return dt_c * SECS_PER_CYCLE +end + + +-- Growth Logic +local STAGE_LENGTH_AVG = 160.0 +local STAGE_LENGTH_DEV = STAGE_LENGTH_AVG / 6 + + +-- return plant name and stage from node provided +local function plant_name_stage(node) + + local name + + if type(node) == "table" then + + if node.name then + name = node.name + elseif node.x and node.y and node.z then + node = minetest.get_node_or_nil(node) + name = node and node.name + end + else + name = tostring(node) + end + + if not name or name == "ignore" then + return nil + end + + local sep_pos = name:find("_[^_]+$") + + if sep_pos and sep_pos > 1 then + + local stage = tonumber(name:sub(sep_pos + 1)) + + if stage and stage >= 0 then + return name:sub(1, sep_pos - 1), stage + end + end + + return name, 0 +end + + +-- Map from node name to +-- { plant_name = ..., name = ..., stage = n, stages_left = { node_name, ... } } + +local plant_stages = {} + +farming.plant_stages = plant_stages + +--- Registers the stages of growth of a (possible plant) node. + -- + -- @param node + -- Node or position table, or node name. + -- @return + -- The (possibly zero) number of stages of growth the plant will go through + -- before being fully grown, or nil if not a plant. + +local register_plant_node + +-- Recursive helper +local function reg_plant_stages(plant_name, stage, force_last) + + local node_name = plant_name and plant_name .. "_" .. stage + local node_def = node_name and minetest.registered_nodes[node_name] + + if not node_def then + return nil + end + + local stages = plant_stages[node_name] + + if stages then + return stages + end + + if minetest.get_item_group(node_name, "growing") > 0 then + + local ns = reg_plant_stages(plant_name, stage + 1, true) + local stages_left = (ns and { ns.name, unpack(ns.stages_left) }) or {} + + stages = { + plant_name = plant_name, + name = node_name, + stage = stage, + stages_left = stages_left + } + + if #stages_left > 0 then + + local old_constr = node_def.on_construct + local old_destr = node_def.on_destruct + + minetest.override_item(node_name, + { + on_construct = function(pos) + + if old_constr then + old_constr(pos) + end + + farming.handle_growth(pos) + end, + + on_destruct = function(pos) + + minetest.get_node_timer(pos):stop() + + if old_destr then + old_destr(pos) + end + end, + + on_timer = function(pos, elapsed) + return farming.plant_growth_timer(pos, elapsed, node_name) + end, + }) + end + + elseif force_last then + + stages = { + plant_name = plant_name, + name = node_name, + stage = stage, + stages_left = {} + } + else + return nil + end + + plant_stages[node_name] = stages + + return stages +end + + +local register_plant_node = function(node) + + local plant_name, stage = plant_name_stage(node) + + if plant_name then + + local stages = reg_plant_stages(plant_name, stage, false) + return stages and #stages.stages_left + else + return nil + end +end + + +local function set_growing(pos, stages_left) + + if not stages_left then + return + end + + local timer = minetest.get_node_timer(pos) + + if stages_left > 0 then + + if not timer:is_started() then + + local stage_length = statistics.normal(STAGE_LENGTH_AVG, STAGE_LENGTH_DEV) + + stage_length = clamp(stage_length, 0.5 * STAGE_LENGTH_AVG, 3.0 * STAGE_LENGTH_AVG) + + timer:set(stage_length, -0.5 * math.random() * STAGE_LENGTH_AVG) + end + + elseif timer:is_started() then + timer:stop() + end +end + + +-- detects a crop at given position, starting or stopping growth timer when needed +function farming.handle_growth(pos, node) + + if not pos then + return + end + + local stages_left = register_plant_node(node or pos) + + if stages_left then + set_growing(pos, stages_left) + end +end + + +minetest.after(0, function() + + for _, node_def in pairs(minetest.registered_nodes) do + register_plant_node(node_def) + end +end) + + +-- Just in case a growing type or added node is missed (also catches existing +-- nodes added to map before timers were incorporated). +minetest.register_abm({ + nodenames = {"group:growing"}, + interval = 300, + chance = 1, + catch_up = false, + action = function(pos, node) + farming.handle_growth(pos, node) + end +}) + + +-- Plant timer function that grows plants under the right conditions. +function farming.plant_growth_timer(pos, elapsed, node_name) + + local stages = plant_stages[node_name] + + if not stages then + return false + end + + local max_growth = #stages.stages_left + + if max_growth <= 0 then + return false + end + + -- custom growth check + local chk = minetest.registered_nodes[node_name].growth_check + + if chk then + + if chk(pos, node_name) then + return true + end + + -- otherwise check for wet soil beneath crop + else + local under = minetest.get_node({ x = pos.x, y = pos.y - 1, z = pos.z }) + + if minetest.get_item_group(under.name, "soil") < 3 then + return true + end + end + + local growth + local light_pos = {x = pos.x, y = pos.y, z = pos.z} + local lambda = elapsed / STAGE_LENGTH_AVG + + if lambda < 0.1 then + return true + end + + local MIN_LIGHT = minetest.registered_nodes[node_name].minlight or 12 + local MAX_LIGHT = minetest.registered_nodes[node_name].maxlight or 15 + --print ("---", MIN_LIGHT, MAX_LIGHT) + + if max_growth == 1 or lambda < 2.0 then + + local light = (minetest.get_node_light(light_pos) or 0) + --print ("light level:", light) + + if light < MIN_LIGHT or light > MAX_LIGHT then + return true + end + + growth = 1 + else + local night_light = (minetest.get_node_light(light_pos, 0) or 0) + local day_light = (minetest.get_node_light(light_pos, 0.5) or 0) + local night_growth = night_light >= MIN_LIGHT and night_light <= MAX_LIGHT + local day_growth = day_light >= MIN_LIGHT and day_light <= MAX_LIGHT + + if not night_growth then + + if not day_growth then + return true + end + + lambda = day_or_night_time(elapsed, true) / STAGE_LENGTH_AVG + + elseif not day_growth then + + lambda = day_or_night_time(elapsed, false) / STAGE_LENGTH_AVG + end + + growth = statistics.poisson(lambda, max_growth) + + if growth < 1 then + return true + end + end + + if minetest.registered_nodes[stages.stages_left[growth]] then + + local p2 = minetest.registered_nodes[stages.stages_left[growth] ].place_param2 or 1 + + minetest.swap_node(pos, {name = stages.stages_left[growth], param2 = p2}) + else + return true + end + + return growth ~= max_growth +end + + +-- refill placed plant by crabman (26/08/2015) updated by TenPlus1 +function farming.refill_plant(player, plantname, index) + + local inv = player:get_inventory() + local old_stack = inv:get_stack("main", index) + + if old_stack:get_name() ~= "" then + return + end + + for i, stack in ipairs(inv:get_list("main")) do + + if stack:get_name() == plantname and i ~= index then + + inv:set_stack("main", index, stack) + stack:clear() + inv:set_stack("main", i, stack) + + return + end + end +end + + +-- Place Seeds on Soil +function farming.place_seed(itemstack, placer, pointed_thing, plantname) + + local pt = pointed_thing + + -- check if pointing at a node + if not pt or pt.type ~= "node" then + return + end + + local under = minetest.get_node(pt.under) + + -- am I right-clicking on something that has a custom on_place set? + -- thanks to Krock for helping with this issue :) + local def = minetest.registered_nodes[under.name] + if placer and itemstack and def and def.on_rightclick then + return def.on_rightclick(pt.under, under, placer, itemstack) + end + + local above = minetest.get_node(pt.above) + + -- check if pointing at the top of the node + if pt.above.y ~= pt.under.y + 1 then + return + end + + -- return if any of the nodes is not registered + if not minetest.registered_nodes[under.name] + or not minetest.registered_nodes[above.name] then + return + end + + -- can I replace above node, and am I pointing at soil + if not minetest.registered_nodes[above.name].buildable_to + or minetest.get_item_group(under.name, "soil") < 2 + -- avoid multiple seed placement bug + or minetest.get_item_group(above.name, "plant") ~= 0 then + return + end + + -- is player planting seed? + local name = placer and placer:get_player_name() or "" + + -- if not protected then add node and remove 1 item from the itemstack + if not minetest.is_protected(pt.above, name) then + + local p2 = minetest.registered_nodes[plantname].place_param2 or 1 + + minetest.set_node(pt.above, {name = plantname, param2 = p2}) + +--minetest.get_node_timer(pt.above):start(1) +--farming.handle_growth(pt.above)--, node) + + minetest.sound_play("default_place_node", {pos = pt.above, gain = 1.0}) + + if placer and itemstack + and not farming.is_creative(placer:get_player_name()) then + + local name = itemstack:get_name() + + itemstack:take_item() + + -- check for refill + if itemstack:get_count() == 0 then + + minetest.after(0.10, + farming.refill_plant, + placer, + name, + placer:get_wield_index() + ) + end + end + + return itemstack + end +end + + +-- Function to register plants (default farming compatibility) +farming.register_plant = function(name, def) + + if not def.steps then + return nil + end + + local mname = name:split(":")[1] + local pname = name:split(":")[2] + + -- Check def + def.description = def.description or S("Seed") + def.inventory_image = def.inventory_image or "unknown_item.png" + def.minlight = def.minlight or 12 + def.maxlight = def.maxlight or 15 + + -- Register seed + minetest.register_node(":" .. mname .. ":seed_" .. pname, { + + description = def.description, + tiles = {def.inventory_image}, + inventory_image = def.inventory_image, + wield_image = def.inventory_image, + drawtype = "signlike", + groups = {seed = 1, snappy = 3, attached_node = 1, flammable = 2}, + paramtype = "light", + paramtype2 = "wallmounted", + walkable = false, + sunlight_propagates = true, + selection_box = farming.select, + place_param2 = def.place_param2 or nil, + next_plant = mname .. ":" .. pname .. "_1", + + on_place = function(itemstack, placer, pointed_thing) + return farming.place_seed(itemstack, placer, + pointed_thing, mname .. ":" .. pname .. "_1") + end, + }) + + -- Register harvest + minetest.register_craftitem(":" .. mname .. ":" .. pname, { + description = pname:gsub("^%l", string.upper), + inventory_image = mname .. "_" .. pname .. ".png", + groups = def.groups or {flammable = 2}, + }) + + -- Register growing steps + for i = 1, def.steps do + + local base_rarity = 1 + if def.steps ~= 1 then + base_rarity = 8 - (i - 1) * 7 / (def.steps - 1) + end + local drop = { + items = { + {items = {mname .. ":" .. pname}, rarity = base_rarity}, + {items = {mname .. ":" .. pname}, rarity = base_rarity * 2}, + {items = {mname .. ":seed_" .. pname}, rarity = base_rarity}, + {items = {mname .. ":seed_" .. pname}, rarity = base_rarity * 2}, + } + } + + local g = { + snappy = 3, flammable = 2, plant = 1, growing = 1, + attached_node = 1, not_in_creative_inventory = 1, + } + + -- Last step doesn't need growing=1 so Abm never has to check these + if i == def.steps then + g.growing = 0 + end + + local node_name = mname .. ":" .. pname .. "_" .. i + + local next_plant = nil + + if i < def.steps then + next_plant = mname .. ":" .. pname .. "_" .. (i + 1) + end + + minetest.register_node(node_name, { + drawtype = "plantlike", + waving = 1, + tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"}, + paramtype = "light", + paramtype2 = def.paramtype2, + place_param2 = def.place_param2, + walkable = false, + buildable_to = true, + sunlight_propagates = true, + drop = drop, + selection_box = farming.select, + groups = g, + sounds = default.node_sound_leaves_defaults(), + minlight = def.minlight, + maxlight = def.maxlight, + next_plant = next_plant, + }) + end + +-- add to farming.registered_plants +farming.registered_plants[mname .. ":" .. pname] = { + crop = mname .. ":" .. pname, + seed = mname .. ":seed_" .. pname, + steps = def.steps, + minlight = def.minlight, + maxlight = def.maxlight +} +--print(dump(farming.registered_plants[mname .. ":" .. pname])) + -- Return info + return {seed = mname .. ":seed_" .. pname, harvest = mname .. ":" .. pname} +end + + +-- default settings +farming.carrot = 0.001 +farming.potato = 0.001 +farming.tomato = 0.001 +farming.cucumber = 0.001 +farming.corn = 0.001 +farming.coffee = 0.001 +farming.melon = 0.001 +farming.pumpkin = 0.001 +farming.cocoa = true +farming.raspberry = 0.001 +farming.blueberry = 0.001 +farming.rhubarb = 0.001 +farming.beans = 0.001 +farming.grapes = 0.001 +farming.barley = true +farming.chili = 0.003 +farming.hemp = 0.003 +farming.garlic = 0.001 +farming.onion = 0.001 +farming.pepper = 0.002 +farming.pineapple = 0.001 +farming.peas = 0.001 +farming.beetroot = 0.001 +farming.grains = true +farming.rarety = 0.002 + + +-- Load new global settings if found inside mod folder +local input = io.open(farming.path.."/farming.conf", "r") +if input then + dofile(farming.path .. "/farming.conf") + input:close() +end + +-- load new world-specific settings if found inside world folder +local worldpath = minetest.get_worldpath() +input = io.open(worldpath.."/farming.conf", "r") +if input then + dofile(worldpath .. "/farming.conf") + input:close() +end + + +-- important items +dofile(farming.path.."/soil.lua") +dofile(farming.path.."/hoes.lua") +dofile(farming.path.."/grass.lua") +dofile(farming.path.."/utensils.lua") + +-- default crops +dofile(farming.path.."/crops/wheat.lua") +dofile(farming.path.."/crops/cotton.lua") + + +-- helper function +local function ddoo(file, check) + + if check then + dofile(farming.path .. "/crops/" .. file) + end +end + +-- add additional crops and food (if enabled) +ddoo("carrot.lua", farming.carrot) +ddoo("potato.lua", farming.potato) +ddoo("tomato.lua", farming.tomato) +ddoo("cucumber.lua", farming.cucumber) +ddoo("corn.lua", farming.corn) +ddoo("coffee.lua", farming.coffee) +ddoo("melon.lua", farming.melon) +ddoo("pumpkin.lua", farming.pumpkin) +ddoo("cocoa.lua", farming.cocoa) +ddoo("raspberry.lua", farming.raspberry) +ddoo("blueberry.lua", farming.blueberry) +ddoo("rhubarb.lua", farming.rhubarb) +ddoo("beans.lua", farming.beans) +ddoo("grapes.lua", farming.grapes) +ddoo("barley.lua", farming.barley) +ddoo("hemp.lua", farming.hemp) +ddoo("garlic.lua", farming.garlic) +ddoo("onion.lua", farming.onion) +ddoo("pepper.lua", farming.pepper) +ddoo("pineapple.lua", farming.pineapple) +ddoo("peas.lua", farming.peas) +ddoo("beetroot.lua", farming.beetroot) +ddoo("chili.lua", farming.chili) +ddoo("ryeoatrice.lua", farming.grains) + +dofile(farming.path.."/food.lua") +dofile(farming.path.."/mapgen.lua") +dofile(farming.path.."/compatibility.lua") -- Farming Plus compatibility diff --git a/mods/farming/intllib.lua b/mods/farming/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mods/farming/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mods/farming/license.txt b/mods/farming/license.txt new file mode 100644 index 0000000..8584871 --- /dev/null +++ b/mods/farming/license.txt @@ -0,0 +1,144 @@ +The MIT License (MIT) + +Copyright (c) 2016 TenPlus1 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +License of media (textures): +---------------------------- +Created by PilzAdam (License: CC BY 3.0): + farming_bread.png + farming_soil.png + farming_soil_wet.png + farming_soil_wet_side.png + farming_string.png + +Created by Napiophelios (CC BY-SA 3.0): + farming_cotton.png + +Created by Calinou (License: CC BY-SA): + farming_tool_bronzehoe.png + farming_tool_steelhoe.png + farming_tool_stonehoe.png + farming_tool_woodhoe.png + farming_tool_mesehoe.png + farming_tool_diamondhoe.png + +Created by VanessaE (License: CC BY 3.0): + farming_cotton_seed.png + farming_wheat_seed.png + farming_flour.png + farming_wheat.png + farming_wheat_1.png + farming_wheat_2.png + farming_wheat_3.png + farming_wheat_4.png + farming_wheat_5.png + farming_wheat_5.png + farming_wheat_7.png + farming_wheat_8.png + farming_cotton_1.png + farming_cotton_2.png + farming_cotton_3.png + farming_cotton_4.png + farming_cotton_5.png + farming_cotton_6.png + farming_cotton_7.png + farming_cotton_8.png + +Created by Doc (License: CC BY 3.0): + farming_cucumber.png + farming_cucumber_1.png + farming_cucumber_2.png + farming_cucumber_3.png + farming_cucumber_4.png + farming_potato.png + farming_potato_1.png + farming_potato_2.png + farming_potato_3.png + farming_potato_4.png + farming_raspberries.png + farming_raspberry_1.png + farming_raspberry_2.png + farming_raspberry_3.png + farming_raspberry_4.png + +Created by Gambit (License: CC BY 3.0): + default_junglegrass.png + farming_carrot.png + farming_carrot_1.png + farming_carrot_2.png + farming_carrot_3.png + farming_carrot_4.png + farming_carrot_5.png + farming_carrot_6.png + farming_carrot_7.png + farming_carrot_8.png + +Created by JoseTheCrafter and edited by TenPlus1 (CC BY 3.0): + farming_tomato.png + farming_tomato_1.png + farming_tomato_2.png + farming_tomato_3.png + farming_tomato_4.png + farming_tomato_5.png + farming_tomato_6.png + farming_tomato_7.png + farming_tomato_8.png + +Created by GeMinecraft and edited by TenPlus1 (CC BY 3.0): + farming_corn.png + farming_corn_cob.png + farming_corn_1.png + farming_corn_2.png + farming_corn_3.png + farming_corn_4.png + farming_corn_5.png + farming_corn_6.png + farming_corn_7.png + farming_corn_8.png + +Created by TenPlus1 (CC BY 3.0) + farming_cocoa_1.png + farming_cocoa_2.png + farming_cocoa_3.png + farming_cocoa_beans.png + farming_cookie.png + farming_raspberry_smoothie.png + farming_rhubarb_1.png + farming_rhubarb_2.png + farming_rhubarb_3.png + farming_rhubarb.png + farming_rhubarb_pie.png + farming_hemp*.png + +Created by ademant (CC-BY-3.0) + farming_rye*.png + farming_oat*.png + farming_rice*.png + +Created by PilzAdam and edited by SpaghettiToastBook (CC0): + farming_bread_multigrain.png + +Created by VanessaE and edited by SpaghettiToastBook (CC0): + farming_flour_multigrain.png + +Created by mDiyo (Natura), modified by TenPlus1 (License: CC BY-SA 3.0): + farming_barley.png diff --git a/mods/farming/locale/de.po b/mods/farming/locale/de.po new file mode 100644 index 0000000..731b31d --- /dev/null +++ b/mods/farming/locale/de.po @@ -0,0 +1,262 @@ +# German Translation for farming mod. +# Copyright (C) 2017 +# This file is distributed under the same license as the farming package. +# Xanthin. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 1.27\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-31 HO:MI+ZONE\n" +"PO-Revision-Date: 2016-03-31 HO:MI+ZONE\n" +"Last-Translator: Xanthin\n" +"Language-Team: \n" +"Language: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: barley.lua +msgid "Barley Seed" +msgstr "Gerstenkörner" + +#: barley.lua +msgid "Barley" +msgstr "Gerste" + +#: beanpole.lua +msgid "Green Beans" +msgstr "Grüne Bohnen" + +#: beanpole.lua +msgid "Bean Pole (place on soil before planting beans)" +msgstr "Bohnenstange (vor dem Pflanzen der Bohnen auf den\nAckerboden stellen)" + +#: blueberry.lua +msgid "Blueberries" +msgstr "Blaubeeren" + +#: blueberry.lua +msgid "Blueberry Muffin" +msgstr "Blaubeermuffin" + +#: carrot.lua +msgid "Carrot" +msgstr "Möhre" + +#: carrot.lua +msgid "Golden Carrot" +msgstr "Goldene Möhre" + +#: cocoa.lua +msgid "Cocoa Beans" +msgstr "Kakaobohne" + +#: cocoa.lua +msgid "Cookie" +msgstr "Keks" + +#: cocoa.lua +msgid "Bar of Dark Chocolate" +msgstr "Tafel Zartbitterschokolade" + +#: coffee.lua +msgid "Coffee Beans" +msgstr "Kaffeebohnen" + +#: coffee.lua +msgid "Drinking Cup (empty)" +msgstr "Tasse (leer)" + +#: coffee.lua +msgid "Cold Cup of Coffee" +msgstr "Kalte Tasse Kaffee" + +#: coffee.lua +msgid "Hot Cup of Coffee" +msgstr "Heiße Tasse Kaffee" + +#: corn.lua +msgid "Corn" +msgstr "Mais" + +#: corn.lua +msgid "Corn on the Cob" +msgstr "Maiskolben" + +#: corn.lua +msgid "Bottle of Ethanol" +msgstr "Flasche Ethanol" + +#: cotton.lua +msgid "Cotton Seed" +msgstr "Baumwollsamen" + +#: cotton.lua +msgid "Cotton" +msgstr "Baumwolle" + +#: cucumber.lua +msgid "Cucumber" +msgstr "Gurke" + +#: donut.lua +msgid "Donut" +msgstr "Donut" + +#: donut.lua +msgid "Chocolate Donut" +msgstr "Schokodonut" + +#: donut.lua +msgid "Apple Donut" +msgstr "Apfeldonut" + +#: grapes.lua +msgid "Grapes" +msgstr "Weintrauben" + +#: grapes.lua +msgid "Trellis (place on soil before planting grapes)" +msgstr "Spalier (vor dem Pflanzen der Weintrauben auf den\nAckerboden stellen)" + +#: hemp.lua +msgid "Hemp Seed" +msgstr "Hanfsamen" + +#: hemp.lua +msgid "Hemp Leaf" +msgstr "Hanfblatt" + +#: hemp.lua +msgid "Bottle of Hemp Oil" +msgstr "Flasche mit Hanföl" + +#: hemp.lua +msgid "Hemp Fibre" +msgstr "Hanffaser" + +#: hemp.lua +msgid "Hemp Rope" +msgstr "Hanfseil" + +#: hoes.lua +msgid "Hoe" +msgstr "Hacke" + +#: hoes.lua +msgid "Wooden Hoe" +msgstr "Holzhacke" + +#: hoes.lua +msgid "Stone Hoe" +msgstr "Steinhacke" + +#: hoes.lua +msgid "Steel Hoe" +msgstr "Stahlhacke" + +#: hoes.lua +msgid "Bronze Hoe" +msgstr "Bronzehacke" + +#: hoes.lua +msgid "Mese Hoe" +msgstr "Mesehacke" + +#: hoes.lua +msgid "Diamond Hoe" +msgstr "Diamanthacke" + +#: init.lua +msgid "Seed" +msgstr "Saatgut" + +#: melon.lua +msgid "Melon Slice" +msgstr "Melonenscheibe" + +#: melon.lua +msgid "Melon" +msgstr "Melone" + +#: potato.lua +msgid "Potato" +msgstr "Kartoffel" + +#: potato.lua +msgid "Baked Potato" +msgstr "Ofenkartoffel" + +#: pumpkin.lua +msgid "Pumpkin" +msgstr "Kürbis" + +#: pumpkin.lua +msgid "Pumpkin Slice" +msgstr "Kürbisscheibe" + +#: pumpkin.lua +msgid "Jack 'O Lantern (punch to turn on and off)" +msgstr "Kürbislaterne (Punch zum Ein- und Ausschalten)" + +#: pumpkin.lua +msgid "Pumpkin Bread" +msgstr "Kürbisbrot" + +#: pumpkin.lua +msgid "Pumpkin Dough" +msgstr "Kürbisteig" + +#: raspberry.lua +msgid "Raspberries" +msgstr "Himbeeren" + +#: raspberry.lua +msgid "Raspberry Smoothie" +msgstr "Himbeersmoothie" + +#: rhubarb.lua +msgid "Rhubarb" +msgstr "Rhabarber" + +#: rhubarb.lua +msgid "Rhubarb Pie" +msgstr "Rhabarberkuchen" + +#: soil.lua +msgid "Soil" +msgstr "Ackerboden" + +#: soil.lua +msgid "Wet Soil" +msgstr "Bewässerter Ackerboden" + +#: sugar.lua +msgid "Sugar" +msgstr "Zucker" + +#: tomato.lua +msgid "Tomato" +msgstr "Tomate" + +#: wheat.lua +msgid "Wheat Seed" +msgstr "Weizenkörner" + +#: wheat.lua +msgid "Wheat" +msgstr "Weizen" + +#: wheat.lua +msgid "Straw" +msgstr "Stroh" + +#: wheat.lua +msgid "Flour" +msgstr "Mehl" + +#: wheat.lua +msgid "Bread" +msgstr "Brot" diff --git a/mods/farming/locale/fr.po b/mods/farming/locale/fr.po new file mode 100644 index 0000000..7b50640 --- /dev/null +++ b/mods/farming/locale/fr.po @@ -0,0 +1,259 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-03-27 20:21+0200\n" +"PO-Revision-Date: 2018-03-27 22:16+0200\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.7.1\n" +"Last-Translator: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"Language: fr\n" + +#: barley.lua +msgid "Barley Seed" +msgstr "Graine d'orge" + +#: barley.lua +msgid "Barley" +msgstr "Orge" + +#: beanpole.lua +msgid "Green Beans" +msgstr "Haricots verts" + +#: beanpole.lua +msgid "Bean Pole (place on soil before planting beans)" +msgstr "Tuteur pour haricots (placer sur le sol avant de planter des haricots)" + +#: blueberry.lua +msgid "Blueberries" +msgstr "Myrtilles" + +#: blueberry.lua +msgid "Blueberry Muffin" +msgstr "Gâteau aux myrtilles" + +#: carrot.lua +msgid "Carrot" +msgstr "Carotte" + +#: carrot.lua +msgid "Golden Carrot" +msgstr "Carotte dorée" + +#: cocoa.lua +msgid "Cocoa Beans" +msgstr "Fèves de chocolat" + +#: cocoa.lua +msgid "Cookie" +msgstr "Biscuit" + +#: cocoa.lua +msgid "Bar of Dark Chocolate" +msgstr "Barre de chocolat noir" + +#: coffee.lua +msgid "Coffee Beans" +msgstr "Grains de café" + +#: coffee.lua +msgid "Drinking Cup (empty)" +msgstr "Tasse (vide)" + +#: coffee.lua +msgid "Cold Cup of Coffee" +msgstr "Tasse de café froid" + +#: coffee.lua +msgid "Hot Cup of Coffee" +msgstr "Tasse de café chaud" + +#: corn.lua +msgid "Corn" +msgstr "Maïs" + +#: corn.lua +msgid "Corn on the Cob" +msgstr "Épi de maïs" + +#: corn.lua +msgid "Bottle of Ethanol" +msgstr "Bouteille de'éthanol" + +#: cotton.lua +msgid "Cotton Seed" +msgstr "Graines de coton" + +#: cotton.lua +msgid "Cotton" +msgstr "Coton" + +#: cucumber.lua +msgid "Cucumber" +msgstr "Concombre" + +#: donut.lua +msgid "Donut" +msgstr "Beignet" + +#: donut.lua +msgid "Chocolate Donut" +msgstr "Beignet au chocolat" + +#: donut.lua +msgid "Apple Donut" +msgstr "Beignet aux pommes" + +#: grapes.lua +msgid "Grapes" +msgstr "Raisins" + +#: grapes.lua +msgid "Trellis (place on soil before planting grapes)" +msgstr "Treillis (placer sur le sol avant de planter les raisins)" + +#: hemp.lua +msgid "Hemp Seed" +msgstr "Graines de chanvre" + +#: hemp.lua +msgid "Hemp Leaf" +msgstr "Feuille de chanvre" + +#: hemp.lua +msgid "Bottle of Hemp Oil" +msgstr "Bouteille d'huile de chanvre" + +#: hemp.lua +msgid "Hemp Fibre" +msgstr "Fibre de chanvre" + +#: hemp.lua +msgid "Hemp Rope" +msgstr "Corde de chanvre" + +#: hoes.lua +msgid "Wooden Hoe" +msgstr "Houe en bois" + +#: hoes.lua +msgid "Stone Hoe" +msgstr "Houe en pierre" + +#: hoes.lua +msgid "Steel Hoe" +msgstr "Houe en acier" + +#: hoes.lua +msgid "Bronze Hoe" +msgstr "Houe en bronze" + +#: hoes.lua +msgid "Mese Hoe" +msgstr "Houe en mese" + +#: hoes.lua +msgid "Diamond Hoe" +msgstr "Houe en diamant" + +#: init.lua +msgid "Seed" +msgstr "Graine" + +#: melon.lua +msgid "Melon Slice" +msgstr "Tranche de melon" + +#: melon.lua +msgid "Melon" +msgstr "Melon" + +#: potato.lua +msgid "Potato" +msgstr "Pomme de terre" + +#: potato.lua +msgid "Baked Potato" +msgstr "Pomme de terre cuite" + +#: pumpkin.lua +msgid "Pumpkin" +msgstr "Citrouille" + +#: pumpkin.lua +msgid "Pumpkin Slice" +msgstr "Tranche de citrouille" + +#: pumpkin.lua +msgid "Jack 'O Lantern (punch to turn on and off)" +msgstr "Jack 'O Lantern (tapé pour allumer et éteindre)" + +#: pumpkin.lua +msgid "Pumpkin Bread" +msgstr "Pain à la citrouille" + +#: pumpkin.lua +msgid "Pumpkin Dough" +msgstr "Pâte à la citrouille" + +#: raspberry.lua +msgid "Raspberries" +msgstr "Framboises" + +#: raspberry.lua +msgid "Raspberry Smoothie" +msgstr "Smoothie aux framboises" + +#: rhubarb.lua +msgid "Rhubarb" +msgstr "Rhubarbe" + +#: rhubarb.lua +msgid "Rhubarb Pie" +msgstr "Tarte à la rhubarbe" + +#: soil.lua +msgid "Soil" +msgstr "Sol" + +#: soil.lua +msgid "Wet Soil" +msgstr "Sol humide" + +#: sugar.lua +msgid "Sugar" +msgstr "Sucre" + +#: tomato.lua +msgid "Tomato" +msgstr "Tomate" + +#: wheat.lua +msgid "Wheat Seed" +msgstr "Graine de blé" + +#: wheat.lua +msgid "Wheat" +msgstr "Blé" + +#: wheat.lua +msgid "Straw" +msgstr "Paille" + +#: wheat.lua +msgid "Flour" +msgstr "Farine" + +#: wheat.lua +msgid "Bread" +msgstr "Pain" diff --git a/mods/farming/locale/pt.po b/mods/farming/locale/pt.po new file mode 100644 index 0000000..bc4352f --- /dev/null +++ b/mods/farming/locale/pt.po @@ -0,0 +1,258 @@ +# Portuguese Translation for farming mod. +# Copyright (C) 2017 +# This file is distributed under the same license as the farming package. +# BrunoMine , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: 1.27\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-08-16 17:38-0300\n" +"PO-Revision-Date: 2017-08-17 17:01-0300\n" +"Last-Translator: BrunoMine \n" +"Language-Team: \n" +"Language: Portuguese\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Gtranslator 2.91.7\n" + +#: barley.lua +msgid "Barley Seed" +msgstr "Sementes de Cevada" + +#: barley.lua +msgid "Barley" +msgstr "Cevada" + +#: beanpole.lua +msgid "Green Beans" +msgstr "Feijoes Verdes" + +#: beanpole.lua +msgid "Bean Pole (place on soil before planting beans)" +msgstr "Apoio de feijao (coloque no solo antes de plantar feijao)" + +#: blueberry.lua +msgid "Blueberries" +msgstr "Mirtilos" + +#: blueberry.lua +msgid "Blueberry Muffin" +msgstr "Muffin de Mirtilos" + +#: carrot.lua +msgid "Carrot" +msgstr "Cenoura" + +#: carrot.lua +msgid "Golden Carrot" +msgstr "Cenoura Dourada" + +#: cocoa.lua +msgid "Cocoa Beans" +msgstr "Amendoas de Cacau" + +#: cocoa.lua +msgid "Cookie" +msgstr "Cookie" + +#: cocoa.lua +msgid "Bar of Dark Chocolate" +msgstr "Barra de Chocolate Preto" + +#: coffee.lua +msgid "Coffee Beans" +msgstr "Grao de Cafe" + +#: coffee.lua +msgid "Drinking Cup (empty)" +msgstr "Xicara (vazia)" + +#: coffee.lua +msgid "Cold Cup of Coffee" +msgstr "Xicara de Cafe Frio" + +#: coffee.lua +msgid "Hot Cup of Coffee" +msgstr "Xicara de Cafe Quente" + +#: corn.lua +msgid "Corn" +msgstr "Milho" + +#: corn.lua +msgid "Corn on the Cob" +msgstr "Espiga de Milho" + +#: corn.lua +msgid "Bottle of Ethanol" +msgstr "Garrafa de Etanol" + +#: cotton.lua +msgid "Cotton Seed" +msgstr "Sementes de Algodao" + +#: cotton.lua +msgid "Cotton" +msgstr "Algodao" + +#: cucumber.lua +msgid "Cucumber" +msgstr "Pepino" + +#: donut.lua +msgid "Donut" +msgstr "Donut" + +#: donut.lua +msgid "Chocolate Donut" +msgstr "Donut de Chocolate" + +#: donut.lua +msgid "Apple Donut" +msgstr "Donut de Maça" + +#: grapes.lua +msgid "Grapes" +msgstr "Uvas" + +#: grapes.lua +msgid "Trellis (place on soil before planting grapes)" +msgstr "Grade de Ripas (colocar no solo antes de plantar uvas)" + +#: hemp.lua +msgid "Hemp Seed" +msgstr "Sementes de Canhamo" + +#: hemp.lua +msgid "Hemp Leaf" +msgstr "Folha de Canhamo" + +#: hemp.lua +msgid "Bottle of Hemp Oil" +msgstr "Garrafa de Oleo de Canhamo" + +#: hemp.lua +msgid "Hemp Fibre" +msgstr "Fibra de Canhamo" + +#: hemp.lua +msgid "Hemp Rope" +msgstr "Corda de Canhamo" + +#: hoes.lua +msgid "Wooden Hoe" +msgstr "Enxada de Madeira" + +#: hoes.lua +msgid "Stone Hoe" +msgstr "Enxada de Pedra" + +#: hoes.lua +msgid "Steel Hoe" +msgstr "Enxada de Aço" + +#: hoes.lua +msgid "Bronze Hoe" +msgstr "Enxada de Bronze" + +#: hoes.lua +msgid "Mese Hoe" +msgstr "Enxada de Mese" + +#: hoes.lua +msgid "Diamond Hoe" +msgstr "Enxada de Diamante" + +#: init.lua +msgid "Seed" +msgstr "Sementes" + +#: melon.lua +msgid "Melon Slice" +msgstr "Sementes de Melancia" + +#: melon.lua +msgid "Melon" +msgstr "Melancia" + +#: potato.lua +msgid "Potato" +msgstr "Batata" + +#: potato.lua +msgid "Baked Potato" +msgstr "Batata Cozida" + +#: pumpkin.lua +msgid "Pumpkin" +msgstr "Abobora" + +#: pumpkin.lua +msgid "Pumpkin Slice" +msgstr "Pedaço de Abobora" + +#: pumpkin.lua +msgid "Jack 'O Lantern (punch to turn on and off)" +msgstr "Jack 'O Lantern (Socos para ligar e desligar)" + +#: pumpkin.lua +msgid "Pumpkin Bread" +msgstr "Pao de Abobora" + +#: pumpkin.lua +msgid "Pumpkin Dough" +msgstr "Massa de Abobora" + +#: raspberry.lua +msgid "Raspberries" +msgstr "Framboesa" + +#: raspberry.lua +msgid "Raspberry Smoothie" +msgstr "Batida de Framboesa" + +#: rhubarb.lua +msgid "Rhubarb" +msgstr "Ruibarbo" + +#: rhubarb.lua +msgid "Rhubarb Pie" +msgstr "Torta de Ruibarbo" + +#: soil.lua +msgid "Soil" +msgstr "Solo" + +#: soil.lua +msgid "Wet Soil" +msgstr "Solo Seco" + +#: sugar.lua +msgid "Sugar" +msgstr "Açucar" + +#: tomato.lua +msgid "Tomato" +msgstr "Tomate" + +#: wheat.lua +msgid "Wheat Seed" +msgstr "Sementes de Trigo" + +#: wheat.lua +msgid "Wheat" +msgstr "Trigo" + +#: wheat.lua +msgid "Straw" +msgstr "Palha" + +#: wheat.lua +msgid "Flour" +msgstr "Farinha" + +#: wheat.lua +msgid "Bread" +msgstr "Pao" diff --git a/mods/farming/locale/ru.po b/mods/farming/locale/ru.po new file mode 100644 index 0000000..607c96d --- /dev/null +++ b/mods/farming/locale/ru.po @@ -0,0 +1,262 @@ +# Russian translation for farming mod. +# Copyright (C) 2018 +# This file is distributed under the same license as the farming package. +# codexp , 2018. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: 1.27\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-03-22 01:25+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: Russian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: barley.lua +msgid "Barley Seed" +msgstr "Ñемена ÑчменÑ" + +#: barley.lua +msgid "Barley" +msgstr "Ñчмень" + +#: beanpole.lua +msgid "Green Beans" +msgstr "Ð·ÐµÐ»ÐµÐ½Ð°Ñ Ñ„Ð°Ñоль" + +#: beanpole.lua +msgid "Bean Pole (place on soil before planting beans)" +msgstr "жердь Ð´Ð»Ñ Ð±Ð¾Ð±Ð¾Ð²Ñ‹Ñ… (уÑтановите на почву перед поÑадкой бобовых)" + +#: blueberry.lua +msgid "Blueberries" +msgstr "голубика" + +#: blueberry.lua +msgid "Blueberry Muffin" +msgstr "ÐºÐµÐºÑ Ð¸Ð· голубики" + +#: carrot.lua +msgid "Carrot" +msgstr "морковь" + +#: carrot.lua +msgid "Golden Carrot" +msgstr "Ð·Ð¾Ð»Ð¾Ñ‚Ð°Ñ Ð¼Ð¾Ñ€ÐºÐ¾Ð²ÑŒ" + +#: cocoa.lua +msgid "Cocoa Beans" +msgstr "бобы какао" + +#: cocoa.lua +msgid "Cookie" +msgstr "печенье" + +#: cocoa.lua +msgid "Bar of Dark Chocolate" +msgstr "плитка темного шоколада" + +#: coffee.lua +msgid "Coffee Beans" +msgstr "кофе в зернах" + +#: coffee.lua +msgid "Drinking Cup (empty)" +msgstr "чашка (пуÑтаÑ)" + +#: coffee.lua +msgid "Cold Cup of Coffee" +msgstr "Ñ…Ð¾Ð»Ð¾Ð´Ð½Ð°Ñ Ñ‡Ð°ÑˆÐºÐ° кофе" + +#: coffee.lua +msgid "Hot Cup of Coffee" +msgstr "горÑÑ‡Ð°Ñ Ñ‡Ð°ÑˆÐºÐ° кофе" + +#: corn.lua +msgid "Corn" +msgstr "кукуруза" + +#: corn.lua +msgid "Corn on the Cob" +msgstr "початок кукурузы" + +#: corn.lua +msgid "Bottle of Ethanol" +msgstr "бутылка Ñтилового Ñпирта" + +#: cotton.lua +msgid "Cotton Seed" +msgstr "Ñемена хлопка" + +#: cotton.lua +msgid "Cotton" +msgstr "хлопок" + +#: cucumber.lua +msgid "Cucumber" +msgstr "огурец" + +#: donut.lua +msgid "Donut" +msgstr "пончик" + +#: donut.lua +msgid "Chocolate Donut" +msgstr "шоколадный пончик" + +#: donut.lua +msgid "Apple Donut" +msgstr "Ñблочный пончик" + +#: grapes.lua +msgid "Grapes" +msgstr "виноград" + +#: grapes.lua +msgid "Trellis (place on soil before planting grapes)" +msgstr "решетка (поÑтавьте на почву Ð´Ð»Ñ Ð¿Ð¾Ñадки винограда)" + +#: hemp.lua +msgid "Hemp Seed" +msgstr "Ñемена конопли" + +#: hemp.lua +msgid "Hemp Leaf" +msgstr "лиÑÑ‚ÑŒÑ ÐºÐ¾Ð½Ð¾Ð¿Ð»Ð¸" + +#: hemp.lua +msgid "Bottle of Hemp Oil" +msgstr "бутылка коноплÑного маÑла" + +#: hemp.lua +msgid "Hemp Fibre" +msgstr "" + +#: hemp.lua +msgid "Hemp Rope" +msgstr "Пенька" + +#: hoes.lua +msgid "Hoe" +msgstr "мотыга" + +#: hoes.lua +msgid "Wooden Hoe" +msgstr "деревÑÐ½Ð½Ð°Ñ Ð¼Ð¾Ñ‚Ñ‹Ð³Ð°" + +#: hoes.lua +msgid "Stone Hoe" +msgstr "ÐºÐ°Ð¼ÐµÐ½Ð½Ð°Ñ Ð¼Ð¾Ñ‚Ñ‹Ð³Ð°" + +#: hoes.lua +msgid "Steel Hoe" +msgstr "ÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð¼Ð¾Ñ‚Ñ‹Ð³Ð°" + +#: hoes.lua +msgid "Bronze Hoe" +msgstr "Ð±Ñ€Ð¾Ð½Ð·Ð¾Ð²Ð°Ñ Ð¼Ð¾Ñ‚Ñ‹Ð³Ð°" + +#: hoes.lua +msgid "Mese Hoe" +msgstr "магичеÑÐºÐ°Ñ Ð¼Ð¾Ñ‚Ñ‹Ð³Ð°" + +#: hoes.lua +msgid "Diamond Hoe" +msgstr "Ð°Ð»Ð¼Ð°Ð·Ð½Ð°Ñ Ð¼Ð¾Ñ‚Ñ‹Ð³Ð°" + +#: init.lua +msgid "Seed" +msgstr "Ñемена" + +#: melon.lua +msgid "Melon Slice" +msgstr "ломтик арбуза" + +#: melon.lua +msgid "Melon" +msgstr "арбуз" + +#: potato.lua +msgid "Potato" +msgstr "картофель" + +#: potato.lua +msgid "Baked Potato" +msgstr "запеченный картофель" + +#: pumpkin.lua +msgid "Pumpkin" +msgstr "тыква" + +#: pumpkin.lua +msgid "Pumpkin Slice" +msgstr "ломтик тыквы" + +#: pumpkin.lua +msgid "Jack 'O Lantern (punch to turn on and off)" +msgstr "Ñветильник джека (удар Ð´Ð»Ñ Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¸ отключениÑ)" + +#: pumpkin.lua +msgid "Pumpkin Bread" +msgstr "тыквенный хлеб" + +#: pumpkin.lua +msgid "Pumpkin Dough" +msgstr "тыквенное теÑто" + +#: raspberry.lua +msgid "Raspberries" +msgstr "малина" + +#: raspberry.lua +msgid "Raspberry Smoothie" +msgstr "малиновый коктейль" + +#: rhubarb.lua +msgid "Rhubarb" +msgstr "ревень" + +#: rhubarb.lua +msgid "Rhubarb Pie" +msgstr "пирог из ревенÑ" + +#: soil.lua +msgid "Soil" +msgstr "землÑ" + +#: soil.lua +msgid "Wet Soil" +msgstr "Ð¼Ð¾ÐºÑ€Ð°Ñ Ð·ÐµÐ¼Ð»Ñ" + +#: sugar.lua +msgid "Sugar" +msgstr "Ñахар" + +#: tomato.lua +msgid "Tomato" +msgstr "помидор" + +#: wheat.lua +msgid "Wheat Seed" +msgstr "" + +#: wheat.lua +msgid "Wheat" +msgstr "Ñемена пшеницы" + +#: wheat.lua +msgid "Straw" +msgstr "Ñолома" + +#: wheat.lua +msgid "Flour" +msgstr "мука" + +#: wheat.lua +msgid "Bread" +msgstr "хлеб" diff --git a/mods/farming/locale/template.pot b/mods/farming/locale/template.pot new file mode 100644 index 0000000..210d946 --- /dev/null +++ b/mods/farming/locale/template.pot @@ -0,0 +1,258 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-08-16 17:38-0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: barley.lua +msgid "Barley Seed" +msgstr "" + +#: barley.lua +msgid "Barley" +msgstr "" + +#: beanpole.lua +msgid "Green Beans" +msgstr "" + +#: beanpole.lua +msgid "Bean Pole (place on soil before planting beans)" +msgstr "" + +#: blueberry.lua +msgid "Blueberries" +msgstr "" + +#: blueberry.lua +msgid "Blueberry Muffin" +msgstr "" + +#: carrot.lua +msgid "Carrot" +msgstr "" + +#: carrot.lua +msgid "Golden Carrot" +msgstr "" + +#: cocoa.lua +msgid "Cocoa Beans" +msgstr "" + +#: cocoa.lua +msgid "Cookie" +msgstr "" + +#: cocoa.lua +msgid "Bar of Dark Chocolate" +msgstr "" + +#: coffee.lua +msgid "Coffee Beans" +msgstr "" + +#: coffee.lua +msgid "Drinking Cup (empty)" +msgstr "" + +#: coffee.lua +msgid "Cold Cup of Coffee" +msgstr "" + +#: coffee.lua +msgid "Hot Cup of Coffee" +msgstr "" + +#: corn.lua +msgid "Corn" +msgstr "" + +#: corn.lua +msgid "Corn on the Cob" +msgstr "" + +#: corn.lua +msgid "Bottle of Ethanol" +msgstr "" + +#: cotton.lua +msgid "Cotton Seed" +msgstr "" + +#: cotton.lua +msgid "Cotton" +msgstr "" + +#: cucumber.lua +msgid "Cucumber" +msgstr "" + +#: donut.lua +msgid "Donut" +msgstr "" + +#: donut.lua +msgid "Chocolate Donut" +msgstr "" + +#: donut.lua +msgid "Apple Donut" +msgstr "" + +#: grapes.lua +msgid "Grapes" +msgstr "" + +#: grapes.lua +msgid "Trellis (place on soil before planting grapes)" +msgstr "" + +#: hemp.lua +msgid "Hemp Seed" +msgstr "" + +#: hemp.lua +msgid "Hemp Leaf" +msgstr "" + +#: hemp.lua +msgid "Bottle of Hemp Oil" +msgstr "" + +#: hemp.lua +msgid "Hemp Fibre" +msgstr "" + +#: hemp.lua +msgid "Hemp Rope" +msgstr "" + +#: hoes.lua +msgid "Wooden Hoe" +msgstr "" + +#: hoes.lua +msgid "Stone Hoe" +msgstr "" + +#: hoes.lua +msgid "Steel Hoe" +msgstr "" + +#: hoes.lua +msgid "Bronze Hoe" +msgstr "" + +#: hoes.lua +msgid "Mese Hoe" +msgstr "" + +#: hoes.lua +msgid "Diamond Hoe" +msgstr "" + +#: init.lua +msgid "Seed" +msgstr "" + +#: melon.lua +msgid "Melon Slice" +msgstr "" + +#: melon.lua +msgid "Melon" +msgstr "" + +#: potato.lua +msgid "Potato" +msgstr "" + +#: potato.lua +msgid "Baked Potato" +msgstr "" + +#: pumpkin.lua +msgid "Pumpkin" +msgstr "" + +#: pumpkin.lua +msgid "Pumpkin Slice" +msgstr "" + +#: pumpkin.lua +msgid "Jack 'O Lantern (punch to turn on and off)" +msgstr "" + +#: pumpkin.lua +msgid "Pumpkin Bread" +msgstr "" + +#: pumpkin.lua +msgid "Pumpkin Dough" +msgstr "" + +#: raspberry.lua +msgid "Raspberries" +msgstr "" + +#: raspberry.lua +msgid "Raspberry Smoothie" +msgstr "" + +#: rhubarb.lua +msgid "Rhubarb" +msgstr "" + +#: rhubarb.lua +msgid "Rhubarb Pie" +msgstr "" + +#: soil.lua +msgid "Soil" +msgstr "" + +#: soil.lua +msgid "Wet Soil" +msgstr "" + +#: sugar.lua +msgid "Sugar" +msgstr "" + +#: tomato.lua +msgid "Tomato" +msgstr "" + +#: wheat.lua +msgid "Wheat Seed" +msgstr "" + +#: wheat.lua +msgid "Wheat" +msgstr "" + +#: wheat.lua +msgid "Straw" +msgstr "" + +#: wheat.lua +msgid "Flour" +msgstr "" + +#: wheat.lua +msgid "Bread" +msgstr "" diff --git a/mods/farming/mapgen.lua b/mods/farming/mapgen.lua new file mode 100644 index 0000000..4c5a520 --- /dev/null +++ b/mods/farming/mapgen.lua @@ -0,0 +1,146 @@ + +-- decoration function +local function register_plant(name, min, max, spawnon, spawnby, num, rarety) + + -- do not place on mapgen if no value given (or not true) + if not rarety then + return + end + + -- set rarety value or default to farming.rarety if not a number + rarety = tonumber(rarety) or farming.rarety + + minetest.register_decoration({ + deco_type = "simple", + place_on = spawnon or {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = rarety, + spread = {x = 100, y = 100, z = 100}, + seed = 329, + octaves = 3, + persist = 0.6 + }, + y_min = min, + y_max = max, + decoration = "farming:" .. name, + spawn_by = spawnby, + num_spawn_by = num, + }) +end + + +-- add crops to mapgen +register_plant("potato_3", 15, 40, nil, "", -1, farming.potato) +register_plant("tomato_7", 5, 20, nil, "", -1, farming.tomato) +register_plant("corn_7", 12, 22, nil, "", -1, farming.corn) +register_plant("coffee_5", 20, 45, {"default:dirt_with_dry_grass", + "default:dirt_with_rainforest_litter"}, "", -1, farming.coffee) +register_plant("raspberry_4", 3, 10, nil, "", -1, farming.raspberry) +register_plant("rhubarb_3", 3, 15, nil, "", -1, farming.rhubarb) +register_plant("blueberry_4", 3, 10, nil, "", -1, farming.blueberry) +register_plant("beanbush", 18, 35, nil, "", -1, farming.beans) +register_plant("grapebush", 25, 45, nil, "", -1, farming.grapes) +register_plant("onion_5", 5, 22, nil, "", -1, farming.onion) +register_plant("garlic_5", 3, 30, nil, "group:tree", 1, farming.garlic) +register_plant("pea_5", 25, 50, nil, "", -1, farming.peas) +register_plant("beetroot_5", 1, 15, nil, "", -1, farming.beetroot) + + +if minetest.get_mapgen_setting("mg_name") == "v6" then + + register_plant("carrot_8", 1, 30, nil, "group:water", 1, farming.carrot) + register_plant("cucumber_4", 1, 20, nil, "group:water", 1, farming.cucumber) + register_plant("melon_8", 1, 20, nil, "group:water", 1, farming.melon) + register_plant("pumpkin_8", 1, 20, nil, "group:water", 1, farming.pumpkin) +else + -- v7 maps have a beach so plants growing near water is limited to 6 high + register_plant("carrot_8", 1, 15, nil, "", -1, farming.carrot) + register_plant("cucumber_4", 1, 10, nil, "", -1, farming.cucumber) + register_plant("melon_8", 1, 6, {"default:dirt_with_dry_grass", + "default:dirt_with_rainforest_litter"}, "", -1, farming.melon) + register_plant("pumpkin_8", 1, 6, nil, "", -1, farming.pumpkin) +end + +if farming.hemp then +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dirt_with_grass", "default:dirt_with_rainforest_litter"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = tonumber(farming.hemp) or farming.rarety, + spread = {x = 100, y = 100, z = 100}, + seed = 420, + octaves = 3, + persist = 0.6 + }, + y_min = 3, + y_max = 45, + decoration = "farming:hemp_7", + spawn_by = "group:tree", + num_spawn_by = 1, +}) +end + +if farming.chili then +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dirt_with_grass", "default:dirt_with_rainforest_litter"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = tonumber(farming.chili) or farming.rarety, + spread = {x = 100, y = 100, z = 100}, + seed = 760, + octaves = 3, + persist = 0.6 + }, + y_min = 5, + y_max = 35, + decoration = {"farming:chili_8"}, + spawn_by = "group:tree", + num_spawn_by = 1, +}) +end + +if farming.pepper then +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dirt_with_rainforest_litter"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = tonumber(farming.pepper) or farming.rarety, + spread = {x = 100, y = 100, z = 100}, + seed = 933, + octaves = 3, + persist = 0.6 + }, + y_min = 5, + y_max = 35, + decoration = {"farming:pepper_5"}, + spawn_by = "group:tree", + num_spawn_by = 1, +}) +end + +if farming.pineapple then +minetest.register_decoration({ + deco_type = "simple", + place_on = {"default:dirt_with_dry_grass", "default:dry_dirt_with_dry_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = tonumber(farming.pineapple) or farming.rarety, + spread = {x = 100, y = 100, z = 100}, + seed = 917, + octaves = 3, + persist = 0.6 + }, + y_min = 18, + y_max = 30, + decoration = {"farming:pineapple_8"}, +}) +end diff --git a/mods/farming/mod.conf b/mods/farming/mod.conf new file mode 100644 index 0000000..80ab8b0 --- /dev/null +++ b/mods/farming/mod.conf @@ -0,0 +1 @@ +name = farming \ No newline at end of file diff --git a/mods/farming/screenshot.png b/mods/farming/screenshot.png new file mode 100644 index 0000000..aba30f0 Binary files /dev/null and b/mods/farming/screenshot.png differ diff --git a/mods/farming/soil.lua b/mods/farming/soil.lua new file mode 100644 index 0000000..d379f5d --- /dev/null +++ b/mods/farming/soil.lua @@ -0,0 +1,74 @@ + +local S = farming.intllib + +-- normal soil +minetest.register_node("farming:soil", { + description = S("Soil"), + tiles = {"default_dirt.png^farming_soil.png", "default_dirt.png"}, + drop = "default:dirt", + groups = {crumbly = 3, not_in_creative_inventory = 1, soil = 2}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- wet soil +minetest.register_node("farming:soil_wet", { + description = S("Wet Soil"), + tiles = {"default_dirt.png^farming_soil_wet.png", "default_dirt.png^farming_soil_wet_side.png"}, + drop = "default:dirt", + groups = {crumbly = 3, not_in_creative_inventory = 1, soil = 3}, + sounds = default.node_sound_dirt_defaults(), +}) + +-- sand is not soil, change existing sand-soil to use normal soil +minetest.register_alias("farming:desert_sand_soil", "farming:soil") +minetest.register_alias("farming:desert_sand_soil_wet", "farming:soil_wet") + +-- if water near soil then change to wet soil +minetest.register_abm({ + nodenames = {"farming:soil", "farming:soil_wet"}, + interval = 15, + chance = 4, + catch_up = false, + + action = function(pos, node) + + pos.y = pos.y + 1 + local nn = minetest.get_node_or_nil(pos) + pos.y = pos.y - 1 + + if nn then nn = nn.name else return end + + -- what's on top of soil, if solid/not plant change soil to dirt + if minetest.registered_nodes[nn] + and minetest.registered_nodes[nn].walkable + and minetest.get_item_group(nn, "plant") == 0 then + minetest.set_node(pos, {name = "default:dirt"}) + return + end + + -- if map around soil not loaded then skip until loaded + if minetest.find_node_near(pos, 3, {"ignore"}) then + return + end + + -- check if there is water nearby and change soil accordingly +-- if minetest.find_node_near(pos, 3, {"group:water"}) then + + -- check if water is within 3 nodes horizontally and 1 below + if #minetest.find_nodes_in_area( + {x = pos.x + 3, y = pos.y - 1, z = pos.z + 3}, + {x = pos.x - 3, y = pos.y , z = pos.z - 3}, + {"group:water"}) > 0 then + + if node.name == "farming:soil" then + minetest.set_node(pos, {name = "farming:soil_wet"}) + end + + elseif node.name == "farming:soil_wet" then + minetest.set_node(pos, {name = "farming:soil"}) + + elseif node.name == "farming:soil" and minetest.get_item_group(nn, "plant") == 0 then + minetest.set_node(pos, {name = "default:dirt"}) + end + end, +}) diff --git a/mods/farming/statistics.lua b/mods/farming/statistics.lua new file mode 100644 index 0000000..c8defa2 --- /dev/null +++ b/mods/farming/statistics.lua @@ -0,0 +1,174 @@ +local statistics = {} +local ROOT_2 = math.sqrt(2.0) + +-- Approximations for erf(x) and erfInv(x) from +-- https://en.wikipedia.org/wiki/Error_function + +local erf +local erf_inv + +local A = 8 * (math.pi - 3.0)/(3.0 * math.pi * (4.0 - math.pi)) +local B = 4.0 / math.pi +local C = 2.0/(math.pi * A) +local D = 1.0 / A + +erf = function(x) + + if x == 0 then return 0; end + + local xSq = x * x + local aXSq = A * xSq + local v = math.sqrt(1.0 - math.exp(-xSq * (B + aXSq) / (1.0 + aXSq))) + + return (x > 0 and v) or -v +end + +erf_inv = function(x) + + if x == 0 then return 0; end + + if x <= -1 or x >= 1 then return nil; end + + local y = math.log(1 - x * x) + local u = C + 0.5 * y + local v = math.sqrt(math.sqrt(u * u - D * y) - u) + + return (x > 0 and v) or -v +end + +local function std_normal(u) + return ROOT_2 * erf_inv(2.0 * u - 1.0) +end + +local poisson +local cdf_table = {} + +local function generate_cdf(lambda_index, lambda) + + local max = math.ceil(4 * lambda) + local pdf = math.exp(-lambda) + local cdf = pdf + local t = { [0] = pdf } + + for i = 1, max - 1 do + pdf = pdf * lambda / i + cdf = cdf + pdf + t[i] = cdf + end + + return t +end + +for li = 1, 100 do + cdf_table[li] = generate_cdf(li, 0.25 * li) +end + +poisson = function(lambda, max) + + if max < 2 then + return (math.random() < math.exp(-lambda) and 0) or 1 + elseif lambda >= 2 * max then + return max + end + + local u = math.random() + local lambda_index = math.floor(4 * lambda + 0.5) + local cdfs = cdf_table[lambda_index] + + if cdfs then + + lambda = 0.25 * lambda_index + + if u < cdfs[0] then return 0; end + if max > #cdfs then max = #cdfs + 1 else max = math.floor(max); end + if u >= cdfs[max - 1] then return max; end + + if max > 4 then -- Binary search + + local s = 0 + + while s + 1 < max do + + local m = math.floor(0.5 * (s + max)) + + if u < cdfs[m] then max = m; else s = m; end + end + else + for i = 1, max - 1 do + if u < cdfs[i] then return i; end + end + end + + return max + else + local x = lambda + math.sqrt(lambda) * std_normal(u) + + return (x < 0.5 and 0) or (x >= max - 0.5 and max) or math.floor(x + 0.5) + end +end + +-- Error function. +statistics.erf = erf + +-- Inverse error function. +statistics.erf_inv = erf_inv + +--- Standard normal distribution function (mean 0, standard deviation 1). + -- + -- @return + -- Any real number (actually between -3.0 and 3.0). + +statistics.std_normal = function() + + local u = math.random() + + if u < 0.001 then + return -3.0 + elseif u > 0.999 then + return 3.0 + end + + return std_normal(u) +end + +--- Standard normal distribution function (mean 0, standard deviation 1). + -- + -- @param mu + -- The distribution mean. + -- @param sigma + -- The distribution standard deviation. + -- @return + -- Any real number (actually between -3*sigma and 3*sigma). + +statistics.normal = function(mu, sigma) + + local u = math.random() + + if u < 0.001 then + return mu - 3.0 * sigma + elseif u > 0.999 then + return mu + 3.0 * sigma + end + + return mu + sigma * std_normal(u) +end + +--- Poisson distribution function. + -- + -- @param lambda + -- The distribution mean and variance. + -- @param max + -- The distribution maximum. + -- @return + -- An integer between 0 and max (both inclusive). + +statistics.poisson = function(lambda, max) + + lambda, max = tonumber(lambda), tonumber(max) + + if not lambda or not max or lambda <= 0 or max < 1 then return 0; end + + return poisson(lambda, max) +end + +return statistics diff --git a/mods/farming/textures/banana_leaf.png b/mods/farming/textures/banana_leaf.png new file mode 100644 index 0000000..5800cbf Binary files /dev/null and b/mods/farming/textures/banana_leaf.png differ diff --git a/mods/farming/textures/banana_single.png b/mods/farming/textures/banana_single.png new file mode 100644 index 0000000..b15ed2f Binary files /dev/null and b/mods/farming/textures/banana_single.png differ diff --git a/mods/farming/textures/crops_garlic.png b/mods/farming/textures/crops_garlic.png new file mode 100644 index 0000000..a73638c Binary files /dev/null and b/mods/farming/textures/crops_garlic.png differ diff --git a/mods/farming/textures/crops_garlic_braid.png b/mods/farming/textures/crops_garlic_braid.png new file mode 100644 index 0000000..f5fa269 Binary files /dev/null and b/mods/farming/textures/crops_garlic_braid.png differ diff --git a/mods/farming/textures/crops_garlic_braid_side.png b/mods/farming/textures/crops_garlic_braid_side.png new file mode 100644 index 0000000..ce467b7 Binary files /dev/null and b/mods/farming/textures/crops_garlic_braid_side.png differ diff --git a/mods/farming/textures/crops_garlic_clove.png b/mods/farming/textures/crops_garlic_clove.png new file mode 100644 index 0000000..bfc1cee Binary files /dev/null and b/mods/farming/textures/crops_garlic_clove.png differ diff --git a/mods/farming/textures/crops_garlic_plant_1.png b/mods/farming/textures/crops_garlic_plant_1.png new file mode 100644 index 0000000..61eb9a8 Binary files /dev/null and b/mods/farming/textures/crops_garlic_plant_1.png differ diff --git a/mods/farming/textures/crops_garlic_plant_2.png b/mods/farming/textures/crops_garlic_plant_2.png new file mode 100644 index 0000000..217fd25 Binary files /dev/null and b/mods/farming/textures/crops_garlic_plant_2.png differ diff --git a/mods/farming/textures/crops_garlic_plant_3.png b/mods/farming/textures/crops_garlic_plant_3.png new file mode 100644 index 0000000..557b017 Binary files /dev/null and b/mods/farming/textures/crops_garlic_plant_3.png differ diff --git a/mods/farming/textures/crops_garlic_plant_4.png b/mods/farming/textures/crops_garlic_plant_4.png new file mode 100644 index 0000000..80ef076 Binary files /dev/null and b/mods/farming/textures/crops_garlic_plant_4.png differ diff --git a/mods/farming/textures/crops_garlic_plant_5.png b/mods/farming/textures/crops_garlic_plant_5.png new file mode 100644 index 0000000..8b8c31a Binary files /dev/null and b/mods/farming/textures/crops_garlic_plant_5.png differ diff --git a/mods/farming/textures/crops_onion.png b/mods/farming/textures/crops_onion.png new file mode 100644 index 0000000..2099c63 Binary files /dev/null and b/mods/farming/textures/crops_onion.png differ diff --git a/mods/farming/textures/crops_onion_plant_1.png b/mods/farming/textures/crops_onion_plant_1.png new file mode 100644 index 0000000..dea2d4b Binary files /dev/null and b/mods/farming/textures/crops_onion_plant_1.png differ diff --git a/mods/farming/textures/crops_onion_plant_2.png b/mods/farming/textures/crops_onion_plant_2.png new file mode 100644 index 0000000..1f850f1 Binary files /dev/null and b/mods/farming/textures/crops_onion_plant_2.png differ diff --git a/mods/farming/textures/crops_onion_plant_3.png b/mods/farming/textures/crops_onion_plant_3.png new file mode 100644 index 0000000..d9af239 Binary files /dev/null and b/mods/farming/textures/crops_onion_plant_3.png differ diff --git a/mods/farming/textures/crops_onion_plant_4.png b/mods/farming/textures/crops_onion_plant_4.png new file mode 100644 index 0000000..962b21b Binary files /dev/null and b/mods/farming/textures/crops_onion_plant_4.png differ diff --git a/mods/farming/textures/crops_onion_plant_5.png b/mods/farming/textures/crops_onion_plant_5.png new file mode 100644 index 0000000..dfb1f7f Binary files /dev/null and b/mods/farming/textures/crops_onion_plant_5.png differ diff --git a/mods/farming/textures/crops_pepper.png b/mods/farming/textures/crops_pepper.png new file mode 100644 index 0000000..bb8f40c Binary files /dev/null and b/mods/farming/textures/crops_pepper.png differ diff --git a/mods/farming/textures/crops_pepper_ground.png b/mods/farming/textures/crops_pepper_ground.png new file mode 100644 index 0000000..d72405a Binary files /dev/null and b/mods/farming/textures/crops_pepper_ground.png differ diff --git a/mods/farming/textures/crops_pepper_plant_1.png b/mods/farming/textures/crops_pepper_plant_1.png new file mode 100644 index 0000000..43ce6ba Binary files /dev/null and b/mods/farming/textures/crops_pepper_plant_1.png differ diff --git a/mods/farming/textures/crops_pepper_plant_2.png b/mods/farming/textures/crops_pepper_plant_2.png new file mode 100644 index 0000000..556f952 Binary files /dev/null and b/mods/farming/textures/crops_pepper_plant_2.png differ diff --git a/mods/farming/textures/crops_pepper_plant_3.png b/mods/farming/textures/crops_pepper_plant_3.png new file mode 100644 index 0000000..24e92e1 Binary files /dev/null and b/mods/farming/textures/crops_pepper_plant_3.png differ diff --git a/mods/farming/textures/crops_pepper_plant_4.png b/mods/farming/textures/crops_pepper_plant_4.png new file mode 100644 index 0000000..e33554d Binary files /dev/null and b/mods/farming/textures/crops_pepper_plant_4.png differ diff --git a/mods/farming/textures/crops_pepper_plant_5.png b/mods/farming/textures/crops_pepper_plant_5.png new file mode 100644 index 0000000..c2c92eb Binary files /dev/null and b/mods/farming/textures/crops_pepper_plant_5.png differ diff --git a/mods/farming/textures/crops_peppercorn.png b/mods/farming/textures/crops_peppercorn.png new file mode 100644 index 0000000..0ee3c49 Binary files /dev/null and b/mods/farming/textures/crops_peppercorn.png differ diff --git a/mods/farming/textures/default_junglegrass.png b/mods/farming/textures/default_junglegrass.png new file mode 100644 index 0000000..5d8cdbc Binary files /dev/null and b/mods/farming/textures/default_junglegrass.png differ diff --git a/mods/farming/textures/farming_baked_potato.png b/mods/farming/textures/farming_baked_potato.png new file mode 100644 index 0000000..425c4ae Binary files /dev/null and b/mods/farming/textures/farming_baked_potato.png differ diff --git a/mods/farming/textures/farming_baking_tray.png b/mods/farming/textures/farming_baking_tray.png new file mode 100644 index 0000000..be1711c Binary files /dev/null and b/mods/farming/textures/farming_baking_tray.png differ diff --git a/mods/farming/textures/farming_barley.png b/mods/farming/textures/farming_barley.png new file mode 100644 index 0000000..ca929e0 Binary files /dev/null and b/mods/farming/textures/farming_barley.png differ diff --git a/mods/farming/textures/farming_barley_1.png b/mods/farming/textures/farming_barley_1.png new file mode 100644 index 0000000..4a458b1 Binary files /dev/null and b/mods/farming/textures/farming_barley_1.png differ diff --git a/mods/farming/textures/farming_barley_2.png b/mods/farming/textures/farming_barley_2.png new file mode 100644 index 0000000..96610c2 Binary files /dev/null and b/mods/farming/textures/farming_barley_2.png differ diff --git a/mods/farming/textures/farming_barley_3.png b/mods/farming/textures/farming_barley_3.png new file mode 100644 index 0000000..ef14b5b Binary files /dev/null and b/mods/farming/textures/farming_barley_3.png differ diff --git a/mods/farming/textures/farming_barley_4.png b/mods/farming/textures/farming_barley_4.png new file mode 100644 index 0000000..f7c9054 Binary files /dev/null and b/mods/farming/textures/farming_barley_4.png differ diff --git a/mods/farming/textures/farming_barley_5.png b/mods/farming/textures/farming_barley_5.png new file mode 100644 index 0000000..68c0d68 Binary files /dev/null and b/mods/farming/textures/farming_barley_5.png differ diff --git a/mods/farming/textures/farming_barley_6.png b/mods/farming/textures/farming_barley_6.png new file mode 100644 index 0000000..496a218 Binary files /dev/null and b/mods/farming/textures/farming_barley_6.png differ diff --git a/mods/farming/textures/farming_barley_7.png b/mods/farming/textures/farming_barley_7.png new file mode 100644 index 0000000..1c636af Binary files /dev/null and b/mods/farming/textures/farming_barley_7.png differ diff --git a/mods/farming/textures/farming_barley_seed.png b/mods/farming/textures/farming_barley_seed.png new file mode 100644 index 0000000..2f00a20 Binary files /dev/null and b/mods/farming/textures/farming_barley_seed.png differ diff --git a/mods/farming/textures/farming_beanbush.png b/mods/farming/textures/farming_beanbush.png new file mode 100644 index 0000000..637e716 Binary files /dev/null and b/mods/farming/textures/farming_beanbush.png differ diff --git a/mods/farming/textures/farming_beanpole.png b/mods/farming/textures/farming_beanpole.png new file mode 100644 index 0000000..ed07572 Binary files /dev/null and b/mods/farming/textures/farming_beanpole.png differ diff --git a/mods/farming/textures/farming_beanpole_1.png b/mods/farming/textures/farming_beanpole_1.png new file mode 100644 index 0000000..ef2bd5a Binary files /dev/null and b/mods/farming/textures/farming_beanpole_1.png differ diff --git a/mods/farming/textures/farming_beanpole_2.png b/mods/farming/textures/farming_beanpole_2.png new file mode 100644 index 0000000..34143e4 Binary files /dev/null and b/mods/farming/textures/farming_beanpole_2.png differ diff --git a/mods/farming/textures/farming_beanpole_3.png b/mods/farming/textures/farming_beanpole_3.png new file mode 100644 index 0000000..d693f17 Binary files /dev/null and b/mods/farming/textures/farming_beanpole_3.png differ diff --git a/mods/farming/textures/farming_beanpole_4.png b/mods/farming/textures/farming_beanpole_4.png new file mode 100644 index 0000000..c779b25 Binary files /dev/null and b/mods/farming/textures/farming_beanpole_4.png differ diff --git a/mods/farming/textures/farming_beanpole_5.png b/mods/farming/textures/farming_beanpole_5.png new file mode 100644 index 0000000..910f8a0 Binary files /dev/null and b/mods/farming/textures/farming_beanpole_5.png differ diff --git a/mods/farming/textures/farming_beans.png b/mods/farming/textures/farming_beans.png new file mode 100644 index 0000000..ad5cf85 Binary files /dev/null and b/mods/farming/textures/farming_beans.png differ diff --git a/mods/farming/textures/farming_beetroot.png b/mods/farming/textures/farming_beetroot.png new file mode 100644 index 0000000..6a60168 Binary files /dev/null and b/mods/farming/textures/farming_beetroot.png differ diff --git a/mods/farming/textures/farming_beetroot_1.png b/mods/farming/textures/farming_beetroot_1.png new file mode 100644 index 0000000..8b75e10 Binary files /dev/null and b/mods/farming/textures/farming_beetroot_1.png differ diff --git a/mods/farming/textures/farming_beetroot_2.png b/mods/farming/textures/farming_beetroot_2.png new file mode 100644 index 0000000..9c1ce1e Binary files /dev/null and b/mods/farming/textures/farming_beetroot_2.png differ diff --git a/mods/farming/textures/farming_beetroot_3.png b/mods/farming/textures/farming_beetroot_3.png new file mode 100644 index 0000000..0f28e5e Binary files /dev/null and b/mods/farming/textures/farming_beetroot_3.png differ diff --git a/mods/farming/textures/farming_beetroot_4.png b/mods/farming/textures/farming_beetroot_4.png new file mode 100644 index 0000000..35f211b Binary files /dev/null and b/mods/farming/textures/farming_beetroot_4.png differ diff --git a/mods/farming/textures/farming_beetroot_5.png b/mods/farming/textures/farming_beetroot_5.png new file mode 100644 index 0000000..c4b8957 Binary files /dev/null and b/mods/farming/textures/farming_beetroot_5.png differ diff --git a/mods/farming/textures/farming_beetroot_soup.png b/mods/farming/textures/farming_beetroot_soup.png new file mode 100644 index 0000000..4df562e Binary files /dev/null and b/mods/farming/textures/farming_beetroot_soup.png differ diff --git a/mods/farming/textures/farming_blueberries.png b/mods/farming/textures/farming_blueberries.png new file mode 100644 index 0000000..b0c4931 Binary files /dev/null and b/mods/farming/textures/farming_blueberries.png differ diff --git a/mods/farming/textures/farming_blueberry_1.png b/mods/farming/textures/farming_blueberry_1.png new file mode 100644 index 0000000..83832c8 Binary files /dev/null and b/mods/farming/textures/farming_blueberry_1.png differ diff --git a/mods/farming/textures/farming_blueberry_2.png b/mods/farming/textures/farming_blueberry_2.png new file mode 100644 index 0000000..308a0ca Binary files /dev/null and b/mods/farming/textures/farming_blueberry_2.png differ diff --git a/mods/farming/textures/farming_blueberry_3.png b/mods/farming/textures/farming_blueberry_3.png new file mode 100644 index 0000000..43d2ab1 Binary files /dev/null and b/mods/farming/textures/farming_blueberry_3.png differ diff --git a/mods/farming/textures/farming_blueberry_4.png b/mods/farming/textures/farming_blueberry_4.png new file mode 100644 index 0000000..75fb69a Binary files /dev/null and b/mods/farming/textures/farming_blueberry_4.png differ diff --git a/mods/farming/textures/farming_blueberry_muffin.png b/mods/farming/textures/farming_blueberry_muffin.png new file mode 100644 index 0000000..b1253d7 Binary files /dev/null and b/mods/farming/textures/farming_blueberry_muffin.png differ diff --git a/mods/farming/textures/farming_blueberry_pie.png b/mods/farming/textures/farming_blueberry_pie.png new file mode 100644 index 0000000..2174686 Binary files /dev/null and b/mods/farming/textures/farming_blueberry_pie.png differ diff --git a/mods/farming/textures/farming_bottle_ethanol.png b/mods/farming/textures/farming_bottle_ethanol.png new file mode 100644 index 0000000..84e6162 Binary files /dev/null and b/mods/farming/textures/farming_bottle_ethanol.png differ diff --git a/mods/farming/textures/farming_bowl.png b/mods/farming/textures/farming_bowl.png new file mode 100644 index 0000000..627c22e Binary files /dev/null and b/mods/farming/textures/farming_bowl.png differ diff --git a/mods/farming/textures/farming_bread.png b/mods/farming/textures/farming_bread.png new file mode 100644 index 0000000..bd00e3e Binary files /dev/null and b/mods/farming/textures/farming_bread.png differ diff --git a/mods/farming/textures/farming_bread_multigrain.png b/mods/farming/textures/farming_bread_multigrain.png new file mode 100644 index 0000000..66dda07 Binary files /dev/null and b/mods/farming/textures/farming_bread_multigrain.png differ diff --git a/mods/farming/textures/farming_bread_slice.png b/mods/farming/textures/farming_bread_slice.png new file mode 100644 index 0000000..ff2714d Binary files /dev/null and b/mods/farming/textures/farming_bread_slice.png differ diff --git a/mods/farming/textures/farming_carrot.png b/mods/farming/textures/farming_carrot.png new file mode 100644 index 0000000..73f2fd4 Binary files /dev/null and b/mods/farming/textures/farming_carrot.png differ diff --git a/mods/farming/textures/farming_carrot_1.png b/mods/farming/textures/farming_carrot_1.png new file mode 100644 index 0000000..bbeae7e Binary files /dev/null and b/mods/farming/textures/farming_carrot_1.png differ diff --git a/mods/farming/textures/farming_carrot_2.png b/mods/farming/textures/farming_carrot_2.png new file mode 100644 index 0000000..b24ecc0 Binary files /dev/null and b/mods/farming/textures/farming_carrot_2.png differ diff --git a/mods/farming/textures/farming_carrot_3.png b/mods/farming/textures/farming_carrot_3.png new file mode 100644 index 0000000..8400505 Binary files /dev/null and b/mods/farming/textures/farming_carrot_3.png differ diff --git a/mods/farming/textures/farming_carrot_4.png b/mods/farming/textures/farming_carrot_4.png new file mode 100644 index 0000000..32ee262 Binary files /dev/null and b/mods/farming/textures/farming_carrot_4.png differ diff --git a/mods/farming/textures/farming_carrot_5.png b/mods/farming/textures/farming_carrot_5.png new file mode 100644 index 0000000..0bcd9c1 Binary files /dev/null and b/mods/farming/textures/farming_carrot_5.png differ diff --git a/mods/farming/textures/farming_carrot_6.png b/mods/farming/textures/farming_carrot_6.png new file mode 100644 index 0000000..a17c6b2 Binary files /dev/null and b/mods/farming/textures/farming_carrot_6.png differ diff --git a/mods/farming/textures/farming_carrot_7.png b/mods/farming/textures/farming_carrot_7.png new file mode 100644 index 0000000..d26eee7 Binary files /dev/null and b/mods/farming/textures/farming_carrot_7.png differ diff --git a/mods/farming/textures/farming_carrot_8.png b/mods/farming/textures/farming_carrot_8.png new file mode 100644 index 0000000..00b6d92 Binary files /dev/null and b/mods/farming/textures/farming_carrot_8.png differ diff --git a/mods/farming/textures/farming_carrot_gold.png b/mods/farming/textures/farming_carrot_gold.png new file mode 100644 index 0000000..b817101 Binary files /dev/null and b/mods/farming/textures/farming_carrot_gold.png differ diff --git a/mods/farming/textures/farming_carrot_juice.png b/mods/farming/textures/farming_carrot_juice.png new file mode 100644 index 0000000..5a03245 Binary files /dev/null and b/mods/farming/textures/farming_carrot_juice.png differ diff --git a/mods/farming/textures/farming_chili_1.png b/mods/farming/textures/farming_chili_1.png new file mode 100644 index 0000000..aa11988 Binary files /dev/null and b/mods/farming/textures/farming_chili_1.png differ diff --git a/mods/farming/textures/farming_chili_2.png b/mods/farming/textures/farming_chili_2.png new file mode 100644 index 0000000..ae34506 Binary files /dev/null and b/mods/farming/textures/farming_chili_2.png differ diff --git a/mods/farming/textures/farming_chili_3.png b/mods/farming/textures/farming_chili_3.png new file mode 100644 index 0000000..5e1d901 Binary files /dev/null and b/mods/farming/textures/farming_chili_3.png differ diff --git a/mods/farming/textures/farming_chili_4.png b/mods/farming/textures/farming_chili_4.png new file mode 100644 index 0000000..d97769b Binary files /dev/null and b/mods/farming/textures/farming_chili_4.png differ diff --git a/mods/farming/textures/farming_chili_5.png b/mods/farming/textures/farming_chili_5.png new file mode 100644 index 0000000..dd4755d Binary files /dev/null and b/mods/farming/textures/farming_chili_5.png differ diff --git a/mods/farming/textures/farming_chili_6.png b/mods/farming/textures/farming_chili_6.png new file mode 100644 index 0000000..4ee057b Binary files /dev/null and b/mods/farming/textures/farming_chili_6.png differ diff --git a/mods/farming/textures/farming_chili_7.png b/mods/farming/textures/farming_chili_7.png new file mode 100644 index 0000000..5912c2e Binary files /dev/null and b/mods/farming/textures/farming_chili_7.png differ diff --git a/mods/farming/textures/farming_chili_8.png b/mods/farming/textures/farming_chili_8.png new file mode 100644 index 0000000..976eb52 Binary files /dev/null and b/mods/farming/textures/farming_chili_8.png differ diff --git a/mods/farming/textures/farming_chili_bowl.png b/mods/farming/textures/farming_chili_bowl.png new file mode 100644 index 0000000..6454ba3 Binary files /dev/null and b/mods/farming/textures/farming_chili_bowl.png differ diff --git a/mods/farming/textures/farming_chili_pepper.png b/mods/farming/textures/farming_chili_pepper.png new file mode 100644 index 0000000..922cec4 Binary files /dev/null and b/mods/farming/textures/farming_chili_pepper.png differ diff --git a/mods/farming/textures/farming_chocolate_block.png b/mods/farming/textures/farming_chocolate_block.png new file mode 100644 index 0000000..20e5a79 Binary files /dev/null and b/mods/farming/textures/farming_chocolate_block.png differ diff --git a/mods/farming/textures/farming_chocolate_dark.png b/mods/farming/textures/farming_chocolate_dark.png new file mode 100644 index 0000000..03243b2 Binary files /dev/null and b/mods/farming/textures/farming_chocolate_dark.png differ diff --git a/mods/farming/textures/farming_cocoa_1.png b/mods/farming/textures/farming_cocoa_1.png new file mode 100644 index 0000000..18fd362 Binary files /dev/null and b/mods/farming/textures/farming_cocoa_1.png differ diff --git a/mods/farming/textures/farming_cocoa_2.png b/mods/farming/textures/farming_cocoa_2.png new file mode 100644 index 0000000..c304ee0 Binary files /dev/null and b/mods/farming/textures/farming_cocoa_2.png differ diff --git a/mods/farming/textures/farming_cocoa_3.png b/mods/farming/textures/farming_cocoa_3.png new file mode 100644 index 0000000..d66b47d Binary files /dev/null and b/mods/farming/textures/farming_cocoa_3.png differ diff --git a/mods/farming/textures/farming_cocoa_4.png b/mods/farming/textures/farming_cocoa_4.png new file mode 100644 index 0000000..990a8b4 Binary files /dev/null and b/mods/farming/textures/farming_cocoa_4.png differ diff --git a/mods/farming/textures/farming_cocoa_beans.png b/mods/farming/textures/farming_cocoa_beans.png new file mode 100644 index 0000000..4022f8e Binary files /dev/null and b/mods/farming/textures/farming_cocoa_beans.png differ diff --git a/mods/farming/textures/farming_coffee_1.png b/mods/farming/textures/farming_coffee_1.png new file mode 100644 index 0000000..97c207a Binary files /dev/null and b/mods/farming/textures/farming_coffee_1.png differ diff --git a/mods/farming/textures/farming_coffee_2.png b/mods/farming/textures/farming_coffee_2.png new file mode 100644 index 0000000..a659f85 Binary files /dev/null and b/mods/farming/textures/farming_coffee_2.png differ diff --git a/mods/farming/textures/farming_coffee_3.png b/mods/farming/textures/farming_coffee_3.png new file mode 100644 index 0000000..93088c8 Binary files /dev/null and b/mods/farming/textures/farming_coffee_3.png differ diff --git a/mods/farming/textures/farming_coffee_4.png b/mods/farming/textures/farming_coffee_4.png new file mode 100644 index 0000000..37a609f Binary files /dev/null and b/mods/farming/textures/farming_coffee_4.png differ diff --git a/mods/farming/textures/farming_coffee_5.png b/mods/farming/textures/farming_coffee_5.png new file mode 100644 index 0000000..e624fbe Binary files /dev/null and b/mods/farming/textures/farming_coffee_5.png differ diff --git a/mods/farming/textures/farming_coffee_beans.png b/mods/farming/textures/farming_coffee_beans.png new file mode 100644 index 0000000..0786f4e Binary files /dev/null and b/mods/farming/textures/farming_coffee_beans.png differ diff --git a/mods/farming/textures/farming_coffee_cup.png b/mods/farming/textures/farming_coffee_cup.png new file mode 100644 index 0000000..d3820bc Binary files /dev/null and b/mods/farming/textures/farming_coffee_cup.png differ diff --git a/mods/farming/textures/farming_cookie.png b/mods/farming/textures/farming_cookie.png new file mode 100644 index 0000000..e80be35 Binary files /dev/null and b/mods/farming/textures/farming_cookie.png differ diff --git a/mods/farming/textures/farming_corn.png b/mods/farming/textures/farming_corn.png new file mode 100644 index 0000000..2a2894a Binary files /dev/null and b/mods/farming/textures/farming_corn.png differ diff --git a/mods/farming/textures/farming_corn_1.png b/mods/farming/textures/farming_corn_1.png new file mode 100644 index 0000000..60e8b99 Binary files /dev/null and b/mods/farming/textures/farming_corn_1.png differ diff --git a/mods/farming/textures/farming_corn_2.png b/mods/farming/textures/farming_corn_2.png new file mode 100644 index 0000000..6ba6cc9 Binary files /dev/null and b/mods/farming/textures/farming_corn_2.png differ diff --git a/mods/farming/textures/farming_corn_3.png b/mods/farming/textures/farming_corn_3.png new file mode 100644 index 0000000..c5fa80b Binary files /dev/null and b/mods/farming/textures/farming_corn_3.png differ diff --git a/mods/farming/textures/farming_corn_4.png b/mods/farming/textures/farming_corn_4.png new file mode 100644 index 0000000..a43632d Binary files /dev/null and b/mods/farming/textures/farming_corn_4.png differ diff --git a/mods/farming/textures/farming_corn_5.png b/mods/farming/textures/farming_corn_5.png new file mode 100644 index 0000000..7b6fb02 Binary files /dev/null and b/mods/farming/textures/farming_corn_5.png differ diff --git a/mods/farming/textures/farming_corn_6.png b/mods/farming/textures/farming_corn_6.png new file mode 100644 index 0000000..313697b Binary files /dev/null and b/mods/farming/textures/farming_corn_6.png differ diff --git a/mods/farming/textures/farming_corn_7.png b/mods/farming/textures/farming_corn_7.png new file mode 100644 index 0000000..6a937e7 Binary files /dev/null and b/mods/farming/textures/farming_corn_7.png differ diff --git a/mods/farming/textures/farming_corn_8.png b/mods/farming/textures/farming_corn_8.png new file mode 100644 index 0000000..77e442b Binary files /dev/null and b/mods/farming/textures/farming_corn_8.png differ diff --git a/mods/farming/textures/farming_corn_cob.png b/mods/farming/textures/farming_corn_cob.png new file mode 100644 index 0000000..a2fd9da Binary files /dev/null and b/mods/farming/textures/farming_corn_cob.png differ diff --git a/mods/farming/textures/farming_cornstarch.png b/mods/farming/textures/farming_cornstarch.png new file mode 100644 index 0000000..d5f8218 Binary files /dev/null and b/mods/farming/textures/farming_cornstarch.png differ diff --git a/mods/farming/textures/farming_cotton.png b/mods/farming/textures/farming_cotton.png new file mode 100644 index 0000000..8aa50e4 Binary files /dev/null and b/mods/farming/textures/farming_cotton.png differ diff --git a/mods/farming/textures/farming_cotton_1.png b/mods/farming/textures/farming_cotton_1.png new file mode 100644 index 0000000..5fc2180 Binary files /dev/null and b/mods/farming/textures/farming_cotton_1.png differ diff --git a/mods/farming/textures/farming_cotton_2.png b/mods/farming/textures/farming_cotton_2.png new file mode 100644 index 0000000..db4f4a3 Binary files /dev/null and b/mods/farming/textures/farming_cotton_2.png differ diff --git a/mods/farming/textures/farming_cotton_3.png b/mods/farming/textures/farming_cotton_3.png new file mode 100644 index 0000000..df3d7a7 Binary files /dev/null and b/mods/farming/textures/farming_cotton_3.png differ diff --git a/mods/farming/textures/farming_cotton_4.png b/mods/farming/textures/farming_cotton_4.png new file mode 100644 index 0000000..f314b07 Binary files /dev/null and b/mods/farming/textures/farming_cotton_4.png differ diff --git a/mods/farming/textures/farming_cotton_5.png b/mods/farming/textures/farming_cotton_5.png new file mode 100644 index 0000000..3e89085 Binary files /dev/null and b/mods/farming/textures/farming_cotton_5.png differ diff --git a/mods/farming/textures/farming_cotton_6.png b/mods/farming/textures/farming_cotton_6.png new file mode 100644 index 0000000..f4bd4fb Binary files /dev/null and b/mods/farming/textures/farming_cotton_6.png differ diff --git a/mods/farming/textures/farming_cotton_7.png b/mods/farming/textures/farming_cotton_7.png new file mode 100644 index 0000000..466d40a Binary files /dev/null and b/mods/farming/textures/farming_cotton_7.png differ diff --git a/mods/farming/textures/farming_cotton_8.png b/mods/farming/textures/farming_cotton_8.png new file mode 100644 index 0000000..f835ba5 Binary files /dev/null and b/mods/farming/textures/farming_cotton_8.png differ diff --git a/mods/farming/textures/farming_cotton_seed.png b/mods/farming/textures/farming_cotton_seed.png new file mode 100644 index 0000000..f1d5b8a Binary files /dev/null and b/mods/farming/textures/farming_cotton_seed.png differ diff --git a/mods/farming/textures/farming_cucumber.png b/mods/farming/textures/farming_cucumber.png new file mode 100644 index 0000000..2acb7b2 Binary files /dev/null and b/mods/farming/textures/farming_cucumber.png differ diff --git a/mods/farming/textures/farming_cucumber_1.png b/mods/farming/textures/farming_cucumber_1.png new file mode 100644 index 0000000..e008fd1 Binary files /dev/null and b/mods/farming/textures/farming_cucumber_1.png differ diff --git a/mods/farming/textures/farming_cucumber_2.png b/mods/farming/textures/farming_cucumber_2.png new file mode 100644 index 0000000..9c345ff Binary files /dev/null and b/mods/farming/textures/farming_cucumber_2.png differ diff --git a/mods/farming/textures/farming_cucumber_3.png b/mods/farming/textures/farming_cucumber_3.png new file mode 100644 index 0000000..25f3c54 Binary files /dev/null and b/mods/farming/textures/farming_cucumber_3.png differ diff --git a/mods/farming/textures/farming_cucumber_4.png b/mods/farming/textures/farming_cucumber_4.png new file mode 100644 index 0000000..fc62f2f Binary files /dev/null and b/mods/farming/textures/farming_cucumber_4.png differ diff --git a/mods/farming/textures/farming_cutting_board.png b/mods/farming/textures/farming_cutting_board.png new file mode 100644 index 0000000..90b3f9c Binary files /dev/null and b/mods/farming/textures/farming_cutting_board.png differ diff --git a/mods/farming/textures/farming_desert_sand_soil.png b/mods/farming/textures/farming_desert_sand_soil.png new file mode 100644 index 0000000..1450e01 Binary files /dev/null and b/mods/farming/textures/farming_desert_sand_soil.png differ diff --git a/mods/farming/textures/farming_desert_sand_soil_wet.png b/mods/farming/textures/farming_desert_sand_soil_wet.png new file mode 100644 index 0000000..cffa955 Binary files /dev/null and b/mods/farming/textures/farming_desert_sand_soil_wet.png differ diff --git a/mods/farming/textures/farming_desert_sand_soil_wet_side.png b/mods/farming/textures/farming_desert_sand_soil_wet_side.png new file mode 100644 index 0000000..fbb2815 Binary files /dev/null and b/mods/farming/textures/farming_desert_sand_soil_wet_side.png differ diff --git a/mods/farming/textures/farming_donut.png b/mods/farming/textures/farming_donut.png new file mode 100644 index 0000000..8985299 Binary files /dev/null and b/mods/farming/textures/farming_donut.png differ diff --git a/mods/farming/textures/farming_donut_apple.png b/mods/farming/textures/farming_donut_apple.png new file mode 100644 index 0000000..6dfe63d Binary files /dev/null and b/mods/farming/textures/farming_donut_apple.png differ diff --git a/mods/farming/textures/farming_donut_chocolate.png b/mods/farming/textures/farming_donut_chocolate.png new file mode 100644 index 0000000..aa4b93f Binary files /dev/null and b/mods/farming/textures/farming_donut_chocolate.png differ diff --git a/mods/farming/textures/farming_flour.png b/mods/farming/textures/farming_flour.png new file mode 100644 index 0000000..b1a9783 Binary files /dev/null and b/mods/farming/textures/farming_flour.png differ diff --git a/mods/farming/textures/farming_flour_multigrain.png b/mods/farming/textures/farming_flour_multigrain.png new file mode 100644 index 0000000..5367bc5 Binary files /dev/null and b/mods/farming/textures/farming_flour_multigrain.png differ diff --git a/mods/farming/textures/farming_garlic_bread.png b/mods/farming/textures/farming_garlic_bread.png new file mode 100644 index 0000000..b760004 Binary files /dev/null and b/mods/farming/textures/farming_garlic_bread.png differ diff --git a/mods/farming/textures/farming_grapebush.png b/mods/farming/textures/farming_grapebush.png new file mode 100644 index 0000000..c2e6620 Binary files /dev/null and b/mods/farming/textures/farming_grapebush.png differ diff --git a/mods/farming/textures/farming_grapes.png b/mods/farming/textures/farming_grapes.png new file mode 100644 index 0000000..aa00ed6 Binary files /dev/null and b/mods/farming/textures/farming_grapes.png differ diff --git a/mods/farming/textures/farming_grapes_1.png b/mods/farming/textures/farming_grapes_1.png new file mode 100644 index 0000000..64a935d Binary files /dev/null and b/mods/farming/textures/farming_grapes_1.png differ diff --git a/mods/farming/textures/farming_grapes_2.png b/mods/farming/textures/farming_grapes_2.png new file mode 100644 index 0000000..6cc2a33 Binary files /dev/null and b/mods/farming/textures/farming_grapes_2.png differ diff --git a/mods/farming/textures/farming_grapes_3.png b/mods/farming/textures/farming_grapes_3.png new file mode 100644 index 0000000..66d6310 Binary files /dev/null and b/mods/farming/textures/farming_grapes_3.png differ diff --git a/mods/farming/textures/farming_grapes_4.png b/mods/farming/textures/farming_grapes_4.png new file mode 100644 index 0000000..57cdc73 Binary files /dev/null and b/mods/farming/textures/farming_grapes_4.png differ diff --git a/mods/farming/textures/farming_grapes_5.png b/mods/farming/textures/farming_grapes_5.png new file mode 100644 index 0000000..aad41f4 Binary files /dev/null and b/mods/farming/textures/farming_grapes_5.png differ diff --git a/mods/farming/textures/farming_grapes_6.png b/mods/farming/textures/farming_grapes_6.png new file mode 100644 index 0000000..2e23a3c Binary files /dev/null and b/mods/farming/textures/farming_grapes_6.png differ diff --git a/mods/farming/textures/farming_grapes_7.png b/mods/farming/textures/farming_grapes_7.png new file mode 100644 index 0000000..9e70b6d Binary files /dev/null and b/mods/farming/textures/farming_grapes_7.png differ diff --git a/mods/farming/textures/farming_grapes_8.png b/mods/farming/textures/farming_grapes_8.png new file mode 100644 index 0000000..5093a06 Binary files /dev/null and b/mods/farming/textures/farming_grapes_8.png differ diff --git a/mods/farming/textures/farming_hemp_1.png b/mods/farming/textures/farming_hemp_1.png new file mode 100644 index 0000000..6fb4510 Binary files /dev/null and b/mods/farming/textures/farming_hemp_1.png differ diff --git a/mods/farming/textures/farming_hemp_2.png b/mods/farming/textures/farming_hemp_2.png new file mode 100644 index 0000000..a676173 Binary files /dev/null and b/mods/farming/textures/farming_hemp_2.png differ diff --git a/mods/farming/textures/farming_hemp_3.png b/mods/farming/textures/farming_hemp_3.png new file mode 100644 index 0000000..57136d5 Binary files /dev/null and b/mods/farming/textures/farming_hemp_3.png differ diff --git a/mods/farming/textures/farming_hemp_4.png b/mods/farming/textures/farming_hemp_4.png new file mode 100644 index 0000000..b375cf3 Binary files /dev/null and b/mods/farming/textures/farming_hemp_4.png differ diff --git a/mods/farming/textures/farming_hemp_5.png b/mods/farming/textures/farming_hemp_5.png new file mode 100644 index 0000000..890a3d2 Binary files /dev/null and b/mods/farming/textures/farming_hemp_5.png differ diff --git a/mods/farming/textures/farming_hemp_6.png b/mods/farming/textures/farming_hemp_6.png new file mode 100644 index 0000000..258d4e3 Binary files /dev/null and b/mods/farming/textures/farming_hemp_6.png differ diff --git a/mods/farming/textures/farming_hemp_7.png b/mods/farming/textures/farming_hemp_7.png new file mode 100644 index 0000000..1ce3a8d Binary files /dev/null and b/mods/farming/textures/farming_hemp_7.png differ diff --git a/mods/farming/textures/farming_hemp_8.png b/mods/farming/textures/farming_hemp_8.png new file mode 100644 index 0000000..8d2143f Binary files /dev/null and b/mods/farming/textures/farming_hemp_8.png differ diff --git a/mods/farming/textures/farming_hemp_block.png b/mods/farming/textures/farming_hemp_block.png new file mode 100644 index 0000000..285a2cd Binary files /dev/null and b/mods/farming/textures/farming_hemp_block.png differ diff --git a/mods/farming/textures/farming_hemp_fibre.png b/mods/farming/textures/farming_hemp_fibre.png new file mode 100644 index 0000000..fe3c918 Binary files /dev/null and b/mods/farming/textures/farming_hemp_fibre.png differ diff --git a/mods/farming/textures/farming_hemp_leaf.png b/mods/farming/textures/farming_hemp_leaf.png new file mode 100644 index 0000000..997c8f0 Binary files /dev/null and b/mods/farming/textures/farming_hemp_leaf.png differ diff --git a/mods/farming/textures/farming_hemp_oil.png b/mods/farming/textures/farming_hemp_oil.png new file mode 100644 index 0000000..fa8afe2 Binary files /dev/null and b/mods/farming/textures/farming_hemp_oil.png differ diff --git a/mods/farming/textures/farming_hemp_rope.png b/mods/farming/textures/farming_hemp_rope.png new file mode 100644 index 0000000..03a7082 Binary files /dev/null and b/mods/farming/textures/farming_hemp_rope.png differ diff --git a/mods/farming/textures/farming_hemp_seed.png b/mods/farming/textures/farming_hemp_seed.png new file mode 100644 index 0000000..6be42c8 Binary files /dev/null and b/mods/farming/textures/farming_hemp_seed.png differ diff --git a/mods/farming/textures/farming_hoe_bomb.png b/mods/farming/textures/farming_hoe_bomb.png new file mode 100644 index 0000000..e8db9b1 Binary files /dev/null and b/mods/farming/textures/farming_hoe_bomb.png differ diff --git a/mods/farming/textures/farming_jaffa_cake.png b/mods/farming/textures/farming_jaffa_cake.png new file mode 100644 index 0000000..87cc003 Binary files /dev/null and b/mods/farming/textures/farming_jaffa_cake.png differ diff --git a/mods/farming/textures/farming_juicer.png b/mods/farming/textures/farming_juicer.png new file mode 100644 index 0000000..46265e4 Binary files /dev/null and b/mods/farming/textures/farming_juicer.png differ diff --git a/mods/farming/textures/farming_melon_1.png b/mods/farming/textures/farming_melon_1.png new file mode 100644 index 0000000..3c6ea6d Binary files /dev/null and b/mods/farming/textures/farming_melon_1.png differ diff --git a/mods/farming/textures/farming_melon_2.png b/mods/farming/textures/farming_melon_2.png new file mode 100644 index 0000000..185ed82 Binary files /dev/null and b/mods/farming/textures/farming_melon_2.png differ diff --git a/mods/farming/textures/farming_melon_3.png b/mods/farming/textures/farming_melon_3.png new file mode 100644 index 0000000..6e661f9 Binary files /dev/null and b/mods/farming/textures/farming_melon_3.png differ diff --git a/mods/farming/textures/farming_melon_4.png b/mods/farming/textures/farming_melon_4.png new file mode 100644 index 0000000..d9199f3 Binary files /dev/null and b/mods/farming/textures/farming_melon_4.png differ diff --git a/mods/farming/textures/farming_melon_5.png b/mods/farming/textures/farming_melon_5.png new file mode 100644 index 0000000..755cbd3 Binary files /dev/null and b/mods/farming/textures/farming_melon_5.png differ diff --git a/mods/farming/textures/farming_melon_6.png b/mods/farming/textures/farming_melon_6.png new file mode 100644 index 0000000..b31a5b4 Binary files /dev/null and b/mods/farming/textures/farming_melon_6.png differ diff --git a/mods/farming/textures/farming_melon_7.png b/mods/farming/textures/farming_melon_7.png new file mode 100644 index 0000000..3aebfdd Binary files /dev/null and b/mods/farming/textures/farming_melon_7.png differ diff --git a/mods/farming/textures/farming_melon_side.png b/mods/farming/textures/farming_melon_side.png new file mode 100644 index 0000000..88e40c6 Binary files /dev/null and b/mods/farming/textures/farming_melon_side.png differ diff --git a/mods/farming/textures/farming_melon_slice.png b/mods/farming/textures/farming_melon_slice.png new file mode 100644 index 0000000..6ee9775 Binary files /dev/null and b/mods/farming/textures/farming_melon_slice.png differ diff --git a/mods/farming/textures/farming_melon_top.png b/mods/farming/textures/farming_melon_top.png new file mode 100644 index 0000000..f387dbd Binary files /dev/null and b/mods/farming/textures/farming_melon_top.png differ diff --git a/mods/farming/textures/farming_mixing_bowl.png b/mods/farming/textures/farming_mixing_bowl.png new file mode 100644 index 0000000..e96edf0 Binary files /dev/null and b/mods/farming/textures/farming_mixing_bowl.png differ diff --git a/mods/farming/textures/farming_mortar_pestle.png b/mods/farming/textures/farming_mortar_pestle.png new file mode 100644 index 0000000..abfeb9e Binary files /dev/null and b/mods/farming/textures/farming_mortar_pestle.png differ diff --git a/mods/farming/textures/farming_oat.png b/mods/farming/textures/farming_oat.png new file mode 100644 index 0000000..e8d5c23 Binary files /dev/null and b/mods/farming/textures/farming_oat.png differ diff --git a/mods/farming/textures/farming_oat_1.png b/mods/farming/textures/farming_oat_1.png new file mode 100644 index 0000000..177fbdf Binary files /dev/null and b/mods/farming/textures/farming_oat_1.png differ diff --git a/mods/farming/textures/farming_oat_2.png b/mods/farming/textures/farming_oat_2.png new file mode 100644 index 0000000..fe051ea Binary files /dev/null and b/mods/farming/textures/farming_oat_2.png differ diff --git a/mods/farming/textures/farming_oat_3.png b/mods/farming/textures/farming_oat_3.png new file mode 100644 index 0000000..5aba108 Binary files /dev/null and b/mods/farming/textures/farming_oat_3.png differ diff --git a/mods/farming/textures/farming_oat_4.png b/mods/farming/textures/farming_oat_4.png new file mode 100644 index 0000000..833b134 Binary files /dev/null and b/mods/farming/textures/farming_oat_4.png differ diff --git a/mods/farming/textures/farming_oat_5.png b/mods/farming/textures/farming_oat_5.png new file mode 100644 index 0000000..ec0803b Binary files /dev/null and b/mods/farming/textures/farming_oat_5.png differ diff --git a/mods/farming/textures/farming_oat_6.png b/mods/farming/textures/farming_oat_6.png new file mode 100644 index 0000000..847adc5 Binary files /dev/null and b/mods/farming/textures/farming_oat_6.png differ diff --git a/mods/farming/textures/farming_oat_7.png b/mods/farming/textures/farming_oat_7.png new file mode 100644 index 0000000..3552811 Binary files /dev/null and b/mods/farming/textures/farming_oat_7.png differ diff --git a/mods/farming/textures/farming_oat_8.png b/mods/farming/textures/farming_oat_8.png new file mode 100644 index 0000000..c7a5540 Binary files /dev/null and b/mods/farming/textures/farming_oat_8.png differ diff --git a/mods/farming/textures/farming_oat_seed.png b/mods/farming/textures/farming_oat_seed.png new file mode 100644 index 0000000..893c93c Binary files /dev/null and b/mods/farming/textures/farming_oat_seed.png differ diff --git a/mods/farming/textures/farming_orange.png b/mods/farming/textures/farming_orange.png new file mode 100644 index 0000000..8b9ec29 Binary files /dev/null and b/mods/farming/textures/farming_orange.png differ diff --git a/mods/farming/textures/farming_pea_1.png b/mods/farming/textures/farming_pea_1.png new file mode 100644 index 0000000..eb48e36 Binary files /dev/null and b/mods/farming/textures/farming_pea_1.png differ diff --git a/mods/farming/textures/farming_pea_2.png b/mods/farming/textures/farming_pea_2.png new file mode 100644 index 0000000..4db7551 Binary files /dev/null and b/mods/farming/textures/farming_pea_2.png differ diff --git a/mods/farming/textures/farming_pea_3.png b/mods/farming/textures/farming_pea_3.png new file mode 100644 index 0000000..980d6ea Binary files /dev/null and b/mods/farming/textures/farming_pea_3.png differ diff --git a/mods/farming/textures/farming_pea_4.png b/mods/farming/textures/farming_pea_4.png new file mode 100644 index 0000000..551eaf4 Binary files /dev/null and b/mods/farming/textures/farming_pea_4.png differ diff --git a/mods/farming/textures/farming_pea_5.png b/mods/farming/textures/farming_pea_5.png new file mode 100644 index 0000000..907760d Binary files /dev/null and b/mods/farming/textures/farming_pea_5.png differ diff --git a/mods/farming/textures/farming_pea_peas.png b/mods/farming/textures/farming_pea_peas.png new file mode 100644 index 0000000..d70b283 Binary files /dev/null and b/mods/farming/textures/farming_pea_peas.png differ diff --git a/mods/farming/textures/farming_pea_pod.png b/mods/farming/textures/farming_pea_pod.png new file mode 100644 index 0000000..1c19c9f Binary files /dev/null and b/mods/farming/textures/farming_pea_pod.png differ diff --git a/mods/farming/textures/farming_pea_soup.png b/mods/farming/textures/farming_pea_soup.png new file mode 100644 index 0000000..03753cf Binary files /dev/null and b/mods/farming/textures/farming_pea_soup.png differ diff --git a/mods/farming/textures/farming_pineapple.png b/mods/farming/textures/farming_pineapple.png new file mode 100644 index 0000000..febf22a Binary files /dev/null and b/mods/farming/textures/farming_pineapple.png differ diff --git a/mods/farming/textures/farming_pineapple_1.png b/mods/farming/textures/farming_pineapple_1.png new file mode 100644 index 0000000..262eff7 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_1.png differ diff --git a/mods/farming/textures/farming_pineapple_2.png b/mods/farming/textures/farming_pineapple_2.png new file mode 100644 index 0000000..4b96d17 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_2.png differ diff --git a/mods/farming/textures/farming_pineapple_3.png b/mods/farming/textures/farming_pineapple_3.png new file mode 100644 index 0000000..90464a1 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_3.png differ diff --git a/mods/farming/textures/farming_pineapple_4.png b/mods/farming/textures/farming_pineapple_4.png new file mode 100644 index 0000000..be58e53 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_4.png differ diff --git a/mods/farming/textures/farming_pineapple_5.png b/mods/farming/textures/farming_pineapple_5.png new file mode 100644 index 0000000..2526f83 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_5.png differ diff --git a/mods/farming/textures/farming_pineapple_6.png b/mods/farming/textures/farming_pineapple_6.png new file mode 100644 index 0000000..741e0e3 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_6.png differ diff --git a/mods/farming/textures/farming_pineapple_7.png b/mods/farming/textures/farming_pineapple_7.png new file mode 100644 index 0000000..22bad23 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_7.png differ diff --git a/mods/farming/textures/farming_pineapple_8.png b/mods/farming/textures/farming_pineapple_8.png new file mode 100644 index 0000000..5182c4f Binary files /dev/null and b/mods/farming/textures/farming_pineapple_8.png differ diff --git a/mods/farming/textures/farming_pineapple_juice.png b/mods/farming/textures/farming_pineapple_juice.png new file mode 100644 index 0000000..43a54c7 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_juice.png differ diff --git a/mods/farming/textures/farming_pineapple_ring.png b/mods/farming/textures/farming_pineapple_ring.png new file mode 100644 index 0000000..deb2e6d Binary files /dev/null and b/mods/farming/textures/farming_pineapple_ring.png differ diff --git a/mods/farming/textures/farming_pineapple_top.png b/mods/farming/textures/farming_pineapple_top.png new file mode 100644 index 0000000..f653d83 Binary files /dev/null and b/mods/farming/textures/farming_pineapple_top.png differ diff --git a/mods/farming/textures/farming_porridge.png b/mods/farming/textures/farming_porridge.png new file mode 100644 index 0000000..cd4466f Binary files /dev/null and b/mods/farming/textures/farming_porridge.png differ diff --git a/mods/farming/textures/farming_pot.png b/mods/farming/textures/farming_pot.png new file mode 100644 index 0000000..d28411d Binary files /dev/null and b/mods/farming/textures/farming_pot.png differ diff --git a/mods/farming/textures/farming_potato.png b/mods/farming/textures/farming_potato.png new file mode 100644 index 0000000..6e91d6a Binary files /dev/null and b/mods/farming/textures/farming_potato.png differ diff --git a/mods/farming/textures/farming_potato_1.png b/mods/farming/textures/farming_potato_1.png new file mode 100644 index 0000000..a9c0040 Binary files /dev/null and b/mods/farming/textures/farming_potato_1.png differ diff --git a/mods/farming/textures/farming_potato_2.png b/mods/farming/textures/farming_potato_2.png new file mode 100644 index 0000000..c81830c Binary files /dev/null and b/mods/farming/textures/farming_potato_2.png differ diff --git a/mods/farming/textures/farming_potato_3.png b/mods/farming/textures/farming_potato_3.png new file mode 100644 index 0000000..a3d7920 Binary files /dev/null and b/mods/farming/textures/farming_potato_3.png differ diff --git a/mods/farming/textures/farming_potato_4.png b/mods/farming/textures/farming_potato_4.png new file mode 100644 index 0000000..405b7e5 Binary files /dev/null and b/mods/farming/textures/farming_potato_4.png differ diff --git a/mods/farming/textures/farming_potato_salad.png b/mods/farming/textures/farming_potato_salad.png new file mode 100644 index 0000000..0028c91 Binary files /dev/null and b/mods/farming/textures/farming_potato_salad.png differ diff --git a/mods/farming/textures/farming_pumpkin_1.png b/mods/farming/textures/farming_pumpkin_1.png new file mode 100644 index 0000000..e5b9a2b Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_1.png differ diff --git a/mods/farming/textures/farming_pumpkin_2.png b/mods/farming/textures/farming_pumpkin_2.png new file mode 100644 index 0000000..d977e8c Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_2.png differ diff --git a/mods/farming/textures/farming_pumpkin_3.png b/mods/farming/textures/farming_pumpkin_3.png new file mode 100644 index 0000000..83f8190 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_3.png differ diff --git a/mods/farming/textures/farming_pumpkin_4.png b/mods/farming/textures/farming_pumpkin_4.png new file mode 100644 index 0000000..20de004 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_4.png differ diff --git a/mods/farming/textures/farming_pumpkin_5.png b/mods/farming/textures/farming_pumpkin_5.png new file mode 100644 index 0000000..59fa78e Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_5.png differ diff --git a/mods/farming/textures/farming_pumpkin_6.png b/mods/farming/textures/farming_pumpkin_6.png new file mode 100644 index 0000000..6ae543e Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_6.png differ diff --git a/mods/farming/textures/farming_pumpkin_7.png b/mods/farming/textures/farming_pumpkin_7.png new file mode 100644 index 0000000..79190e0 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_7.png differ diff --git a/mods/farming/textures/farming_pumpkin_8.png b/mods/farming/textures/farming_pumpkin_8.png new file mode 100644 index 0000000..b941442 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_8.png differ diff --git a/mods/farming/textures/farming_pumpkin_bread.png b/mods/farming/textures/farming_pumpkin_bread.png new file mode 100644 index 0000000..0dfae08 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_bread.png differ diff --git a/mods/farming/textures/farming_pumpkin_dough.png b/mods/farming/textures/farming_pumpkin_dough.png new file mode 100644 index 0000000..62ea7a6 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_dough.png differ diff --git a/mods/farming/textures/farming_pumpkin_face_off.png b/mods/farming/textures/farming_pumpkin_face_off.png new file mode 100644 index 0000000..df70171 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_face_off.png differ diff --git a/mods/farming/textures/farming_pumpkin_face_on.png b/mods/farming/textures/farming_pumpkin_face_on.png new file mode 100644 index 0000000..fa71c9d Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_face_on.png differ diff --git a/mods/farming/textures/farming_pumpkin_side.png b/mods/farming/textures/farming_pumpkin_side.png new file mode 100644 index 0000000..2d30f20 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_side.png differ diff --git a/mods/farming/textures/farming_pumpkin_slice.png b/mods/farming/textures/farming_pumpkin_slice.png new file mode 100644 index 0000000..1fb659e Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_slice.png differ diff --git a/mods/farming/textures/farming_pumpkin_top.png b/mods/farming/textures/farming_pumpkin_top.png new file mode 100644 index 0000000..7928345 Binary files /dev/null and b/mods/farming/textures/farming_pumpkin_top.png differ diff --git a/mods/farming/textures/farming_raspberries.png b/mods/farming/textures/farming_raspberries.png new file mode 100644 index 0000000..ab96e1b Binary files /dev/null and b/mods/farming/textures/farming_raspberries.png differ diff --git a/mods/farming/textures/farming_raspberry_1.png b/mods/farming/textures/farming_raspberry_1.png new file mode 100644 index 0000000..d1a7ffc Binary files /dev/null and b/mods/farming/textures/farming_raspberry_1.png differ diff --git a/mods/farming/textures/farming_raspberry_2.png b/mods/farming/textures/farming_raspberry_2.png new file mode 100644 index 0000000..308a0ca Binary files /dev/null and b/mods/farming/textures/farming_raspberry_2.png differ diff --git a/mods/farming/textures/farming_raspberry_3.png b/mods/farming/textures/farming_raspberry_3.png new file mode 100644 index 0000000..43d2ab1 Binary files /dev/null and b/mods/farming/textures/farming_raspberry_3.png differ diff --git a/mods/farming/textures/farming_raspberry_4.png b/mods/farming/textures/farming_raspberry_4.png new file mode 100644 index 0000000..32da6b9 Binary files /dev/null and b/mods/farming/textures/farming_raspberry_4.png differ diff --git a/mods/farming/textures/farming_raspberry_smoothie.png b/mods/farming/textures/farming_raspberry_smoothie.png new file mode 100644 index 0000000..fe178d1 Binary files /dev/null and b/mods/farming/textures/farming_raspberry_smoothie.png differ diff --git a/mods/farming/textures/farming_rhubarb.png b/mods/farming/textures/farming_rhubarb.png new file mode 100644 index 0000000..7d416ab Binary files /dev/null and b/mods/farming/textures/farming_rhubarb.png differ diff --git a/mods/farming/textures/farming_rhubarb_1.png b/mods/farming/textures/farming_rhubarb_1.png new file mode 100644 index 0000000..01585b1 Binary files /dev/null and b/mods/farming/textures/farming_rhubarb_1.png differ diff --git a/mods/farming/textures/farming_rhubarb_2.png b/mods/farming/textures/farming_rhubarb_2.png new file mode 100644 index 0000000..71845c7 Binary files /dev/null and b/mods/farming/textures/farming_rhubarb_2.png differ diff --git a/mods/farming/textures/farming_rhubarb_3.png b/mods/farming/textures/farming_rhubarb_3.png new file mode 100644 index 0000000..b412f7e Binary files /dev/null and b/mods/farming/textures/farming_rhubarb_3.png differ diff --git a/mods/farming/textures/farming_rhubarb_pie.png b/mods/farming/textures/farming_rhubarb_pie.png new file mode 100644 index 0000000..1f77b53 Binary files /dev/null and b/mods/farming/textures/farming_rhubarb_pie.png differ diff --git a/mods/farming/textures/farming_rice.png b/mods/farming/textures/farming_rice.png new file mode 100644 index 0000000..3d64c7e Binary files /dev/null and b/mods/farming/textures/farming_rice.png differ diff --git a/mods/farming/textures/farming_rice_1.png b/mods/farming/textures/farming_rice_1.png new file mode 100644 index 0000000..715bb2e Binary files /dev/null and b/mods/farming/textures/farming_rice_1.png differ diff --git a/mods/farming/textures/farming_rice_2.png b/mods/farming/textures/farming_rice_2.png new file mode 100644 index 0000000..2662d42 Binary files /dev/null and b/mods/farming/textures/farming_rice_2.png differ diff --git a/mods/farming/textures/farming_rice_3.png b/mods/farming/textures/farming_rice_3.png new file mode 100644 index 0000000..fee87b2 Binary files /dev/null and b/mods/farming/textures/farming_rice_3.png differ diff --git a/mods/farming/textures/farming_rice_4.png b/mods/farming/textures/farming_rice_4.png new file mode 100644 index 0000000..97b026f Binary files /dev/null and b/mods/farming/textures/farming_rice_4.png differ diff --git a/mods/farming/textures/farming_rice_5.png b/mods/farming/textures/farming_rice_5.png new file mode 100644 index 0000000..c249851 Binary files /dev/null and b/mods/farming/textures/farming_rice_5.png differ diff --git a/mods/farming/textures/farming_rice_6.png b/mods/farming/textures/farming_rice_6.png new file mode 100644 index 0000000..c0e7233 Binary files /dev/null and b/mods/farming/textures/farming_rice_6.png differ diff --git a/mods/farming/textures/farming_rice_7.png b/mods/farming/textures/farming_rice_7.png new file mode 100644 index 0000000..9d251ee Binary files /dev/null and b/mods/farming/textures/farming_rice_7.png differ diff --git a/mods/farming/textures/farming_rice_8.png b/mods/farming/textures/farming_rice_8.png new file mode 100644 index 0000000..41b37e0 Binary files /dev/null and b/mods/farming/textures/farming_rice_8.png differ diff --git a/mods/farming/textures/farming_rice_bread.png b/mods/farming/textures/farming_rice_bread.png new file mode 100644 index 0000000..f14f741 Binary files /dev/null and b/mods/farming/textures/farming_rice_bread.png differ diff --git a/mods/farming/textures/farming_rice_flour.png b/mods/farming/textures/farming_rice_flour.png new file mode 100644 index 0000000..2722151 Binary files /dev/null and b/mods/farming/textures/farming_rice_flour.png differ diff --git a/mods/farming/textures/farming_rice_seed.png b/mods/farming/textures/farming_rice_seed.png new file mode 100644 index 0000000..854cd05 Binary files /dev/null and b/mods/farming/textures/farming_rice_seed.png differ diff --git a/mods/farming/textures/farming_rose_water.png b/mods/farming/textures/farming_rose_water.png new file mode 100644 index 0000000..96e546f Binary files /dev/null and b/mods/farming/textures/farming_rose_water.png differ diff --git a/mods/farming/textures/farming_rye.png b/mods/farming/textures/farming_rye.png new file mode 100644 index 0000000..ebc5b37 Binary files /dev/null and b/mods/farming/textures/farming_rye.png differ diff --git a/mods/farming/textures/farming_rye_1.png b/mods/farming/textures/farming_rye_1.png new file mode 100644 index 0000000..932b621 Binary files /dev/null and b/mods/farming/textures/farming_rye_1.png differ diff --git a/mods/farming/textures/farming_rye_2.png b/mods/farming/textures/farming_rye_2.png new file mode 100644 index 0000000..b6a69b7 Binary files /dev/null and b/mods/farming/textures/farming_rye_2.png differ diff --git a/mods/farming/textures/farming_rye_3.png b/mods/farming/textures/farming_rye_3.png new file mode 100644 index 0000000..aaa71c2 Binary files /dev/null and b/mods/farming/textures/farming_rye_3.png differ diff --git a/mods/farming/textures/farming_rye_4.png b/mods/farming/textures/farming_rye_4.png new file mode 100644 index 0000000..ea1246e Binary files /dev/null and b/mods/farming/textures/farming_rye_4.png differ diff --git a/mods/farming/textures/farming_rye_5.png b/mods/farming/textures/farming_rye_5.png new file mode 100644 index 0000000..b359673 Binary files /dev/null and b/mods/farming/textures/farming_rye_5.png differ diff --git a/mods/farming/textures/farming_rye_6.png b/mods/farming/textures/farming_rye_6.png new file mode 100644 index 0000000..749a2ef Binary files /dev/null and b/mods/farming/textures/farming_rye_6.png differ diff --git a/mods/farming/textures/farming_rye_7.png b/mods/farming/textures/farming_rye_7.png new file mode 100644 index 0000000..fc78198 Binary files /dev/null and b/mods/farming/textures/farming_rye_7.png differ diff --git a/mods/farming/textures/farming_rye_8.png b/mods/farming/textures/farming_rye_8.png new file mode 100644 index 0000000..0b7c33e Binary files /dev/null and b/mods/farming/textures/farming_rye_8.png differ diff --git a/mods/farming/textures/farming_rye_seed.png b/mods/farming/textures/farming_rye_seed.png new file mode 100644 index 0000000..e65ba9b Binary files /dev/null and b/mods/farming/textures/farming_rye_seed.png differ diff --git a/mods/farming/textures/farming_salt.png b/mods/farming/textures/farming_salt.png new file mode 100644 index 0000000..2b23e33 Binary files /dev/null and b/mods/farming/textures/farming_salt.png differ diff --git a/mods/farming/textures/farming_saucepan.png b/mods/farming/textures/farming_saucepan.png new file mode 100644 index 0000000..2625d45 Binary files /dev/null and b/mods/farming/textures/farming_saucepan.png differ diff --git a/mods/farming/textures/farming_scythe.png b/mods/farming/textures/farming_scythe.png new file mode 100644 index 0000000..aeafce2 Binary files /dev/null and b/mods/farming/textures/farming_scythe.png differ diff --git a/mods/farming/textures/farming_scythe_mithril.png b/mods/farming/textures/farming_scythe_mithril.png new file mode 100644 index 0000000..17c89c5 Binary files /dev/null and b/mods/farming/textures/farming_scythe_mithril.png differ diff --git a/mods/farming/textures/farming_skillet.png b/mods/farming/textures/farming_skillet.png new file mode 100644 index 0000000..60d26a1 Binary files /dev/null and b/mods/farming/textures/farming_skillet.png differ diff --git a/mods/farming/textures/farming_soil.png b/mods/farming/textures/farming_soil.png new file mode 100644 index 0000000..5cd3e68 Binary files /dev/null and b/mods/farming/textures/farming_soil.png differ diff --git a/mods/farming/textures/farming_soil_wet.png b/mods/farming/textures/farming_soil_wet.png new file mode 100644 index 0000000..0b4487d Binary files /dev/null and b/mods/farming/textures/farming_soil_wet.png differ diff --git a/mods/farming/textures/farming_soil_wet_side.png b/mods/farming/textures/farming_soil_wet_side.png new file mode 100644 index 0000000..f0b1bd4 Binary files /dev/null and b/mods/farming/textures/farming_soil_wet_side.png differ diff --git a/mods/farming/textures/farming_straw.png b/mods/farming/textures/farming_straw.png new file mode 100644 index 0000000..e427772 Binary files /dev/null and b/mods/farming/textures/farming_straw.png differ diff --git a/mods/farming/textures/farming_string.png b/mods/farming/textures/farming_string.png new file mode 100644 index 0000000..e2bbfd7 Binary files /dev/null and b/mods/farming/textures/farming_string.png differ diff --git a/mods/farming/textures/farming_sugar.png b/mods/farming/textures/farming_sugar.png new file mode 100644 index 0000000..5cb7fa0 Binary files /dev/null and b/mods/farming/textures/farming_sugar.png differ diff --git a/mods/farming/textures/farming_toast.png b/mods/farming/textures/farming_toast.png new file mode 100644 index 0000000..8a4524e Binary files /dev/null and b/mods/farming/textures/farming_toast.png differ diff --git a/mods/farming/textures/farming_toast_sandwich.png b/mods/farming/textures/farming_toast_sandwich.png new file mode 100644 index 0000000..c60ff5a Binary files /dev/null and b/mods/farming/textures/farming_toast_sandwich.png differ diff --git a/mods/farming/textures/farming_tomato.png b/mods/farming/textures/farming_tomato.png new file mode 100644 index 0000000..586aa56 Binary files /dev/null and b/mods/farming/textures/farming_tomato.png differ diff --git a/mods/farming/textures/farming_tomato_1.png b/mods/farming/textures/farming_tomato_1.png new file mode 100644 index 0000000..d858e58 Binary files /dev/null and b/mods/farming/textures/farming_tomato_1.png differ diff --git a/mods/farming/textures/farming_tomato_2.png b/mods/farming/textures/farming_tomato_2.png new file mode 100644 index 0000000..9d9ed6d Binary files /dev/null and b/mods/farming/textures/farming_tomato_2.png differ diff --git a/mods/farming/textures/farming_tomato_3.png b/mods/farming/textures/farming_tomato_3.png new file mode 100644 index 0000000..fe3dcf0 Binary files /dev/null and b/mods/farming/textures/farming_tomato_3.png differ diff --git a/mods/farming/textures/farming_tomato_4.png b/mods/farming/textures/farming_tomato_4.png new file mode 100644 index 0000000..27c3282 Binary files /dev/null and b/mods/farming/textures/farming_tomato_4.png differ diff --git a/mods/farming/textures/farming_tomato_5.png b/mods/farming/textures/farming_tomato_5.png new file mode 100644 index 0000000..f369a68 Binary files /dev/null and b/mods/farming/textures/farming_tomato_5.png differ diff --git a/mods/farming/textures/farming_tomato_6.png b/mods/farming/textures/farming_tomato_6.png new file mode 100644 index 0000000..0135cb5 Binary files /dev/null and b/mods/farming/textures/farming_tomato_6.png differ diff --git a/mods/farming/textures/farming_tomato_7.png b/mods/farming/textures/farming_tomato_7.png new file mode 100644 index 0000000..4cd85f5 Binary files /dev/null and b/mods/farming/textures/farming_tomato_7.png differ diff --git a/mods/farming/textures/farming_tomato_8.png b/mods/farming/textures/farming_tomato_8.png new file mode 100644 index 0000000..0b49025 Binary files /dev/null and b/mods/farming/textures/farming_tomato_8.png differ diff --git a/mods/farming/textures/farming_tool_bronzehoe.png b/mods/farming/textures/farming_tool_bronzehoe.png new file mode 100644 index 0000000..ef07a80 Binary files /dev/null and b/mods/farming/textures/farming_tool_bronzehoe.png differ diff --git a/mods/farming/textures/farming_tool_diamondhoe.png b/mods/farming/textures/farming_tool_diamondhoe.png new file mode 100644 index 0000000..093acb8 Binary files /dev/null and b/mods/farming/textures/farming_tool_diamondhoe.png differ diff --git a/mods/farming/textures/farming_tool_mesehoe.png b/mods/farming/textures/farming_tool_mesehoe.png new file mode 100644 index 0000000..ffd597a Binary files /dev/null and b/mods/farming/textures/farming_tool_mesehoe.png differ diff --git a/mods/farming/textures/farming_tool_steelhoe.png b/mods/farming/textures/farming_tool_steelhoe.png new file mode 100644 index 0000000..893a695 Binary files /dev/null and b/mods/farming/textures/farming_tool_steelhoe.png differ diff --git a/mods/farming/textures/farming_tool_stonehoe.png b/mods/farming/textures/farming_tool_stonehoe.png new file mode 100644 index 0000000..4f8dade Binary files /dev/null and b/mods/farming/textures/farming_tool_stonehoe.png differ diff --git a/mods/farming/textures/farming_tool_woodhoe.png b/mods/farming/textures/farming_tool_woodhoe.png new file mode 100644 index 0000000..8b20d2d Binary files /dev/null and b/mods/farming/textures/farming_tool_woodhoe.png differ diff --git a/mods/farming/textures/farming_trellis.png b/mods/farming/textures/farming_trellis.png new file mode 100644 index 0000000..855b932 Binary files /dev/null and b/mods/farming/textures/farming_trellis.png differ diff --git a/mods/farming/textures/farming_turkish_delight.png b/mods/farming/textures/farming_turkish_delight.png new file mode 100644 index 0000000..198ffc4 Binary files /dev/null and b/mods/farming/textures/farming_turkish_delight.png differ diff --git a/mods/farming/textures/farming_wheat.png b/mods/farming/textures/farming_wheat.png new file mode 100644 index 0000000..1e0ad3b Binary files /dev/null and b/mods/farming/textures/farming_wheat.png differ diff --git a/mods/farming/textures/farming_wheat_1.png b/mods/farming/textures/farming_wheat_1.png new file mode 100644 index 0000000..c16ad94 Binary files /dev/null and b/mods/farming/textures/farming_wheat_1.png differ diff --git a/mods/farming/textures/farming_wheat_2.png b/mods/farming/textures/farming_wheat_2.png new file mode 100644 index 0000000..baddb4c Binary files /dev/null and b/mods/farming/textures/farming_wheat_2.png differ diff --git a/mods/farming/textures/farming_wheat_3.png b/mods/farming/textures/farming_wheat_3.png new file mode 100644 index 0000000..36ebb19 Binary files /dev/null and b/mods/farming/textures/farming_wheat_3.png differ diff --git a/mods/farming/textures/farming_wheat_4.png b/mods/farming/textures/farming_wheat_4.png new file mode 100644 index 0000000..735ed77 Binary files /dev/null and b/mods/farming/textures/farming_wheat_4.png differ diff --git a/mods/farming/textures/farming_wheat_5.png b/mods/farming/textures/farming_wheat_5.png new file mode 100644 index 0000000..f40b5f0 Binary files /dev/null and b/mods/farming/textures/farming_wheat_5.png differ diff --git a/mods/farming/textures/farming_wheat_6.png b/mods/farming/textures/farming_wheat_6.png new file mode 100644 index 0000000..e9c78e0 Binary files /dev/null and b/mods/farming/textures/farming_wheat_6.png differ diff --git a/mods/farming/textures/farming_wheat_7.png b/mods/farming/textures/farming_wheat_7.png new file mode 100644 index 0000000..cc26ca9 Binary files /dev/null and b/mods/farming/textures/farming_wheat_7.png differ diff --git a/mods/farming/textures/farming_wheat_8.png b/mods/farming/textures/farming_wheat_8.png new file mode 100644 index 0000000..d050093 Binary files /dev/null and b/mods/farming/textures/farming_wheat_8.png differ diff --git a/mods/farming/textures/farming_wheat_seed.png b/mods/farming/textures/farming_wheat_seed.png new file mode 100644 index 0000000..a9031fb Binary files /dev/null and b/mods/farming/textures/farming_wheat_seed.png differ diff --git a/mods/farming/textures/strawberry.png b/mods/farming/textures/strawberry.png new file mode 100644 index 0000000..5b43e6b Binary files /dev/null and b/mods/farming/textures/strawberry.png differ diff --git a/mods/farming/textures/vessels_drinking_cup.png b/mods/farming/textures/vessels_drinking_cup.png new file mode 100644 index 0000000..2eba232 Binary files /dev/null and b/mods/farming/textures/vessels_drinking_cup.png differ diff --git a/mods/farming/utensils.lua b/mods/farming/utensils.lua new file mode 100644 index 0000000..09e14b9 --- /dev/null +++ b/mods/farming/utensils.lua @@ -0,0 +1,131 @@ + +local S = farming.intllib + +-- wooden bowl + +minetest.register_craftitem("farming:bowl", { + description = S("Wooden Bowl"), + inventory_image = "farming_bowl.png", + groups = {food_bowl = 1, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:bowl 4", + recipe = { + {"group:wood", "", "group:wood"}, + {"", "group:wood", ""}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "farming:bowl", + burntime = 10, +}) + +-- saucepan + +minetest.register_craftitem("farming:saucepan", { + description = S("Saucepan"), + inventory_image = "farming_saucepan.png", + groups = {food_saucepan = 1, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:saucepan", + recipe = { + {"default:steel_ingot", "", ""}, + {"", "group:stick", ""}, + } +}) + +-- cooking pot + +minetest.register_craftitem("farming:pot", { + description = S("Cooking Pot"), + inventory_image = "farming_pot.png", + groups = {food_pot = 1, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:pot", + recipe = { + {"group:stick", "default:steel_ingot", "default:steel_ingot"}, + {"", "default:steel_ingot", "default:steel_ingot"}, + } +}) + +-- baking tray + +minetest.register_craftitem("farming:baking_tray", { + description = S("Baking Tray"), + inventory_image = "farming_baking_tray.png", + groups = {food_baking_tray = 1, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:baking_tray", + recipe = { + {"default:clay_brick", "default:clay_brick", "default:clay_brick"}, + {"default:clay_brick", "", "default:clay_brick"}, + {"default:clay_brick", "default:clay_brick", "default:clay_brick"}, + } +}) + +-- skillet + +minetest.register_craftitem("farming:skillet", { + description = S("Skillet"), + inventory_image = "farming_skillet.png", + groups = {food_skillet = 1, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:skillet", + recipe = { + {"default:steel_ingot", "", ""}, + {"", "default:steel_ingot", ""}, + {"", "", "group:stick"}, + } +}) + +-- cutting board + +minetest.register_craftitem("farming:cutting_board", { + description = S("Cutting Board"), + inventory_image = "farming_cutting_board.png", + groups = {food_cutting_board = 1, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:cutting_board", + recipe = { + {"default:steel_ingot", "", ""}, + {"", "group:stick", ""}, + {"", "", "group:wood"}, + } +}) + +-- glass mixing bowl + +minetest.register_craftitem("farming:mixing_bowl", { + description = S("Glass Mixing Bowl"), + inventory_image = "farming_mixing_bowl.png", + groups = {food_mixing_bowl = 1, flammable = 2}, +}) + +minetest.register_craft({ + output = "farming:mixing_bowl", + recipe = { + {"default:glass", "group:stick", "default:glass"}, + {"", "default:glass", ""}, + } +}) + +minetest.register_craft( { + type = "shapeless", + output = "vessels:glass_fragments", + recipe = { + "farming:mixing_bowl", + }, +}) diff --git a/mods/filler/README.md b/mods/filler/README.md new file mode 100644 index 0000000..907eb9f --- /dev/null +++ b/mods/filler/README.md @@ -0,0 +1,20 @@ +# Filling Tool + +A simple mod which makes building easier. + +License: GPL-3.0 + +Dependencies: default + +Forum: https://forum.minetest.net/viewtopic.php?f=9&t=19524&p=311308#p309803 + + +How to use it: + + Hold sneak and right click to select a node. + + Right click to set position 1. + + Right click to set position 2. + + Left click. diff --git a/mods/filler/credits.txt b/mods/filler/credits.txt new file mode 100644 index 0000000..e6acc28 --- /dev/null +++ b/mods/filler/credits.txt @@ -0,0 +1,2 @@ +code by cx384 licensed GPL-3.0 +Wand texture by NathanS21 licensed CC by SA 4.0 diff --git a/mods/filler/description.txt b/mods/filler/description.txt new file mode 100644 index 0000000..82181a7 --- /dev/null +++ b/mods/filler/description.txt @@ -0,0 +1 @@ +Adds a Filling Tool which can fill areas. diff --git a/mods/filler/init.lua b/mods/filler/init.lua new file mode 100644 index 0000000..4bd8192 --- /dev/null +++ b/mods/filler/init.lua @@ -0,0 +1,427 @@ +filler = {} +filler.blacklist = {} +filler.endless_placeable = {} +filler.placing_from_top_to_bottom = {} +filler.blacklist["protector:protect"] = true +filler.blacklist["protector:protect2"] = true +--filler.endless_placeable["air"] = true +--filler.endless_placeable["default:water_source"] = true + +filler.placing_from_top_to_bottom["air"] = true + +local max_volume = 32^3 +local color_pos1 = "#ffbb00" +local color_pos2 = "#00bbff" +local speed = 0.1 +local sound_placing_failed = "default_item_smoke" --"default_cool_lava" --"default_tool_breaks" +local sound_set_pos = "default_place_node_hard" +local sound_scan_node = "default_dig_metal" +local marker_time = 4 +local ownercheck = false -- set to true makes the device belonging to one user only (anti_griefing) +local recipe_on = false -- tool can be crafted + +local mod_storage = minetest.get_mod_storage() + +local function add_rollback_storage(player, pos, node) + local t = minetest.deserialize(mod_storage:get_string(player.."_rollback_storage")) or {} + table.insert(t, 1, {pos = pos, node = node}) + mod_storage:set_string(player.."_rollback_storage", minetest.serialize(t)) +end + +local function get_rollback_storage(player) + local t = minetest.deserialize(mod_storage:get_string(player.."_rollback_storage")) or {} + local e = table.remove(t, 1) + mod_storage:set_string(player.."_rollback_storage", minetest.serialize(t)) + return e +end + +local function refresh_rollback_storage(player) + local t = minetest.deserialize(mod_storage:get_string(player.."_rollback_storage")) or {} + mod_storage:set_string(player.."_rollback_storage", nil) +end + +local function make_it_one(n) + if n<0 then n=-1 end + if n>0 then n=1 end + return n +end + +local function get_volume(pos1, pos2) + if not pos1 or not pos2 then + return 0 + end + local lv = vector.subtract(pos1, pos2) + return (math.abs(lv.x)+1) * (math.abs(lv.y)+1) * (math.abs(lv.z)+1) +end + +local function get_pos_infotext(pos1, pos2) + local lv = vector.subtract(pos1, pos2) + lv.x = math.abs(lv.x)+1 + lv.y = math.abs(lv.y)+1 + lv.z = math.abs(lv.z)+1 + local it = lv.x.."x"..lv.y.."x"..lv.z + local volume = lv.x*lv.y*lv.z + if volume > max_volume then + it = it.." = "..minetest.colorize("#ff0000", volume.." Blocks") + else + it = it.." = "..volume.." Blocks" + end + return it +end + +local function check_owner(itemstack,name) + local owner = itemstack:get_meta():get_string("owner") + if not owner or owner == "" then + itemstack:get_meta():set_string("owner", name) + end + + if owner ~= name then + minetest.chat_send_player(name, core.colorize("#ffbb00", ">>> This is not yours <<<")) + return false + end + + return true +end + +local function set_pos(itemstack, pos, player) + local pos_name = minetest.pos_to_string(pos) + local meta = itemstack:get_meta() + local turner = meta:get_int("turner") + local color = color_pos1 + local pos1 = minetest.string_to_pos(meta:get_string("pos1")) or {x=0,y=0,z=0} + local pos2 = minetest.string_to_pos(meta:get_string("pos2")) or {x=0,y=0,z=0} + if turner == 1 then + pos2 = pos + meta:set_string("pos2", pos_name) + color = color_pos2 + turner = 0 + else + pos1 = pos + meta:set_string("pos1", pos_name) + turner = 1 + end + meta:set_int("turner", turner) + minetest.chat_send_player(player:get_player_name(), + "Filling Tool: "..minetest.colorize(color, "Pos").. + " set to "..pos_name.." "..get_pos_infotext(pos1, pos2) + ) + minetest.sound_play({name = sound_set_pos}, {pos = pos}) + local pos_under = table.copy(pos) + pos_under.y = pos_under.y - 1 + if minetest.get_node(pos_under).name ~= "air" then + minetest.add_particle({ + pos = pos, + expirationtime = marker_time, + vertical = true, + size = 10, + texture = "default_mese_post_light_side.png^[multiply:"..color, + glow = 5 + }) + else + minetest.add_particle({ + pos = pos, + expirationtime = marker_time, + size = 5, + texture = "default_meselamp.png^[multiply:"..color, + glow = 5 + }) + end + return itemstack +end + +local function get_next_pos(cpos, bpos, epos, dpos) + if cpos.x ~= epos.x then + cpos.x = cpos.x + dpos.x + elseif cpos.z ~= epos.z then + cpos.z = cpos.z + dpos.z + cpos.x = bpos.x + elseif cpos.y ~= epos.y then + cpos.y = cpos.y + dpos.y + cpos.x = bpos.x + cpos.z = bpos.z + else + return false + end + return cpos +end + +local function pos_can_place(pos, node_name, player) + local node = minetest.get_node(pos).name + if node == "ignore" then + return false + end + local pnode = minetest.registered_nodes[node] + local node_under = minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y-1, z = pos.z}).name] + if not pnode or not pnode.buildable_to then + return false + elseif node_under and minetest.get_item_group(node_name, "attached_node") > 0 and + node_under.walkable == false then + return false + end + return true +end + +local function rollback_filling(player) + local player_name = player:get_player_name() + local inv = player:get_inventory() + if player:get_attribute("filler_deactivate") == "true" then + minetest.chat_send_player(player_name, "Filling Tool: Deactivated.") + player:set_attribute("filler_deactivate", "false") + player:set_attribute("filler_activated", "false") + return + end + local rollback_storage = get_rollback_storage(player_name) + if not rollback_storage or rollback_storage == {} then + player:set_attribute("filler_activated", "false") + return + end + local node = minetest.get_node(rollback_storage.pos) + while node.name ~= rollback_storage.node.name do + rollback_storage = get_rollback_storage(player_name) + if not rollback_storage or rollback_storage == {} then + player:set_attribute("filler_activated", "false") + return + end + node = minetest.get_node(rollback_storage.pos) + end + minetest.set_node(rollback_storage.pos, {name="air"}) -- this more save in case of clay and other things which change shape if dug + if inv:room_for_item("main", node.name) then + inv:add_item("main", node.name) -- in case of rollback, dug items should be returned + else + minetest.item_drop(ItemStack(node.name), player, rollback_storage.pos) + end + local node_sounds = minetest.registered_nodes[node.name].sounds + if node_sounds and node_sounds.dug then + minetest.sound_play(minetest.registered_nodes[node.name].sounds.dug, {pos = rollback_storage.pos}) + else + --minetest.sound_play("", {pos = rollback_storage.pos}) + end + minetest.after(speed, rollback_filling, player) +end + +local function fill_area(cpos, bpos, epos, node, player, dpos, inv) --cpos, dpos and inv to improve performance + local player_name = player:get_player_name() + if player:get_attribute("filler_deactivate") == "true" then + minetest.chat_send_player(player_name, "Filling Tool: Deactivated.") + player:set_attribute("filler_deactivate", "false") + player:set_attribute("filler_activated", "false") + return + end + while not pos_can_place(cpos, node.name) do + cpos = get_next_pos(cpos, bpos, epos, dpos) + if not cpos then + player:set_attribute("filler_activated", "false") + return + end -- finished + end + -- check if protected discrete + if minetest.is_protected(cpos, player_name) then + minetest.chat_send_player(player_name, + "Filling Tool:"..minetest.colorize("#ff0000", " Stop! ").. + "This area is protected!") + minetest.sound_play({name = sound_placing_failed}, {pos = cpos}) + player:set_attribute("filler_activated", "false") + return + end + if not inv:contains_item("main", node.name) and not filler.endless_placeable[node.name] and + not minetest.setting_getbool("creative_mode") then + minetest.chat_send_player(player_name, + "Filling Tool:"..minetest.colorize("#ff0000", " Stop! ").."You are out of ".. + '"'..minetest.registered_nodes[node.name].description..'"!') + minetest.sound_play({name = sound_placing_failed}, {pos = cpos}) + player:set_attribute("filler_activated", "false") + return + end + + -- place node + if not filler.endless_placeable[node.name] and not minetest.setting_getbool("creative_mode") then + inv:remove_item("main", node.name) + end + + -- works perfect but bad performance + minetest.item_place_node(ItemStack(node.name), player, {type="node", under=cpos, above=cpos}, node.param2) + + -- alternatives + --minetest.add_node(cpos, node) + --minetest.place_node(cpos, node) + + add_rollback_storage(player_name, cpos, node) + local node_sounds = minetest.registered_nodes[node.name].sounds + if node_sounds and node_sounds.place then + minetest.sound_play(minetest.registered_nodes[node.name].sounds.place, {pos = cpos}) + else + --minetest.sound_play("", {pos = cpos}) + end + + cpos = get_next_pos(cpos, bpos, epos, dpos) + if not cpos then + player:set_attribute("filler_activated", "false") + return + end -- finished + minetest.after(speed, fill_area, cpos, bpos, epos, node, player, dpos, inv) +end + +local function set_wear(itemstack, level, max_level) + local temp + if level == 0 then + temp = 0 + else + temp = 65536 - math.floor(level / max_level * 65535) + if temp > 65535 then temp = 65535 end + if temp < 1 then temp = 1 end + end + itemstack:set_wear(temp) +end + +local function get_wear(itemstack) + if itemstack:get_metadata() == "" then + return 100 + else + return tonumber(itemstack:get_metadata()) + end +end + +minetest.register_tool("filler:filler", { + description = "Filling Tool", + inventory_image = "filler_filler.png", + light_source = 10, + + on_place = function(itemstack, placer, pointed_thing) + if not pointed_thing.type == "node" then + return itemstack + end + if placer:get_player_control().sneak == true then + local node = minetest.get_node(pointed_thing.under) + if not minetest.registered_nodes[node.name] then + return itemstack + end + itemstack:get_meta():set_string("node", minetest.serialize(node)) + minetest.chat_send_player(placer:get_player_name(), + "Filling Tool: Node set to ".. + '"'..minetest.registered_nodes[node.name].description..'"') + minetest.sound_play({name = sound_scan_node}, {pos = pointed_thing.under}) + else + return set_pos(itemstack, pointed_thing.above, placer) + end + return itemstack + end, + on_secondary_use = function(itemstack, user) + local pos = vector.round(user:get_pos()) + if user:get_player_control().sneak == true then + local node = minetest.get_node(pos) + if not minetest.registered_nodes[node.name] then + return itemstack + end + itemstack:get_meta():set_string("node", minetest.serialize(node)) + minetest.chat_send_player(user:get_player_name(), + "Filling Tool: Node set to ".. + '"'..minetest.registered_nodes[node.name].description..'"') + minetest.sound_play({name = sound_scan_node}, {pos = pos}) + else + return set_pos(itemstack, pos, user) + end + return itemstack + end, + on_use = function(itemstack, user, pointed_thing) + local uses = get_wear(itemstack) + if uses == 0 then + itemstack:set_name('') + return itemstack end + local player_name = user:get_player_name() + if user:get_attribute("filler_activated") == "true" then + minetest.chat_send_player(player_name, "Filling Tool: The filling tool is currently working.".. + " (You can hold sneak and left click to deactivate it.)") + if user:get_player_control().sneak == true then + user:set_attribute("filler_deactivate", "true") + end + return + end + local meta = itemstack:get_meta() + local pos1 = minetest.string_to_pos(meta:get_string("pos1")) + local pos2 = minetest.string_to_pos(meta:get_string("pos2")) + local node = minetest.deserialize(meta:get_string("node")) + local volume = get_volume(pos1, pos2) + if not user then return end + local inv = user:get_inventory() + + -- Ownercheck added here. + if ownercheck and not check_owner(itemstack,player_name) then + return itemstack + end + -- End Ownercheck + + if not node then + minetest.chat_send_player(player_name, "Filling Tool: Hold sneak and right click to select a node.") + return + end + if not pos1 or not pos2 then + minetest.chat_send_player(player_name, "Filling Tool: Right click to set coordinates.") + return + end + if volume > max_volume then + minetest.chat_send_player(player_name, "Filling Tool: This area is too big.") + return + end + if filler.blacklist[node.name] == true then + minetest.chat_send_player(player_name, 'Filling Tool: "'.. + minetest.registered_nodes[node.name].description..'"'.." can't be placed with the filling tool.") + return + end + local bpos = table.copy(pos1) + local epos = table.copy(pos2) + local cdpos = 1 + if filler.placing_from_top_to_bottom[node.name] == true then + cdpos = -1 + if pos1.y < pos2.y then + bpos = table.copy(pos2) + epos = table.copy(pos1) + end + else + if pos1.y > pos2.y then + bpos = table.copy(pos2) + epos = table.copy(pos1) + end + end + local cpos = table.copy(bpos) + local dpos = vector.direction(bpos, epos) + dpos.x = make_it_one(dpos.x) + dpos.y = cdpos + dpos.z = make_it_one(dpos.z) + refresh_rollback_storage(player_name) + user:set_attribute("filler_activated", "true") + fill_area(cpos, bpos, epos, node, user, dpos, inv) + uses = uses - 1 + itemstack:set_metadata(tostring(uses)) + set_wear(itemstack, uses, 100) + return itemstack + end, +}) + +minetest.register_chatcommand("rsq", { + description = "Revert the last filling action", + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player:get_attribute("filler_activated") == "true" then + minetest.chat_send_player(name, "Filling Tool: The filling tool is currently working.".. + " (You can hold sneak and left click to deactivate it.)") + return + end + player:set_attribute("filler_activated", "true") + rollback_filling(player) + end +}) + +minetest.register_on_joinplayer(function(player) + player:set_attribute("filler_activated", "false") +end) + +if recipe_on then -- this tool is a bit dangerous on multiplayer servers + minetest.register_craft({ + output = 'filler:filler', + recipe = { + {'', 'default:mese_post_light', 'default:diamond'}, + {'', 'default:steel_ingot', 'default:mese_post_light'}, + {'group:stick', '', ''}, + } + }) +end diff --git a/mods/filler/license.txt b/mods/filler/license.txt new file mode 100644 index 0000000..e3c1109 --- /dev/null +++ b/mods/filler/license.txt @@ -0,0 +1 @@ +License: GPL-3.0 by cx384 diff --git a/mods/filler/mod.conf b/mods/filler/mod.conf new file mode 100644 index 0000000..b15a6af --- /dev/null +++ b/mods/filler/mod.conf @@ -0,0 +1,2 @@ +name = filler +depends = default diff --git a/mods/filler/textures/filler_filler.png b/mods/filler/textures/filler_filler.png new file mode 100644 index 0000000..1980f4f Binary files /dev/null and b/mods/filler/textures/filler_filler.png differ diff --git a/mods/filter/LICENSE b/mods/filter/LICENSE new file mode 100644 index 0000000..d45568b --- /dev/null +++ b/mods/filter/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2017-8 Auke Kok +Copyright (c) 2018 rubenwardy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mods/filter/depends.txt b/mods/filter/depends.txt new file mode 100644 index 0000000..6f0ae6b --- /dev/null +++ b/mods/filter/depends.txt @@ -0,0 +1,2 @@ +rules? +email? diff --git a/mods/filter/description.txt b/mods/filter/description.txt new file mode 100644 index 0000000..62a58fd --- /dev/null +++ b/mods/filter/description.txt @@ -0,0 +1 @@ +A chat filter for servers. diff --git a/mods/filter/init.lua b/mods/filter/init.lua new file mode 100644 index 0000000..2808d6f --- /dev/null +++ b/mods/filter/init.lua @@ -0,0 +1,249 @@ + +--[[ + + Copyright 2017-8 Auke Kok + Copyright 2018 rubenwardy + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject + to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +]]-- + +filter = { registered_on_violations = {} } +local words = {} +local muted = {} +local violations = {} +local s = minetest.get_mod_storage() + +function filter.init() + local sw = s:get_string("words") + if sw and sw ~= "" then + words = minetest.parse_json(sw) + end + + if #words == 0 then + filter.import_file(minetest.get_modpath("filter") .. "/words.txt") + end +end + +function filter.import_file(filepath) + local file = io.open(filepath, "r") + if file then + for line in file:lines() do + line = line:trim() + if line ~= "" then + words[#words + 1] = line:trim() + end + end + return true + else + return false + end +end + +function filter.register_on_violation(func) + table.insert(filter.registered_on_violations, func) +end + +function filter.check_message(name, message) + for _, w in ipairs(words) do + if string.find(message:lower(), "%f[%a]" .. w .. "%f[%A]") then + return false + end + end + + return true +end + +function filter.mute(name, duration) + do + local privs = minetest.get_player_privs(name) + privs.shout = nil + minetest.set_player_privs(name, privs) + end + + minetest.chat_send_player(name, "Watch your language! You have been temporarily muted") + + muted[name] = true + + minetest.after(duration * 60, function() + privs = minetest.get_player_privs(name) + if privs.shout == true then + return + end + + muted[name] = nil + minetest.chat_send_player(name, "Chat privilege reinstated. Please do not abuse chat.") + + privs.shout = true + minetest.set_player_privs(name, privs) + end) +end + +function filter.show_warning_formspec(name) + local formspec = "size[7,3]bgcolor[#080808BB;true]" .. default.gui_bg .. default.gui_bg_img .. [[ + image[0,0;2,2;filter_warning.png] + label[2.3,0.5;Please watch your language!] + ]] + + if minetest.global_exists("rules") and rules.show then + formspec = formspec .. [[ + button[0.5,2.1;3,1;rules;Show Rules] + button_exit[3.5,2.1;3,1;close;Okay] + ]] + else + formspec = formspec .. [[ + button_exit[2,2.1;3,1;close;Okay] + ]] + end + minetest.show_formspec(name, "filter:warning", formspec) +end + +function filter.on_violation(name, message) + violations[name] = (violations[name] or 0) + 1 + + local resolution + + for _, cb in pairs(filter.registered_on_violations) do + if cb(name, message, violations) then + resolution = "custom" + end + end + + if not resolution then + if violations[name] == 1 and minetest.get_player_by_name(name) then + resolution = "warned" + filter.show_warning_formspec(name) + elseif violations[name] <= 3 then + resolution = "muted" + filter.mute(name, 1) + else + resolution = "kicked" + minetest.kick_player(name, "Please mind your language!") + end + end + + local logmsg = "VIOLATION (" .. resolution .. "): <" .. name .. "> ".. message + minetest.log("action", logmsg) + + local email_to = minetest.settings:get("filter.email_to") + if email_to and minetest.global_exists("email") then + email.send_mail(name, email_to, logmsg) + end +end + +table.insert(minetest.registered_on_chat_messages, 1, function(name, message) + if message:sub(1, 1) == "/" then + return + end + + local privs = minetest.get_player_privs(name) + if not privs.shout and muted[name] then + minetest.chat_send_player(name, "You are temporarily muted.") + return true + end + + if not filter.check_message(name, message) then + filter.on_violation(name, message) + return true + end +end) + + +local function make_checker(old_func) + return function(name, param) + if not filter.check_message(name, param) then + filter.on_violation(name, param) + return false + end + + return old_func(name, param) + end +end + +for name, def in pairs(minetest.registered_chatcommands) do + if def.privs and def.privs.shout then + def.func = make_checker(def.func) + end +end + +local old_register_chatcommand = minetest.register_chatcommand +function minetest.register_chatcommand(name, def) + if def.privs and def.privs.shout then + def.func = make_checker(def.func) + end + return old_register_chatcommand(name, def) +end + + +local function step() + for name, v in pairs(violations) do + violations[name] = math.floor(v * 0.5) + if violations[name] < 1 then + violations[name] = nil + end + end + minetest.after(10*60, step) +end +minetest.after(10*60, step) + +minetest.register_chatcommand("filter", { + params = "filter server", + description = "manage swear word filter", + privs = {server = true}, + func = function(name, param) + local cmd, val = param:match("(%w+) (.+)") + if param == "list" then + return true, #words .. " words: " .. table.concat(words, ", ") + elseif cmd == "add" then + table.insert(words, val) + s:set_string("words", minetest.write_json(words)) + return true, "Added \"" .. val .. "\"." + elseif cmd == "remove" then + for i, w in ipairs(words) do + if w == val then + table.remove(words, i) + s:set_string("words", minetest.write_json(words)) + return true, "Removed \"" .. val .. "\"." + end + end + return true, "\"" .. val .. "\" not found in list." + else + return true, "I know " .. #words .. " words.\nUsage: /filter []" + end + end, +}) + +if minetest.global_exists("rules") and rules.show then + minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname == "filter:warning" and fields.rules then + rules.show(player) + end + end) +end + +minetest.register_on_shutdown(function() + for name, _ in pairs(muted) do + local privs = minetest.get_player_privs(name) + privs.shout = true + minetest.set_player_privs(name, privs) + end +end) + +filter.init() diff --git a/mods/filter/mod.conf b/mods/filter/mod.conf new file mode 100644 index 0000000..35063b6 --- /dev/null +++ b/mods/filter/mod.conf @@ -0,0 +1,3 @@ +name = filter +description = A chat filter for servers. +optional_depends = rules,email diff --git a/mods/filter/readme.md b/mods/filter/readme.md new file mode 100644 index 0000000..27293e2 --- /dev/null +++ b/mods/filter/readme.md @@ -0,0 +1,38 @@ +# filter mod + +This mod adds a simple chat filter. There is no default word list, +and adding words to the filter list is done through the `/filter` +chat command. You need the `server` priv to use the chat command. + +The `/filter` chat command can `add`, `remove` or `list` words. The +words are stored in `mod_storage`, which means that this mod requires +0.4.16 or above to function. + +If a player speaks a word that is listed in the filter list, they are +muted for 1 minute. After that, their `shout` privilege is restored. +If they leave, their `shout` privilege is still restored, but only after +the time expires, not before. + +## API + +### Callbacks + +* filter.register_on_violation(func(name, message, violations)) + * Violations is the value of the player's violation counter - which is + incremented on a violation, and halved every 10 minutes. + * Return true if you've handled the violation. No more callbacks will be + executation, and the default behaviour (warning/mute/kick) on violation + will be skipped. + +### Methods + +* filter.import_file(path) + * Input bad words from a file (`path`) where each line is a new word. +* filter.check_message(name, message) + * Checks message for violation. Returns true if okay, false if bad. + If it returns false, you should cancel the sending of the message and + call filter.on_violation() +* filter.on_violation(name, message) + * Increments violation count, runs callbacks, and punishes the players. +* filter.mute(name, duration) +* filter.show_warning_formspec(name) diff --git a/mods/filter/screenshot.png b/mods/filter/screenshot.png new file mode 100644 index 0000000..61b0771 Binary files /dev/null and b/mods/filter/screenshot.png differ diff --git a/mods/filter/textures/filter_warning.png b/mods/filter/textures/filter_warning.png new file mode 100644 index 0000000..da4ea7b Binary files /dev/null and b/mods/filter/textures/filter_warning.png differ diff --git a/mods/fire/README.txt b/mods/fire/README.txt new file mode 100644 index 0000000..25ba26e --- /dev/null +++ b/mods/fire/README.txt @@ -0,0 +1,35 @@ +Minetest Game mod: fire +======================= +See license.txt for license information. + +Authors of source code +---------------------- +Originally by Perttu Ahola (celeron55) (LGPLv2.1+) +Various Minetest developers and contributors (LGPLv2.1+) + +Authors of media (textures and sounds) +-------------------------------------- +Everything not listed in here: +Copyright (C) 2012 Perttu Ahola (celeron55) (CC BY-SA 3.0) + +Muadtralk (CC BY-SA 3.0) + fire_basic_flame_animated.png + +Gambit (CC BY-SA 3.0) + fire_flint_steel.png + +dobroide (CC BY 3.0) +http://www.freesound.org/people/dobroide/sounds/4211/ + fire_small.ogg + +Dynamicell (CC BY 3.0) +http://www.freesound.org/people/Dynamicell/sounds/17548/ + fire_large.ogg + fire_fire.*.ogg + +fire_small.ogg and fire_large.ogg are unused but kept temporarily to not break +other mods that may use them. + +Benboncan (CC BY 3.0) +https://www.freesound.org/people/Benboncan/sounds/66457/ + fire_flint_and_steel.ogg diff --git a/mods/fire/init.lua b/mods/fire/init.lua new file mode 100644 index 0000000..1beb7b5 --- /dev/null +++ b/mods/fire/init.lua @@ -0,0 +1,379 @@ +-- fire/init.lua + +-- Global namespace for functions + +fire = {} + +-- Load support for MT game translation. +local S = minetest.get_translator('fire') + + +-- 'Enable fire' setting + +local fire_enabled = minetest.settings:get_bool('enable_fire') +if fire_enabled == nil then + -- enable_fire setting not specified, check for disable_fire + local fire_disabled = minetest.settings:get_bool('disable_fire') + if fire_disabled == nil then + -- Neither setting specified, check whether singleplayer + fire_enabled = minetest.is_singleplayer() + else + fire_enabled = not fire_disabled + end +end + +-- +-- Items +-- + +-- Flood flame function + +local function flood_flame(pos, oldnode, newnode) + -- Play flame extinguish sound if liquid is not an 'igniter' + local nodedef = minetest.registered_items[newnode.name] + if not (nodedef and nodedef.groups and + nodedef.groups.igniter and nodedef.groups.igniter > 0) then + minetest.sound_play('fire_extinguish_flame', + {pos = pos, max_hear_distance = 16, gain = 0.15}) + end + -- Remove the flame + return false +end + +-- Flame nodes + +minetest.register_node('fire:basic_flame', { + drawtype = 'firelike', + tiles = { + { + name = 'fire_basic_flame_animated.png', + animation = { + type = 'vertical_frames', + aspect_w = 16, + aspect_h = 16, + length = 1 + }, + }, + }, + inventory_image = 'fire_basic_flame.png', + paramtype = 'light', + light_source = 13, + walkable = false, + buildable_to = true, + sunlight_propagates = true, + floodable = true, + damage_per_second = 4, + groups = {igniter = 2, dig_immediate = 3, not_in_creative_inventory = 1}, + drop = '', + + on_timer = function(pos) + local f = minetest.find_node_near(pos, 1, {'group:flammable'}) + if not fire_enabled or not f then + minetest.remove_node(pos) + return + end + -- Restart timer + return true + end, + + on_construct = function(pos) + if not fire_enabled then + minetest.remove_node(pos) + else + minetest.get_node_timer(pos):start(math.random(30, 60)) + end + end, + + on_flood = flood_flame, + + on_punch = function(pos, node, puncher) + minetest.remove_node(pos) + minetest.log('action', puncher:get_player_name()..' put out fire at '..minetest.pos_to_string(pos)) + end, +}) + +minetest.register_node('fire:permanent_flame', { + description = S('Permanent Flame'), + drawtype = 'firelike', + tiles = { + { + name = 'fire_basic_flame_animated.png', + animation = { + type = 'vertical_frames', + aspect_w = 16, + aspect_h = 16, + length = 1 + }, + }, + }, + inventory_image = 'fire_basic_flame.png', + paramtype = 'light', + light_source = 13, + walkable = false, + buildable_to = true, + sunlight_propagates = true, + floodable = true, + damage_per_second = 4, + groups = {igniter = 2, dig_immediate = 3}, + drop = '', + + on_flood = flood_flame, +}) + + +-- Flint and steel + +minetest.register_tool('fire:flint_and_steel', { + description = S('Flint and Steel'), + inventory_image = 'fire_flint_steel.png', + sound = {breaks = 'default_tool_breaks'}, + + on_use = function(itemstack, user, pointed_thing) + local sound_pos = pointed_thing.above or user:get_pos() + minetest.sound_play( + 'fire_flint_and_steel', + {pos = sound_pos, gain = 0.5, max_hear_distance = 8} + ) + local player_name = user:get_player_name() + if minetest.check_player_privs(player_name, { fire = true }) then + 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 + 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(pointed_thing.under, user) + elseif minetest.get_item_group(node_under, 'flammable') >= 1 + and minetest.get_node(pointed_thing.above).name == 'air' then + minetest.set_node(pointed_thing.above, {name = 'fire:basic_flame'}) + minetest.log('action', 'Player '..player_name..' started a fire.') + end + end + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(player_name)) then + -- Wear tool + local wdef = itemstack:get_definition() + 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 = sound_pos, gain = 0.5}) + end + return itemstack + end + end + end +}) + +minetest.register_craft({ + output = 'fire:flint_and_steel', + recipe = { + {'default:flint', 'default:steel_ingot'} + } +}) + + +-- Override coalblock to enable permanent flame above +-- Coalblock is non-flammable to avoid unwanted basic_flame nodes + +minetest.override_item('default:coalblock', { + after_destruct = function(pos, oldnode) + pos.y = pos.y + 1 + if minetest.get_node(pos).name == 'fire:permanent_flame' then + minetest.remove_node(pos) + end + end, + on_ignite = function(pos, igniter) + local flame_pos = {x = pos.x, y = pos.y + 1, z = pos.z} + if minetest.get_node(flame_pos).name == 'air' then + minetest.set_node(flame_pos, {name = 'fire:permanent_flame'}) + end + end, +}) + + +-- +-- Sound +-- + +local flame_sound = minetest.settings:get_bool('flame_sound') +if flame_sound == nil then + -- Enable if no setting present + flame_sound = true +end + +if flame_sound then + + local handles = {} + local timer = 0 + + -- Parameters + + local radius = 8 -- Flame node search radius around player + local cycle = 3 -- Cycle time for sound updates + + -- Update sound for player + + function fire.update_player_sound(player) + local player_name = player:get_player_name() + -- Search for flame nodes in radius around player + local ppos = player:get_pos() + local areamin = vector.subtract(ppos, radius) + local areamax = vector.add(ppos, radius) + local fpos, num = minetest.find_nodes_in_area( + areamin, + areamax, + {'fire:basic_flame', 'fire:permanent_flame'} + ) + -- Total number of flames in radius + local flames = (num['fire:basic_flame'] or 0) + + (num['fire:permanent_flame'] or 0) + -- Stop previous sound + if handles[player_name] then + minetest.sound_stop(handles[player_name]) + handles[player_name] = nil + end + -- If flames + if flames > 0 then + -- Find centre of flame positions + local fposmid = fpos[1] + -- If more than 1 flame + if #fpos > 1 then + local fposmin = areamax + local fposmax = areamin + for i = 1, #fpos do + local fposi = fpos[i] + if fposi.x > fposmax.x then + fposmax.x = fposi.x + end + if fposi.y > fposmax.y then + fposmax.y = fposi.y + end + if fposi.z > fposmax.z then + fposmax.z = fposi.z + end + if fposi.x < fposmin.x then + fposmin.x = fposi.x + end + if fposi.y < fposmin.y then + fposmin.y = fposi.y + end + if fposi.z < fposmin.z then + fposmin.z = fposi.z + end + end + fposmid = vector.divide(vector.add(fposmin, fposmax), 2) + end + -- Play sound + local handle = minetest.sound_play( + 'fire_fire', + { + pos = fposmid, + to_player = player_name, + gain = math.min(0.06 * (1 + flames * 0.125), 0.18), + max_hear_distance = 32, + loop = true, -- In case of lag + } + ) + -- Store sound handle for this player + if handle then + handles[player_name] = handle + end + end + end + + -- Cycle for updating players sounds + + minetest.register_globalstep(function(dtime) + timer = timer + dtime + if timer < cycle then + return + end + + timer = 0 + local players = minetest.get_connected_players() + for n = 1, #players do + fire.update_player_sound(players[n]) + end + end) + + -- Stop sound and clear handle on player leave + + minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + if handles[player_name] then + minetest.sound_stop(handles[player_name]) + handles[player_name] = nil + end + end) +end + + +-- Deprecated function kept temporarily to avoid crashes if mod fire nodes call it + +function fire.update_sounds_around(pos) +end + + +-- +-- ABMs +-- + +if fire_enabled then + + -- Ignite neighboring nodes, add basic flames + + minetest.register_abm({ + label = 'Ignite flame', + nodenames = {'group:flammable'}, + neighbors = {'group:igniter'}, + interval = 7, + chance = 12, + catch_up = false, + action = function(pos) + local flammable_node = minetest.get_node(pos) + local def = minetest.registered_nodes[flammable_node.name] + if def.on_ignite then + def.on_ignite(pos) + end + local p = minetest.find_node_near(pos, 1, {'air'}) + local anti_fire = minetest.find_node_near(pos, 1, {'epic:fire_extinguishing_powder'}) + if p then + minetest.set_node(p, {name = 'fire:basic_flame'}) + elseif anti_fire then + epic.spray_foam(pos) + minetest.remove_node(pos) + end + end, + }) + + -- Remove flammable nodes around basic flame + + minetest.register_abm({ + label = 'Remove flammable nodes', + nodenames = {'fire:basic_flame'}, + neighbors = 'group:flammable', + interval = 5, + chance = 18, + catch_up = false, + action = function(pos) + local p = minetest.find_node_near(pos, 1, {'group:flammable'}) + if not p then + return + end + local flammable_node = minetest.get_node(p) + local def = minetest.registered_nodes[flammable_node.name] + if def.on_burn then + def.on_burn(p) + else + minetest.remove_node(p) + minetest.check_for_falling(p) + end + end, + }) + +end diff --git a/mods/fire/license.txt b/mods/fire/license.txt new file mode 100644 index 0000000..43f9cd7 --- /dev/null +++ b/mods/fire/license.txt @@ -0,0 +1,84 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2012-2016 celeron55, Perttu Ahola +Copyright (C) 2012-2016 Various Minetest developers and contributors + +This program 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 program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures and sounds) +--------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Muadtralk +Copyright (C) 2013-2016 Gambit + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ + +----------------------- + +Attribution 3.0 Unported (CC BY 3.0) +Copyright (C) 2005 dobroide +Copyright (C) 2006 Dynamicell +Copyright (C) 2009 Benboncan + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by/3.0/ diff --git a/mods/fire/locale/fire.de.tr b/mods/fire/locale/fire.de.tr new file mode 100644 index 0000000..d6f8dde --- /dev/null +++ b/mods/fire/locale/fire.de.tr @@ -0,0 +1,3 @@ +# textdomain: fire +Permanent Flame=Permanente Flamme +Flint and Steel=Feuerstein und Stahl diff --git a/mods/fire/locale/fire.es.tr b/mods/fire/locale/fire.es.tr new file mode 100644 index 0000000..8c1b604 --- /dev/null +++ b/mods/fire/locale/fire.es.tr @@ -0,0 +1,3 @@ +# textdomain: fire +Permanent Flame=Llama permanente +Flint and Steel=Yesca y pedernal diff --git a/mods/fire/locale/fire.fr.tr b/mods/fire/locale/fire.fr.tr new file mode 100644 index 0000000..268e823 --- /dev/null +++ b/mods/fire/locale/fire.fr.tr @@ -0,0 +1,3 @@ +# textdomain: fire +Permanent Flame=Flamme permanente +Flint and Steel=Briquet à silex en acier diff --git a/mods/fire/locale/fire.it.tr b/mods/fire/locale/fire.it.tr new file mode 100644 index 0000000..03e8c87 --- /dev/null +++ b/mods/fire/locale/fire.it.tr @@ -0,0 +1,3 @@ +# textdomain: fire +Permanent Flame=Fiamma permanente +Flint and Steel=Acciarino \ No newline at end of file diff --git a/mods/fire/locale/fire.ms.tr b/mods/fire/locale/fire.ms.tr new file mode 100644 index 0000000..67b5bbe --- /dev/null +++ b/mods/fire/locale/fire.ms.tr @@ -0,0 +1,3 @@ +# textdomain: fire +Permanent Flame=Api Abadi +Flint and Steel=Pemetik Api diff --git a/mods/fire/locale/fire.ru.tr b/mods/fire/locale/fire.ru.tr new file mode 100644 index 0000000..e10813b --- /dev/null +++ b/mods/fire/locale/fire.ru.tr @@ -0,0 +1,3 @@ +# textdomain: fire +Permanent Flame=Вечный Огонь +Flint and Steel=Огниво и Сталь diff --git a/mods/fire/locale/fire.se.tr b/mods/fire/locale/fire.se.tr new file mode 100644 index 0000000..622925d --- /dev/null +++ b/mods/fire/locale/fire.se.tr @@ -0,0 +1,3 @@ +# textdomain: fire +Permanent Flame=Permanent Eld +Flint and Steel=Flinta och StÃ¥l \ No newline at end of file diff --git a/mods/fire/locale/template.txt b/mods/fire/locale/template.txt new file mode 100644 index 0000000..79ea7a2 --- /dev/null +++ b/mods/fire/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: fire +Permanent Flame= +Flint and Steel= diff --git a/mods/fire/mod.conf b/mods/fire/mod.conf new file mode 100644 index 0000000..c70f23b --- /dev/null +++ b/mods/fire/mod.conf @@ -0,0 +1,3 @@ +name = fire +description = Minetest Game mod: fire +depends = default diff --git a/mods/fire/sounds/fire_extinguish_flame.1.ogg b/mods/fire/sounds/fire_extinguish_flame.1.ogg new file mode 100644 index 0000000..42506dd Binary files /dev/null and b/mods/fire/sounds/fire_extinguish_flame.1.ogg differ diff --git a/mods/fire/sounds/fire_extinguish_flame.2.ogg b/mods/fire/sounds/fire_extinguish_flame.2.ogg new file mode 100644 index 0000000..2747ab8 Binary files /dev/null and b/mods/fire/sounds/fire_extinguish_flame.2.ogg differ diff --git a/mods/fire/sounds/fire_extinguish_flame.3.ogg b/mods/fire/sounds/fire_extinguish_flame.3.ogg new file mode 100644 index 0000000..8baeac3 Binary files /dev/null and b/mods/fire/sounds/fire_extinguish_flame.3.ogg differ diff --git a/mods/fire/sounds/fire_fire.1.ogg b/mods/fire/sounds/fire_fire.1.ogg new file mode 100644 index 0000000..cbfee4c Binary files /dev/null and b/mods/fire/sounds/fire_fire.1.ogg differ diff --git a/mods/fire/sounds/fire_fire.2.ogg b/mods/fire/sounds/fire_fire.2.ogg new file mode 100644 index 0000000..e8d0eb1 Binary files /dev/null and b/mods/fire/sounds/fire_fire.2.ogg differ diff --git a/mods/fire/sounds/fire_fire.3.ogg b/mods/fire/sounds/fire_fire.3.ogg new file mode 100644 index 0000000..5cad3d9 Binary files /dev/null and b/mods/fire/sounds/fire_fire.3.ogg differ diff --git a/mods/fire/sounds/fire_flint_and_steel.ogg b/mods/fire/sounds/fire_flint_and_steel.ogg new file mode 100644 index 0000000..6996e16 Binary files /dev/null and b/mods/fire/sounds/fire_flint_and_steel.ogg differ diff --git a/mods/fire/sounds/fire_large.ogg b/mods/fire/sounds/fire_large.ogg new file mode 100644 index 0000000..fe78e62 Binary files /dev/null and b/mods/fire/sounds/fire_large.ogg differ diff --git a/mods/fire/sounds/fire_small.ogg b/mods/fire/sounds/fire_small.ogg new file mode 100644 index 0000000..5aac595 Binary files /dev/null and b/mods/fire/sounds/fire_small.ogg differ diff --git a/mods/fire/textures/fire_basic_flame.png b/mods/fire/textures/fire_basic_flame.png new file mode 100644 index 0000000..1da0702 Binary files /dev/null and b/mods/fire/textures/fire_basic_flame.png differ diff --git a/mods/fire/textures/fire_basic_flame_animated.png b/mods/fire/textures/fire_basic_flame_animated.png new file mode 100644 index 0000000..1cdd9fd Binary files /dev/null and b/mods/fire/textures/fire_basic_flame_animated.png differ diff --git a/mods/fire/textures/fire_flint_steel.png b/mods/fire/textures/fire_flint_steel.png new file mode 100644 index 0000000..c262ebc Binary files /dev/null and b/mods/fire/textures/fire_flint_steel.png differ diff --git a/mods/fireflies/README.txt b/mods/fireflies/README.txt new file mode 100644 index 0000000..7382578 --- /dev/null +++ b/mods/fireflies/README.txt @@ -0,0 +1,22 @@ +Minetest Game mod: fireflies +============================ +Adds fireflies to the world on mapgen, which can then be caught in a net and placed in +bottles to provide light. + +Authors of source code +---------------------- +Shara RedCat (MIT) + +Authors of media (textures) +--------------------------- +Shara RedCat (CC BY-SA 3.0): + fireflies_firefly.png + fireflies_firefly_animated.png + fireflies_bugnet.png + fireflies_bottle.png + fireflies_bottle_animated.png + +fireflies_bugnet.png is modified from a texture by tenplus1 (CC0) + +fireflies_bottle.png and fireflies_bottle_animated.png are +modified from a texture by Vanessa Ezekowitz (CC BY-SA 3.0) \ No newline at end of file diff --git a/mods/fireflies/init.lua b/mods/fireflies/init.lua new file mode 100644 index 0000000..1c533a1 --- /dev/null +++ b/mods/fireflies/init.lua @@ -0,0 +1,290 @@ +-- firefly/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("fireflies") + + +minetest.register_node("fireflies:firefly", { + description = S("Firefly"), + drawtype = "plantlike", + tiles = {{ + name = "fireflies_firefly_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.5 + }, + }}, + inventory_image = "fireflies_firefly.png", + wield_image = "fireflies_firefly.png", + waving = 1, + paramtype = "light", + sunlight_propagates = true, + buildable_to = true, + walkable = false, + groups = {catchable = 1}, + selection_box = { + type = "fixed", + fixed = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1}, + }, + light_source = 6, + floodable = true, + on_place = function(itemstack, placer, pointed_thing) + local player_name = placer:get_player_name() + local pos = pointed_thing.above + + if not minetest.is_protected(pos, player_name) and + not minetest.is_protected(pointed_thing.under, player_name) and + minetest.get_node(pos).name == "air" then + minetest.set_node(pos, {name = "fireflies:firefly"}) + minetest.get_node_timer(pos):start(1) + itemstack:take_item() + end + return itemstack + end, + on_timer = function(pos, elapsed) + if minetest.get_node_light(pos) > 11 then + minetest.set_node(pos, {name = "fireflies:hidden_firefly"}) + end + minetest.get_node_timer(pos):start(30) + end +}) + +minetest.register_node("fireflies:hidden_firefly", { + description = S("Hidden Firefly"), + drawtype = "airlike", + inventory_image = "fireflies_firefly.png", + wield_image = "fireflies_firefly.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + groups = {not_in_creative_inventory = 1}, + floodable = true, + on_place = function(itemstack, placer, pointed_thing) + local player_name = placer:get_player_name() + local pos = pointed_thing.above + + if not minetest.is_protected(pos, player_name) and + not minetest.is_protected(pointed_thing.under, player_name) and + minetest.get_node(pos).name == "air" then + minetest.set_node(pos, {name = "fireflies:hidden_firefly"}) + minetest.get_node_timer(pos):start(1) + itemstack:take_item() + end + return itemstack + end, + on_timer = function(pos, elapsed) + if minetest.get_node_light(pos) <= 11 then + minetest.set_node(pos, {name = "fireflies:firefly"}) + end + minetest.get_node_timer(pos):start(30) + end +}) + + +-- bug net +minetest.register_tool("fireflies:bug_net", { + description = S("Bug Net"), + inventory_image = "fireflies_bugnet.png", + on_use = function(itemstack, player, pointed_thing) + if not pointed_thing or pointed_thing.type ~= "node" or + minetest.is_protected(pointed_thing.under, player:get_player_name()) then + return + end + local node_name = minetest.get_node(pointed_thing.under).name + local inv = player:get_inventory() + if minetest.get_item_group(node_name, "catchable") == 1 then + minetest.set_node(pointed_thing.under, {name = "air"}) + local stack = ItemStack(node_name.." 1") + local leftover = inv:add_item("main", stack) + if leftover:get_count() > 0 then + minetest.add_item(pointed_thing.under, node_name.." 1") + end + end + if not (creative and creative.is_enabled_for(player:get_player_name())) then + itemstack:add_wear(256) + return itemstack + end + end +}) + +minetest.register_craft( { + output = "fireflies:bug_net", + recipe = { + {"farming:string", "farming:string"}, + {"farming:string", "farming:string"}, + {"group:stick", ""} + } +}) + + +-- firefly in a bottle +minetest.register_node("fireflies:firefly_bottle", { + description = S("Firefly in a Bottle"), + inventory_image = "fireflies_bottle.png", + wield_image = "fireflies_bottle.png", + tiles = {{ + name = "fireflies_bottle_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1.5 + }, + }}, + drawtype = "plantlike", + paramtype = "light", + sunlight_propagates = true, + light_source = 9, + walkable = false, + groups = {vessel = 1, dig_immediate = 3, attached_node = 1}, + selection_box = { + type = "fixed", + fixed = {-0.25, -0.5, -0.25, 0.25, 0.3, 0.25} + }, + sounds = default.node_sound_glass_defaults(), + on_rightclick = function(pos, node, player, itemstack, pointed_thing) + local lower_pos = {x = pos.x, y = pos.y + 1, z = pos.z} + if minetest.is_protected(pos, player:get_player_name()) or + minetest.get_node(lower_pos).name ~= "air" then + return + end + + local upper_pos = {x = pos.x, y = pos.y + 2, z = pos.z} + local firefly_pos + + if not minetest.is_protected(upper_pos, player:get_player_name()) and + minetest.get_node(upper_pos).name == "air" then + firefly_pos = upper_pos + elseif not minetest.is_protected(lower_pos, player:get_player_name()) then + firefly_pos = lower_pos + end + + if firefly_pos then + minetest.set_node(pos, {name = "vessels:glass_bottle"}) + minetest.set_node(firefly_pos, {name = "fireflies:firefly"}) + minetest.get_node_timer(firefly_pos):start(1) + end + end +}) + +minetest.register_craft( { + output = "fireflies:firefly_bottle", + recipe = { + {"fireflies:firefly"}, + {"vessels:glass_bottle"} + } +}) + + +-- register fireflies as decorations + +if minetest.get_mapgen_setting("mg_name") == "v6" then + + minetest.register_decoration({ + name = "fireflies:firefly_low", + deco_type = "simple", + place_on = "default:dirt_with_grass", + place_offset_y = 2, + sidelen = 80, + fill_ratio = 0.0002, + y_max = 31000, + y_min = 1, + decoration = "fireflies:hidden_firefly", + }) + + minetest.register_decoration({ + name = "fireflies:firefly_high", + deco_type = "simple", + place_on = "default:dirt_with_grass", + place_offset_y = 3, + sidelen = 80, + fill_ratio = 0.0002, + y_max = 31000, + y_min = 1, + decoration = "fireflies:hidden_firefly", + }) + +else + + minetest.register_decoration({ + name = "fireflies:firefly_low", + deco_type = "simple", + place_on = { + "default:dirt_with_grass", + "default:dirt_with_coniferous_litter", + "default:dirt_with_rainforest_litter", + "default:dirt" + }, + place_offset_y = 2, + sidelen = 80, + fill_ratio = 0.0005, + biomes = { + "deciduous_forest", + "coniferous_forest", + "rainforest", + "rainforest_swamp" + }, + y_max = 31000, + y_min = -1, + decoration = "fireflies:hidden_firefly", + }) + + minetest.register_decoration({ + name = "fireflies:firefly_high", + deco_type = "simple", + place_on = { + "default:dirt_with_grass", + "default:dirt_with_coniferous_litter", + "default:dirt_with_rainforest_litter", + "default:dirt" + }, + place_offset_y = 3, + sidelen = 80, + fill_ratio = 0.0005, + biomes = { + "deciduous_forest", + "coniferous_forest", + "rainforest", + "rainforest_swamp" + }, + y_max = 31000, + y_min = -1, + decoration = "fireflies:hidden_firefly", + }) + +end + + +-- get decoration IDs +local firefly_low = minetest.get_decoration_id("fireflies:firefly_low") +local firefly_high = minetest.get_decoration_id("fireflies:firefly_high") + +minetest.set_gen_notify({decoration = true}, {firefly_low, firefly_high}) + +-- start nodetimers +minetest.register_on_generated(function(minp, maxp, blockseed) + local gennotify = minetest.get_mapgen_object("gennotify") + local poslist = {} + + for _, pos in ipairs(gennotify["decoration#"..firefly_low] or {}) do + local firefly_low_pos = {x = pos.x, y = pos.y + 3, z = pos.z} + table.insert(poslist, firefly_low_pos) + end + for _, pos in ipairs(gennotify["decoration#"..firefly_high] or {}) do + local firefly_high_pos = {x = pos.x, y = pos.y + 4, z = pos.z} + table.insert(poslist, firefly_high_pos) + end + + if #poslist ~= 0 then + for i = 1, #poslist do + local pos = poslist[i] + minetest.get_node_timer(pos):start(1) + end + end +end) diff --git a/mods/fireflies/license.txt b/mods/fireflies/license.txt new file mode 100644 index 0000000..eebdad6 --- /dev/null +++ b/mods/fireflies/license.txt @@ -0,0 +1,58 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (c) 2018 Shara RedCat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2018 Shara RedCat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ \ No newline at end of file diff --git a/mods/fireflies/locale/fireflies.de.tr b/mods/fireflies/locale/fireflies.de.tr new file mode 100644 index 0000000..c5d116a --- /dev/null +++ b/mods/fireflies/locale/fireflies.de.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=Glühwürmchen +Hidden Firefly=Verborgenes Glühwürmchen +Bug Net=Insektennetz +Firefly in a Bottle=Glühwürmchen in einer Flasche diff --git a/mods/fireflies/locale/fireflies.es.tr b/mods/fireflies/locale/fireflies.es.tr new file mode 100644 index 0000000..95d053e --- /dev/null +++ b/mods/fireflies/locale/fireflies.es.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=Luciérnaga +Hidden Firefly=Luciérnaga oculta +Bug Net=Red de insectos +Firefly in a Bottle=Luciérnaga en botella diff --git a/mods/fireflies/locale/fireflies.fr.tr b/mods/fireflies/locale/fireflies.fr.tr new file mode 100644 index 0000000..3deda66 --- /dev/null +++ b/mods/fireflies/locale/fireflies.fr.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=Luciole +Hidden Firefly=Luciole cachée +Bug Net=Filet à papillon +Firefly in a Bottle=Luciole en bouteille diff --git a/mods/fireflies/locale/fireflies.it.tr b/mods/fireflies/locale/fireflies.it.tr new file mode 100644 index 0000000..130b248 --- /dev/null +++ b/mods/fireflies/locale/fireflies.it.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=Lucciola +Hidden Firefly=Lucciola nascosta +Bug Net=Retino +Firefly in a Bottle=Lucciola imbottigliata \ No newline at end of file diff --git a/mods/fireflies/locale/fireflies.ms.tr b/mods/fireflies/locale/fireflies.ms.tr new file mode 100644 index 0000000..509d03d --- /dev/null +++ b/mods/fireflies/locale/fireflies.ms.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=Kelip-Kelip +Hidden Firefly=Kelip-Kelip Tersembunyi +Bug Net=Jaring Pepijat +Firefly in a Bottle=Kelip-Kelip dalam Botol diff --git a/mods/fireflies/locale/fireflies.ru.tr b/mods/fireflies/locale/fireflies.ru.tr new file mode 100644 index 0000000..c05f288 --- /dev/null +++ b/mods/fireflies/locale/fireflies.ru.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=СветлÑчок +Hidden Firefly=ПритаившийÑÑ Ð¡Ð²ÐµÑ‚Ð»Ñчок +Bug Net=Сачок Ð”Ð»Ñ Ð›Ð¾Ð²Ð»Ð¸ ÐаÑекомых +Firefly in a Bottle=СветлÑчок в Бутылке diff --git a/mods/fireflies/locale/fireflies.se.tr b/mods/fireflies/locale/fireflies.se.tr new file mode 100644 index 0000000..1bff782 --- /dev/null +++ b/mods/fireflies/locale/fireflies.se.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=Eldfluga +Hidden Firefly=Gömd Eldfluga +Bug Net=Buggernät +Firefly in a Bottle=Eldfluga i en flaska \ No newline at end of file diff --git a/mods/fireflies/locale/fireflies.zh_CN.tr b/mods/fireflies/locale/fireflies.zh_CN.tr new file mode 100644 index 0000000..5971785 --- /dev/null +++ b/mods/fireflies/locale/fireflies.zh_CN.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=è¤ç«è™« +Hidden Firefly=éšè—çš„è¤ç«è™« +Bug Net=虫网 +Firefly in a Bottle=放在瓶å­é‡Œçš„è¤ç«è™« diff --git a/mods/fireflies/locale/fireflies.zh_TW.tr b/mods/fireflies/locale/fireflies.zh_TW.tr new file mode 100644 index 0000000..af754a9 --- /dev/null +++ b/mods/fireflies/locale/fireflies.zh_TW.tr @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly=螢ç«èŸ² +Hidden Firefly=éš±è—的螢ç«èŸ² +Bug Net=蟲網 +Firefly in a Bottle=放在瓶å­è£¡çš„螢ç«èŸ² diff --git a/mods/fireflies/locale/template.txt b/mods/fireflies/locale/template.txt new file mode 100644 index 0000000..91aa8ff --- /dev/null +++ b/mods/fireflies/locale/template.txt @@ -0,0 +1,5 @@ +# textdomain: fireflies +Firefly= +Hidden Firefly= +Bug Net= +Firefly in a Bottle= diff --git a/mods/fireflies/mod.conf b/mods/fireflies/mod.conf new file mode 100644 index 0000000..a533588 --- /dev/null +++ b/mods/fireflies/mod.conf @@ -0,0 +1,3 @@ +name = fireflies +description = Minetest Game mod: fireflies +depends = default, vessels diff --git a/mods/fireflies/textures/fireflies_bottle.png b/mods/fireflies/textures/fireflies_bottle.png new file mode 100644 index 0000000..ecca036 Binary files /dev/null and b/mods/fireflies/textures/fireflies_bottle.png differ diff --git a/mods/fireflies/textures/fireflies_bottle_animated.png b/mods/fireflies/textures/fireflies_bottle_animated.png new file mode 100644 index 0000000..96062b3 Binary files /dev/null and b/mods/fireflies/textures/fireflies_bottle_animated.png differ diff --git a/mods/fireflies/textures/fireflies_bugnet.png b/mods/fireflies/textures/fireflies_bugnet.png new file mode 100644 index 0000000..8ec3d33 Binary files /dev/null and b/mods/fireflies/textures/fireflies_bugnet.png differ diff --git a/mods/fireflies/textures/fireflies_firefly.png b/mods/fireflies/textures/fireflies_firefly.png new file mode 100644 index 0000000..c086689 Binary files /dev/null and b/mods/fireflies/textures/fireflies_firefly.png differ diff --git a/mods/fireflies/textures/fireflies_firefly_animated.png b/mods/fireflies/textures/fireflies_firefly_animated.png new file mode 100644 index 0000000..e6932e3 Binary files /dev/null and b/mods/fireflies/textures/fireflies_firefly_animated.png differ diff --git a/mods/fishing/bobber.lua b/mods/fishing/bobber.lua new file mode 100644 index 0000000..136bc62 --- /dev/null +++ b/mods/fishing/bobber.lua @@ -0,0 +1,302 @@ +----------------------------------------------------------------------------------------------- +-- Fishing - Mossmanikin's version - Bobber 0.1.7 +-- License (code & textures): WTFPL +-- Contains code from: fishing (original), mobs, throwing, volcano +-- Supports: 3d_armor, animal_clownfish, animal_fish_blue_white, animal_rat, flowers_plus, mobs, seaplants +----------------------------------------------------------------------------------------------- + +local PoLeWeaR = (65535/(30-(math.random(15, 29)))) +local BooTSWear = (2000*(math.random(20, 29))) +-- Here's what you can catch +local CaTCH = { +-- MoD iTeM WeaR MeSSaGe ("You caught "..) GeTBaiTBack NRMiN CHaNCe (../120) + {"fishing", "fish_raw", 0, "a Fish.", false, 1, 100}, + -- {"animal_clownfish", "clownfish", 0, "a Clownfish.", false, 61, 10}, + -- {"animal_fish_blue_white", "fish_blue_white", 0, "a Blue white fish.", false, 71, 10}, + {"default", "stick", 0, "a Twig.", true, 81, 2}, + -- {"mobs", "rat", 0, "a Rat.", false, 83, 1}, + -- {"animal_rat", "rat", 0, "a Rat.", false, 84, 1}, + -- {"", "rat", 0, "a Rat.", false, 85, 1}, + -- {"flowers_plus", "seaweed", 0, "some Seaweed.", true, 86, 20}, + -- {"seaplants", "kelpgreen", 0, "a Green Kelp.", true, 106, 10}, + {"farming", "string", 0, "a String.", true, 116, 2}, + {"fishing", "pole", PoLeWeaR, "an old Fishing Pole.", true, 118, 2}, + -- {"3d_armor", "boots_wood", BooTSWear, "some very old Boots.", true, 120, 1}, + -- {"trunks", "twig_1", 0, "a Twig.", true, 121, 2}, +} +minetest.register_alias("flowers_plus:seaweed", "flowers:seaweed") -- exception + +local PLaNTS = { + -- MoD* iTeM MeSSaGe ("You caught "..) + {"flowers", "waterlily", "a Waterlily." }, + {"flowers", "waterlily_225", "a Waterlily." }, + {"flowers", "waterlily_45", "a Waterlily." }, + {"flowers", "waterlily_675", "a Waterlily." }, + {"flowers", "waterlily_s1", "a Waterlily." }, + {"flowers", "waterlily_s2", "a Waterlily." }, + {"flowers", "waterlily_s3", "a Waterlily." }, + {"flowers", "waterlily_s4", "a Waterlily." }, + {"flowers", "seaweed", "some Seaweed."}, + {"flowers", "seaweed_2", "some Seaweed."}, + {"flowers", "seaweed_3", "some Seaweed."}, + {"flowers", "seaweed_4", "some Seaweed."}, + {"trunks", "twig_1", "a Twig." }, + {"trunks", "twig_2", "a Twig." }, + {"trunks", "twig_3", "a Twig." }, + {"trunks", "twig_4", "a Twig." }, + {"trunks", "twig_5", "a Twig." }, + {"trunks", "twig_7", "a Twig." }, + {"trunks", "twig_8", "a Twig." }, + {"trunks", "twig_9", "a Twig." }, + {"trunks", "twig_10", "a Twig." }, + {"trunks", "twig_11", "a Twig." }, + {"trunks", "twig_12", "a Twig." }, + {"trunks", "twig_13", "a Twig." }, +} +-- *as used in the node name + +local MoBS = { -- not in use + -- iTeM MeSSaGe ("You caught "..) + {"animal_clownfish:clownfish", "a Clownfish." }, + {"animal_fish_blue_white:fish_blue_white", "a Blue white fish."}, +} + +local say = minetest.chat_send_player + + +minetest.register_node("fishing:bobber_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { +-- { left, bottom, front, right, top , back} + {-8/16, -8/16, 0, 8/16, 8/16, 0}, -- feathers + {-2/16, -8/16, -2/16, 2/16, -4/16, 2/16}, -- bobber + } + }, + tiles = { + "fishing_bobber_top.png", + "fishing_bobber_bottom.png", + "fishing_bobber.png", + "fishing_bobber.png", + "fishing_bobber.png", + "fishing_bobber.png^[transformFX" + }, -- + groups = {not_in_creative_inventory=1}, +}) + +local FISHING_BOBBER_ENTITY={ + hp_max = 605, + water_damage = 1, + physical = true, + timer = 0, + env_damage_timer = 0, + visual = "wielditem", + visual_size = {x=1/3, y=1/3, z=1/3}, + textures = {"fishing:bobber_box"}, + -- {left ,bottom, front, right, top , back} + collisionbox = {-2/16, -4/16, -2/16, 2/16, 0/16, 2/16}, + view_range = 7, +-- DESTROY BOBBER WHEN PUNCHING IT + on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir) + local player = puncher:get_player_name() + local inv = puncher:get_inventory() + if MESSAGES == true then minetest.chat_send_player(player, "You didn't catch anything.", false) end -- fish escaped + if not minetest.setting_getbool("creative_mode") then + if inv:room_for_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) then + inv:add_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) + if MESSAGES == true then minetest.chat_send_player(player, "The bait is still there.", false) end -- bait still there + end + end + -- make sound and remove bobber + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + self.object:remove() + placed_bobbler[player] = nil + end, +-- WHEN RIGHTCLICKING THE BOBBER THE FOLLOWING HAPPENS (CLICK AT THE RIGHT TIME WHILE HOLDING A FISHING POLE) + + on_activate = function(self,staticdata) + if staticdata then + local tmp = minetest.deserialize(staticdata) + if tmp and tmp.owner then + self.owner = tmp.owner + end + end + end, + + get_staticdata = function(self) + local tmp = { + owner=self.owner, + } + return minetest.serialize(tmp) + end, +-- AS SOON AS THE BOBBER IS PLACED IT WILL ACT LIKE + on_step = function(self, dtime) + local pos = self.object:getpos() + + + if math.random(1, 4) == 1 then + self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/2880*math.pi)) + end + for _,player in pairs(minetest.get_connected_players()) do + local s = self.object:getpos() + local p = player:getpos() + local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 + if dist > self.view_range then + -- make sound and remove bobber + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + self.object:remove() + placed_bobbler[player] = nil + end + end + + if self.object:get_hp() > 310 then + local find_fish = minetest.get_objects_inside_radius({x=pos.x,y=pos.y+0.5,z=pos.z}, 1) + for k, obj in pairs(find_fish) do + if obj:get_luaentity() ~= nil then + if obj:get_luaentity().name == "animal_fish_blue_white:fish_blue_white" then + if math.random(1, 30) == 1 then + self.object:set_hp(310) + end + end + end + end + end + + + local do_env_damage = function(self) + self.object:set_hp(self.object:get_hp()-self.water_damage) + if self.object:get_hp() == 600 then + self.object:moveto({x=pos.x,y=pos.y-0.015625,z=pos.z}) + elseif self.object:get_hp() == 595 then + self.object:moveto({x=pos.x,y=pos.y+0.015625,z=pos.z}) + elseif self.object:get_hp() == 590 then + self.object:moveto({x=pos.x,y=pos.y+0.015625,z=pos.z}) + elseif self.object:get_hp() == 585 then + self.object:moveto({x=pos.x,y=pos.y-0.015625,z=pos.z}) + self.object:set_hp(self.object:get_hp()-(math.random(1, 275))) + elseif self.object:get_hp() == 300 then + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + minetest.add_particlespawner(30, 0.5, -- for how long (?) -- Particles on splash + {x=pos.x,y=pos.y-0.0625,z=pos.z}, {x=pos.x,y=pos.y,z=pos.z}, -- position min, pos max + {x=-2,y=-0.0625,z=-2}, {x=2,y=3,z=2}, -- velocity min, vel max + {x=0,y=-9.8,z=0}, {x=0,y=-9.8,z=0}, + 0.3, 1.2, + 0.25, 0.5, -- min size, max size + false, "default_snow.png") + self.object:moveto({x=pos.x,y=pos.y-0.0625,z=pos.z}) + elseif self.object:get_hp() == 295 then + self.object:moveto({x=pos.x,y=pos.y+0.0625,z=pos.z}) + elseif self.object:get_hp() == 290 then + self.object:moveto({x=pos.x,y=pos.y+0.0625,z=pos.z}) + elseif self.object:get_hp() == 285 then + self.object:moveto({x=pos.x,y=pos.y-0.1,z=pos.z}) + elseif self.object:get_hp() < 284 then + self.object:moveto({x=pos.x+(0.001*(math.random(-8, 8))),y=pos.y,z=pos.z+(0.001*(math.random(-8, 8)))}) + --self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/1440*math.pi)) + self.object:setyaw(((math.random(0,360)-180)/1440*math.pi)) + elseif self.object:get_hp() == 0 then + -- make sound and remove bobber + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + self.object:remove() + placed_bobbler[player] = nil + end + end + do_env_damage(self) + + + local objects = minetest.get_objects_inside_radius(pos, BOBBER_CHECK_RADIUS) + if #objects==0 then return true end + -- minetest.chat_send_all('#objects > 0 ') + + for i,clicker in ipairs(objects) do + if clicker:is_player() then + -- minetest.chat_send_all('clicker is player') + + local pll = clicker:get_player_name() + if self.owner == pll then + -- minetest.chat_send_all('self==owner') + local rmb = clicker:get_player_control()['RMB'] + + local item = clicker:get_wielded_item() + local player = clicker:get_player_name() + if not pused[pll] and rmb and item:get_name() == "fishing:pole" then + pused[pll]=true + local inv = clicker:get_inventory() + local say = minetest.chat_send_player + if self.object:get_hp() <= 300 then + if math.random(1, 100) < FISH_CHANCE then + local chance = math.random(1, 122) -- ><((((�> + for i in pairs(CaTCH) do + local MoD = CaTCH[i][1] + local iTeM = CaTCH[i][2] + local WeaR = CaTCH[i][3] + local MeSSaGe = CaTCH[i][4] + local GeTBaiTBack = CaTCH[i][5] + local NRMiN = CaTCH[i][6] + local CHaNCe = CaTCH[i][7] + local NRMaX = NRMiN + CHaNCe - 1 + if chance <= NRMaX and chance >= NRMiN then + if minetest.get_modpath(MoD) ~= nil then + -- remove visible fish, if there + + -- add (in)visible fish to inventory + if inv:room_for_item("main", {name=MoD..":"..iTeM, count=1, wear=WeaR, metadata=""}) then + inv:add_item("main", {name=MoD..":"..iTeM, count=1, wear=WeaR, metadata=""}) + if MESSAGES == true then say(player, "You caught "..MeSSaGe, false) end -- caught somethin' + end + if not minetest.setting_getbool("creative_mode") then + if GeTBaiTBack == true then + if inv:room_for_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) then + inv:add_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) + if MESSAGES == true then say(player, "The bait is still there.", false) end -- bait still there? + end + end + end + else + if inv:room_for_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) then + inv:add_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) + if MESSAGES == true then say(player, "You caught a Fish.", false) end -- caught Fish + end + end + end + end + else --if math.random(1, 100) > FISH_CHANCE then + if MESSAGES == true then say(player, "Your fish escaped.", false) end -- fish escaped + end + + end -- 300 + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + minetest.chat_send_player(player, 'bobber\'s dead') + + self.object:remove() + placed_bobbler[player] = nil + end + + + end + end + end + + return true + end, +} + + + +minetest.register_entity("fishing:bobber_entity", FISHING_BOBBER_ENTITY) diff --git a/mods/fishing/bobber_shark.lua b/mods/fishing/bobber_shark.lua new file mode 100644 index 0000000..12e6a89 --- /dev/null +++ b/mods/fishing/bobber_shark.lua @@ -0,0 +1,223 @@ +----------------------------------------------------------------------------------------------- +-- Fishing - Mossmanikin's version - Bobber Shark 0.0.6 +-- License (code & textures): WTFPL +----------------------------------------------------------------------------------------------- + +-- Here's what you can catch if you use a fish as bait +local CaTCH_BiG = { +-- MoD iTeM WeaR MeSSaGe ("You caught "..) GeTBaiTBack NRMiN CHaNCe (../120) + {"fishing", "shark", 0, "a small Shark.", false, 1, 2}, + {"fishing", "pike", 0, "a Northern Pike.", false, 3, 3} +} + +local PLaNTS = { + -- MoD* iTeM MeSSaGe ("You caught "..) + {"flowers", "waterlily", "a Waterlily." }, + {"flowers", "waterlily_225", "a Waterlily." }, + {"flowers", "waterlily_45", "a Waterlily." }, + {"flowers", "waterlily_675", "a Waterlily." }, + {"flowers", "waterlily_s1", "a Waterlily." }, + {"flowers", "waterlily_s2", "a Waterlily." }, + {"flowers", "waterlily_s3", "a Waterlily." }, + {"flowers", "waterlily_s4", "a Waterlily." }, + {"flowers", "seaweed", "some Seaweed."}, + {"flowers", "seaweed_2", "some Seaweed."}, + {"flowers", "seaweed_3", "some Seaweed."}, + {"flowers", "seaweed_4", "some Seaweed."}, + {"trunks", "twig_1", "a Twig." }, + {"trunks", "twig_2", "a Twig." }, + {"trunks", "twig_3", "a Twig." }, + {"trunks", "twig_4", "a Twig." }, + {"trunks", "twig_5", "a Twig." }, + {"trunks", "twig_7", "a Twig." }, + {"trunks", "twig_8", "a Twig." }, + {"trunks", "twig_9", "a Twig." }, + {"trunks", "twig_10", "a Twig." }, + {"trunks", "twig_11", "a Twig." }, + {"trunks", "twig_12", "a Twig." }, + {"trunks", "twig_13", "a Twig." }, +} +-- *as used in the node name + +local FISHING_BOBBER_ENTITY_SHARK={ + hp_max = 605, + water_damage = 1, + physical = true, + timer = 0, + env_damage_timer = 0, + visual = "wielditem", + visual_size = {x=1/3, y=1/3, z=1/3}, + textures = {"fishing:bobber_box"}, + -- {left ,bottom, front, right, top , back} + collisionbox = {-2/16, -4/16, -2/16, 2/16, 0/16, 2/16}, + view_range = 7, +-- DESTROY BOBBER WHEN PUNCHING IT + on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir) + local player = puncher:get_player_name() + if MESSAGES == true then minetest.chat_send_player(player, "Your fish escaped.", false) end -- fish escaped + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + self.object:remove() + end, +-- WHEN RIGHTCLICKING THE BOBBER THE FOLLOWING HAPPENS (CLICK AT THE RIGHT TIME WHILE HOLDING A FISHING POLE) + on_rightclick = function (self, clicker) + local item = clicker:get_wielded_item() + local player = clicker:get_player_name() + local say = minetest.chat_send_player + if item:get_name() == "fishing:pole" then + local inv = clicker:get_inventory() + local pos = self.object:getpos() + -- catch visible plant + if minetest.get_node(pos).name ~= "air" then + for i in ipairs(PLaNTS) do + local PLaNT = PLaNTS[i][1]..":"..PLaNTS[i][2] + local MeSSaGe = PLaNTS[i][3] + local DRoP = minetest.registered_nodes[PLaNT].drop + if minetest.get_node(pos).name == PLaNT then + minetest.add_node({x=pos.x, y=pos.y, z=pos.z}, {name="air"}) + if inv:room_for_item("main", {name=DRoP, count=1, wear=0, metadata=""}) then + inv:add_item("main", {name=DRoP, count=1, wear=0, metadata=""}) + if MESSAGES == true then say(player, "You caught "..MeSSaGe, false) end -- caught Plant + end + if not minetest.setting_getbool("creative_mode") then + if inv:room_for_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) then + inv:add_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) + if MESSAGES == true then say(player, "The bait is still there.", false) end -- bait still there + end + end + end + end + end + --elseif minetest.get_node(pos).name == "air" then + if self.object:get_hp() <= 300 then + if math.random(1, 100) < SHARK_CHANCE then + local chance = math.random(1, 5) -- ><((((º> + for i in pairs(CaTCH_BiG) do + local MoD = CaTCH_BiG[i][1] + local iTeM = CaTCH_BiG[i][2] + local WeaR = CaTCH_BiG[i][3] + local MeSSaGe = CaTCH_BiG[i][4] + local GeTBaiTBack = CaTCH_BiG[i][5] + local NRMiN = CaTCH_BiG[i][6] + local CHaNCe = CaTCH_BiG[i][7] + local NRMaX = NRMiN + CHaNCe - 1 + if chance <= NRMaX and chance >= NRMiN then + if minetest.get_modpath(MoD) ~= nil then + if inv:room_for_item("main", {name=MoD..":"..iTeM, count=1, wear=WeaR, metadata=""}) then + inv:add_item("main", {name=MoD..":"..iTeM, count=1, wear=WeaR, metadata=""}) + if MESSAGES == true then say(player, "You caught "..MeSSaGe, false) end -- caught somethin' + end + if not minetest.setting_getbool("creative_mode") then + if GeTBaiTBack == true then + if inv:room_for_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) then + inv:add_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) + if MESSAGES == true then say(player, "The bait is still there.", false) end -- bait still there? + end + end + end + end + end + end + else --if math.random(1, 100) > FISH_CHANCE then + if MESSAGES == true then say(player, "Your fish escaped.", false) end -- fish escaped + end + end + if self.object:get_hp() > 300 and minetest.get_node(pos).name == "air" then + if MESSAGES == true then say(player, "You didn't catch any fish.", false) end -- fish escaped + if not minetest.setting_getbool("creative_mode") then + if math.random(1, 3) == 1 then + if inv:room_for_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) then + inv:add_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) + if MESSAGES == true then say(player, "The bait is still there.", false) end -- bait still there + end + end + end + end + --end + else + if MESSAGES == true then say(player, "Your fish escaped.", false) end -- fish escaped + end + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + self.object:remove() + end, +-- AS SOON AS THE BOBBER IS PLACED IT WILL ACT LIKE + on_step = function(self, dtime) + local pos = self.object:getpos() + if BOBBER_CHECK_RADIUS > 0 then + local objs = minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, BOBBER_CHECK_RADIUS) + for k, obj in pairs(objs) do + if obj:get_luaentity() ~= nil then + if obj:get_luaentity().name == "fishing:bobber_entity_shark" then + if obj:get_luaentity() ~= self then + self.object:remove() + end + end + end + end + end + if math.random(1, 4) == 1 then + self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/2880*math.pi)) + end + for _,player in pairs(minetest.get_connected_players()) do + local s = self.object:getpos() + local p = player:getpos() + local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 + if dist > self.view_range then + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + self.object:remove() + end + end + local do_env_damage = function(self) + self.object:set_hp(self.object:get_hp()-self.water_damage) + if self.object:get_hp() == 600 then + self.object:moveto({x=pos.x,y=pos.y-0.015625,z=pos.z}) + elseif self.object:get_hp() == 595 then + self.object:moveto({x=pos.x,y=pos.y+0.015625,z=pos.z}) + elseif self.object:get_hp() == 590 then + self.object:moveto({x=pos.x,y=pos.y+0.015625,z=pos.z}) + elseif self.object:get_hp() == 585 then + self.object:moveto({x=pos.x,y=pos.y-0.015625,z=pos.z}) + self.object:set_hp(self.object:get_hp()-(math.random(1, 200))) + elseif self.object:get_hp() == 300 then + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.7, + }) + minetest.add_particlespawner(40, 0.5, -- for how long (?) -- Particles on splash + {x=pos.x,y=pos.y-0.0625,z=pos.z}, {x=pos.x,y=pos.y-0.2,z=pos.z}, -- position min, pos max + {x=-3,y=-0.0625,z=-3}, {x=3,y=5,z=3}, -- velocity min, vel max + {x=0,y=-9.8,z=0}, {x=0,y=-9.8,z=0}, + 0.3, 2.4, + 0.25, 0.5, -- min size, max size + false, "default_snow.png") + self.object:moveto({x=pos.x,y=pos.y-0.625,z=pos.z}) + elseif self.object:get_hp() == 295 then + self.object:moveto({x=pos.x,y=pos.y+0.425,z=pos.z}) + elseif self.object:get_hp() == 290 then + self.object:moveto({x=pos.x,y=pos.y+0.0625,z=pos.z}) + elseif self.object:get_hp() == 285 then + self.object:moveto({x=pos.x,y=pos.y-0.0625,z=pos.z}) + elseif self.object:get_hp() < 284 then + self.object:moveto({x=pos.x+(0.001*(math.random(-8, 8))),y=pos.y,z=pos.z+(0.001*(math.random(-8, 8)))}) + self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/720*math.pi)) + elseif self.object:get_hp() == 0 then + minetest.sound_play("fishing_bobber1", { + pos = self.object:getpos(), + gain = 0.5, + }) + self.object:remove() + end + end + do_env_damage(self) + end, +} + +minetest.register_entity("fishing:bobber_entity_shark", FISHING_BOBBER_ENTITY_SHARK) \ No newline at end of file diff --git a/mods/fishing/crafting.lua b/mods/fishing/crafting.lua new file mode 100644 index 0000000..23b96ea --- /dev/null +++ b/mods/fishing/crafting.lua @@ -0,0 +1,92 @@ +----------------------------------------------------------------------------------------------- +-- Fishing - Mossmanikin's version - Recipes 0.0.7 +----------------------------------------------------------------------------------------------- +-- License (code & textures): WTFPL +-- Contains code from: animal_clownfish, animal_fish_blue_white, fishing (original), stoneage +-- Looked at code from: +-- Dependencies: default, farming +-- Supports: animal_clownfish, animal_fish_blue_white, animal_rat, mobs +----------------------------------------------------------------------------------------------- + +----------------------------------------------------------------------------------------------- +-- Fishing Pole +----------------------------------------------------------------------------------------------- +-- mc style +minetest.register_craft({ + output = "fishing:pole", + recipe = { + {"", "", "default:stick" }, + {"", "default:stick", "ropes:rope" }, + {"default:stick", "", "ropes:rope" }, + } +}) + +minetest.register_craft({ + output = "fishing:pole", + recipe = { + {"", "", "default:stick" }, + {"", "default:stick", "farming:string"}, + {"default:stick", "", "farming:string"}, + } +}) + +----------------------------------------------------------------------------------------------- +-- Roasted Fish +----------------------------------------------------------------------------------------------- +minetest.register_craft({ + type = "cooking", + output = "fishing:fish", + recipe = "fishing:fish_raw", + cooktime = 2, +}) + +----------------------------------------------------------------------------------------------- +-- Wheat Seed +----------------------------------------------------------------------------------------------- +minetest.register_craft({ + type = "shapeless", + output = "farming:seed_wheat", + recipe = {"farming:wheat"}, +}) +----------------------------------------------------------------------------------------------- +-- Sushi +----------------------------------------------------------------------------------------------- +minetest.register_craft({ + type = "shapeless", + output = "fishing:sushi", + recipe = {"fishing:fish_raw","farming:seed_wheat","flowers:seaweed"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "fishing:sushi", + recipe = {"fishing:fish_raw","farming:seed_wheat","seaplants:kelpgreen"}, + +}) + +minetest.register_craft({ + type = "shapeless", + output = "fishing:sushi", + recipe = {"fishing:fish_raw","farming:seed_wheat","seaplants:kelpgreenmiddle"}, + +}) + +----------------------------------------------------------------------------------------------- +-- Roasted Shark +----------------------------------------------------------------------------------------------- +minetest.register_craft({ + type = "cooking", + output = "fishing:shark_cooked", + recipe = "fishing:shark", + cooktime = 2, +}) + +----------------------------------------------------------------------------------------------- +-- Roasted Pike +----------------------------------------------------------------------------------------------- +minetest.register_craft({ + type = "cooking", + output = "fishing:pike_cooked", + recipe = "fishing:pike", + cooktime = 2, +}) diff --git a/mods/fishing/fishes.lua b/mods/fishing/fishes.lua new file mode 100644 index 0000000..dd152e6 --- /dev/null +++ b/mods/fishing/fishes.lua @@ -0,0 +1,70 @@ +----------------------------------------------------------------------------------------------- +-- Fishing - Mossmanikin's version - Fishes 0.0.4 +-- License (code & textures): WTFPL +----------------------------------------------------------------------------------------------- + +----------------------------------------------------------------------------------------------- +-- Fish +----------------------------------------------------------------------------------------------- +minetest.register_craftitem("fishing:fish_raw", { + description = "Fish", + groups = {}, + inventory_image = "fishing_fish.png", + on_use = minetest.item_eat(2), +}) + ----------------------------------------------------- + -- Roasted Fish + ----------------------------------------------------- + minetest.register_craftitem("fishing:fish", { + description = "Roasted Fish", + groups = {}, + inventory_image = "fishing_fish_cooked.png", + on_use = minetest.item_eat(4), + }) + ----------------------------------------------------- + -- Sushi + ----------------------------------------------------- + minetest.register_craftitem("fishing:sushi", { + description = "Sushi (Hoso Maki)", + groups = {}, + inventory_image = "fishing_sushi.png", + on_use = minetest.item_eat(8), + }) + +----------------------------------------------------------------------------------------------- +-- Whatthef... it's a freakin' Shark! +----------------------------------------------------------------------------------------------- +minetest.register_craftitem("fishing:shark", { + description = "Shark", + groups = {}, + inventory_image = "fishing_shark.png", + on_use = minetest.item_eat(4), +}) + ----------------------------------------------------- + -- Roasted Shark + ----------------------------------------------------- + minetest.register_craftitem("fishing:shark_cooked", { + description = "Roasted Shark", + groups = {}, + inventory_image = "fishing_shark_cooked.png", + on_use = minetest.item_eat(8), + }) + +----------------------------------------------------------------------------------------------- +-- Pike +----------------------------------------------------------------------------------------------- +minetest.register_craftitem("fishing:pike", { + description = "Northern Pike", + groups = {}, + inventory_image = "fishing_pike.png", + on_use = minetest.item_eat(4), +}) + ----------------------------------------------------- + -- Roasted Pike + ----------------------------------------------------- + minetest.register_craftitem("fishing:pike_cooked", { + description = "Roasted Northern Pike", + groups = {}, + inventory_image = "fishing_pike_cooked.png", + on_use = minetest.item_eat(8), + }) diff --git a/mods/fishing/init.lua b/mods/fishing/init.lua new file mode 100644 index 0000000..ee4f074 --- /dev/null +++ b/mods/fishing/init.lua @@ -0,0 +1,121 @@ +----------------------------------------------------------------------------------------------- +local title = "Fishing - Mossmanikin's version" +local version = "0.2.2" +local mname = "fishing" +----------------------------------------------------------------------------------------------- +-- original by wulfsdad (http://forum.minetest.net/viewtopic.php?id=4375) +-- this version by Mossmanikin (https://forum.minetest.net/viewtopic.php?id=6480) +-- License (code & textures): WTFPL +-- Contains code from: animal_clownfish, animal_fish_blue_white, fishing (original), stoneage +-- Looked at code from: default, farming +-- Dependencies: default +-- Supports: animal_clownfish, animal_fish_blue_white, animal_rat, mobs +----------------------------------------------------------------------------------------------- + +-- todo: item wear done +-- automatic re-baiting option done (but not optional) +-- different types of fish, done, but not finished +-- add sound done +-- bobber done +-- change rainworms filling inv & make 'em disappear done + +-- placable fishing rod for decoration done +-- make bobber move slowly while fish on hook done +-- catch bigger fish with smaller done, but not finished +-- change color of bobber when fish on hook done + +----------------------------------------------------------------------------------------------- +-------------------------------------------------------------------------------- +-- some additions made by 4aiman to make a pole be usable w/o clicking on a bobbler, +-- to make bobblers "dissapear" other bobblers only of their "owner" +-- also 1 man = 1 bobbler... or so it would seem ;) +-- Moreover, I've fixed node_drops to be compatible with enchantments. +-------------------------------------------------------------------------------- +dofile(minetest.get_modpath("fishing").."/settings.txt") +dofile(minetest.get_modpath("fishing").."/bobber.lua") +dofile(minetest.get_modpath("fishing").."/bobber_shark.lua") +dofile(minetest.get_modpath("fishing").."/crafting.lua") +dofile(minetest.get_modpath("fishing").."/fishes.lua") +dofile(minetest.get_modpath("fishing").."/worm.lua") + +----------------------------------------------------------------------------------------------- +-- Fishing Pole +----------------------------------------------------------------------------------------------- + +local function rod_wear(itemstack, user, pointed_thing, uses) + itemstack:add_wear(65535/(uses-1)) + return itemstack +end + +pused = {} +placed_bobbler = {} + +minetest.register_tool("fishing:pole", { + + description = "Fishing Pole", + groups = {}, + inventory_image = "fishing_pole.png", + wield_image = "fishing_pole.png^[transformFXR270", + stack_max = 1, + liquids_pointable = true, + range = 7.5, + on_place = function (itemstack, user, pointed_thing) + if placed_bobbler[player]==true then return itemstack end + if pointed_thing and pointed_thing.under then + local pt = pointed_thing + local node = minetest.get_node(pt.under) + if string.find(node.name, "default:water") then + local player = user:get_player_name() + pused[player]=true + local inv = user:get_inventory() + if inv:get_stack("main", user:get_wield_index()+1):get_name() == "fishing:bait_worm" then + if not minetest.setting_getbool("creative_mode") then + inv:remove_item("main", "fishing:bait_worm") + end + minetest.sound_play("fishing_bobber2", { + pos = pt.under, + gain = 0.5, + }) + local ent = minetest.add_entity({interval = 1,x=pt.under.x, y=pt.under.y+(45/64), z=pt.under.z}, "fishing:bobber_entity") + ent:get_luaentity().owner=player + placed_bobbler[player] = true + if WEAR_OUT == true + and not minetest.setting_getbool("creative_mode") then + return rod_wear(itemstack, user, pointed_thing, 60) + else + return {name="fishing:pole", count=1, wear=0, metadata=""} + end + end + if inv:get_stack("main", user:get_wield_index()+1):get_name() == "fishing:fish_raw" then + if not minetest.setting_getbool("creative_mode") then + inv:remove_item("main", "fishing:fish_raw") + end + minetest.sound_play("fishing_bobber2", { + pos = pt.under, + gain = 0.5, + }) + minetest.add_entity({interval = 1,x=pt.under.x, y=pt.under.y+(45/64), z=pt.under.z}, "fishing:bobber_entity_shark") + placed_bobbler[player] = true + if WEAR_OUT == true + and not minetest.setting_getbool("creative_mode") then + return rod_wear(itemstack, user, pointed_thing, 60) + else + return {name="fishing:pole", count=1, wear=0, metadata=""} + end + end + end + end + return nil + end, + on_use = function(itemstack, placer, pointed_thing) + end, +}) + +minetest.register_globalstep(function(dtime) + local players = minetest.get_connected_players() + for i,player in ipairs(players) do + local pll = player:get_player_name() + local control = player:get_player_control() + if not control.RMB then pused[pll]=nil end + end +end) diff --git a/mods/fishing/license.txt b/mods/fishing/license.txt new file mode 100644 index 0000000..a39d016 --- /dev/null +++ b/mods/fishing/license.txt @@ -0,0 +1,4 @@ +-- original by wulfsdad (http://forum.minetest.net/viewtopic.php?id=4375) +-- edited version by Mossmanikin (https://forum.minetest.net/viewtopic.php?id=6480) +-- License (code & textures): CC-BY-SA (3.0) +-- May contain leftover code from: animal_clownfish, animal_fish_blue_white, stoneage diff --git a/mods/fishing/mod.conf b/mods/fishing/mod.conf new file mode 100644 index 0000000..67cc2de --- /dev/null +++ b/mods/fishing/mod.conf @@ -0,0 +1,2 @@ +name = fishing +depends = default, farming diff --git a/mods/fishing/readme.txt b/mods/fishing/readme.txt new file mode 100644 index 0000000..940e4bb --- /dev/null +++ b/mods/fishing/readme.txt @@ -0,0 +1,19 @@ +----------------------------------------------------------------------------------------------- +local title = "Fishing - 4aiman's version" +local version = "0.2.2.1" +local mname = "fishing" +----------------------------------------------------------------------------------------------- +-- original by wulfsdad (http://forum.minetest.net/viewtopic.php?id=4375) +-- edited version by Mossmanikin (https://forum.minetest.net/viewtopic.php?id=6480) +-- License (code & textures): CC-BY-SA (3.0) +-- May contain leftover code from: animal_clownfish, animal_fish_blue_white, stoneage +-- Mossmanikin has looked at the code from: default, farming +-- Dependencies: default +----------------------------------------------------------------------------------------------- +-- +----------------------------------------------------------------------------------------------- +-- some additions were made by 4aiman to make a pole be usable w/o clicking on a bobbler, +-- to make bobblers "dissapear" other bobblers only of their "owner" +-- also 1 man = 1 bobbler... or so it would seem ;) +-- Moreover, node_drops were fixed to be compatible with the "enchantment" mod. +----------------------------------------------------------------------------------------------- diff --git a/mods/fishing/settings.txt b/mods/fishing/settings.txt new file mode 100644 index 0000000..331d750 --- /dev/null +++ b/mods/fishing/settings.txt @@ -0,0 +1,9 @@ +MESSAGES = true +FISH_CHANCE = 70 +NEW_WORM_SOURCE = false +WORM_IS_MOB = false +WORM_CHANCE = 40 +WEAR_OUT = true +BOBBER_CHECK_RADIUS = 5 +SIMPLE_DECO_FISHING_POLE = true +SHARK_CHANCE = 10 diff --git a/mods/fishing/sounds/fishing_bobber1.ogg b/mods/fishing/sounds/fishing_bobber1.ogg new file mode 100644 index 0000000..6c86a0c Binary files /dev/null and b/mods/fishing/sounds/fishing_bobber1.ogg differ diff --git a/mods/fishing/sounds/fishing_bobber2.ogg b/mods/fishing/sounds/fishing_bobber2.ogg new file mode 100644 index 0000000..932cf0b Binary files /dev/null and b/mods/fishing/sounds/fishing_bobber2.ogg differ diff --git a/mods/fishing/textures/animal_clownfish_clownfish_item.png b/mods/fishing/textures/animal_clownfish_clownfish_item.png new file mode 100644 index 0000000..69f0fcc Binary files /dev/null and b/mods/fishing/textures/animal_clownfish_clownfish_item.png differ diff --git a/mods/fishing/textures/animal_fish_blue_white_fish_blue_white_item.png b/mods/fishing/textures/animal_fish_blue_white_fish_blue_white_item.png new file mode 100644 index 0000000..5f8224e Binary files /dev/null and b/mods/fishing/textures/animal_fish_blue_white_fish_blue_white_item.png differ diff --git a/mods/fishing/textures/fishing_bobber.png b/mods/fishing/textures/fishing_bobber.png new file mode 100644 index 0000000..42bfe69 Binary files /dev/null and b/mods/fishing/textures/fishing_bobber.png differ diff --git a/mods/fishing/textures/fishing_bobber_bottom.png b/mods/fishing/textures/fishing_bobber_bottom.png new file mode 100644 index 0000000..32a54f7 Binary files /dev/null and b/mods/fishing/textures/fishing_bobber_bottom.png differ diff --git a/mods/fishing/textures/fishing_bobber_feather_1.png b/mods/fishing/textures/fishing_bobber_feather_1.png new file mode 100644 index 0000000..9eff3f8 Binary files /dev/null and b/mods/fishing/textures/fishing_bobber_feather_1.png differ diff --git a/mods/fishing/textures/fishing_bobber_top.png b/mods/fishing/textures/fishing_bobber_top.png new file mode 100644 index 0000000..039620b Binary files /dev/null and b/mods/fishing/textures/fishing_bobber_top.png differ diff --git a/mods/fishing/textures/fishing_deco_pike.png b/mods/fishing/textures/fishing_deco_pike.png new file mode 100644 index 0000000..fc6079e Binary files /dev/null and b/mods/fishing/textures/fishing_deco_pike.png differ diff --git a/mods/fishing/textures/fishing_fish.png b/mods/fishing/textures/fishing_fish.png new file mode 100644 index 0000000..1cf74ac Binary files /dev/null and b/mods/fishing/textures/fishing_fish.png differ diff --git a/mods/fishing/textures/fishing_fish_cooked.png b/mods/fishing/textures/fishing_fish_cooked.png new file mode 100644 index 0000000..709d8f2 Binary files /dev/null and b/mods/fishing/textures/fishing_fish_cooked.png differ diff --git a/mods/fishing/textures/fishing_pike.png b/mods/fishing/textures/fishing_pike.png new file mode 100644 index 0000000..5c7885f Binary files /dev/null and b/mods/fishing/textures/fishing_pike.png differ diff --git a/mods/fishing/textures/fishing_pike_cooked.png b/mods/fishing/textures/fishing_pike_cooked.png new file mode 100644 index 0000000..7d66e7c Binary files /dev/null and b/mods/fishing/textures/fishing_pike_cooked.png differ diff --git a/mods/fishing/textures/fishing_pole.png b/mods/fishing/textures/fishing_pole.png new file mode 100644 index 0000000..bbb196b Binary files /dev/null and b/mods/fishing/textures/fishing_pole.png differ diff --git a/mods/fishing/textures/fishing_pole_back.png b/mods/fishing/textures/fishing_pole_back.png new file mode 100644 index 0000000..7b58478 Binary files /dev/null and b/mods/fishing/textures/fishing_pole_back.png differ diff --git a/mods/fishing/textures/fishing_pole_bottom.png b/mods/fishing/textures/fishing_pole_bottom.png new file mode 100644 index 0000000..6f52ca8 Binary files /dev/null and b/mods/fishing/textures/fishing_pole_bottom.png differ diff --git a/mods/fishing/textures/fishing_pole_deco.png b/mods/fishing/textures/fishing_pole_deco.png new file mode 100644 index 0000000..9224988 Binary files /dev/null and b/mods/fishing/textures/fishing_pole_deco.png differ diff --git a/mods/fishing/textures/fishing_pole_front.png b/mods/fishing/textures/fishing_pole_front.png new file mode 100644 index 0000000..e8aa3d6 Binary files /dev/null and b/mods/fishing/textures/fishing_pole_front.png differ diff --git a/mods/fishing/textures/fishing_pole_simple.png b/mods/fishing/textures/fishing_pole_simple.png new file mode 100644 index 0000000..afa5b19 Binary files /dev/null and b/mods/fishing/textures/fishing_pole_simple.png differ diff --git a/mods/fishing/textures/fishing_pole_top.png b/mods/fishing/textures/fishing_pole_top.png new file mode 100644 index 0000000..1408eac Binary files /dev/null and b/mods/fishing/textures/fishing_pole_top.png differ diff --git a/mods/fishing/textures/fishing_shark.png b/mods/fishing/textures/fishing_shark.png new file mode 100644 index 0000000..62a1b9e Binary files /dev/null and b/mods/fishing/textures/fishing_shark.png differ diff --git a/mods/fishing/textures/fishing_shark_cooked.png b/mods/fishing/textures/fishing_shark_cooked.png new file mode 100644 index 0000000..b6142ce Binary files /dev/null and b/mods/fishing/textures/fishing_shark_cooked.png differ diff --git a/mods/fishing/textures/fishing_sushi.png b/mods/fishing/textures/fishing_sushi.png new file mode 100644 index 0000000..c64ceca Binary files /dev/null and b/mods/fishing/textures/fishing_sushi.png differ diff --git a/mods/fishing/textures/fishing_trophy_label.png b/mods/fishing/textures/fishing_trophy_label.png new file mode 100644 index 0000000..3c8326b Binary files /dev/null and b/mods/fishing/textures/fishing_trophy_label.png differ diff --git a/mods/fishing/textures/fishing_worm.png b/mods/fishing/textures/fishing_worm.png new file mode 100644 index 0000000..7a4d8d1 Binary files /dev/null and b/mods/fishing/textures/fishing_worm.png differ diff --git a/mods/fishing/worm.lua b/mods/fishing/worm.lua new file mode 100644 index 0000000..069c1d3 --- /dev/null +++ b/mods/fishing/worm.lua @@ -0,0 +1,6 @@ +minetest.register_craftitem("fishing:bait_worm", { + description = "Worm", + groups = { fishing_bait=1 }, + inventory_image = "fishing_worm.png", + on_place = minetest.item_eat(1), +}) diff --git a/mods/flowers/README.txt b/mods/flowers/README.txt new file mode 100644 index 0000000..4b3149c --- /dev/null +++ b/mods/flowers/README.txt @@ -0,0 +1,30 @@ +Minetest Game mod: flowers +========================== +See license.txt for license information. + +Authors of source code +---------------------- +Originally by Ironzorg (MIT) and VanessaE (MIT) +Various Minetest developers and contributors (MIT) + +Authors of media (textures) +--------------------------- +RHRhino (CC BY-SA 3.0): + flowers_dandelion_white.png + flowers_geranium.png + flowers_rose.png + flowers_tulip.png + flowers_viola.png + +Gambit (CC BY-SA 3.0): + flowers_mushroom_brown.png + flowers_mushroom_red.png + flowers_waterlily.png + +yyt16384 (CC BY-SA 3.0): + flowers_waterlily_bottom.png -- Derived from Gambit's texture + +paramat (CC BY-SA 3.0): + flowers_dandelion_yellow.png -- Derived from RHRhino's texture + flowers_tulip_black.png -- Derived from RHRhino's texture + flowers_chrysanthemum_green.png diff --git a/mods/flowers/init.lua b/mods/flowers/init.lua new file mode 100644 index 0000000..9731750 --- /dev/null +++ b/mods/flowers/init.lua @@ -0,0 +1,336 @@ +-- flowers/init.lua + +-- Minetest 0.4 mod: default +-- See README.txt for licensing and other information. + + +-- Namespace for functions + +flowers = {} + +-- Load support for MT game translation. +local S = minetest.get_translator("flowers") + + +-- Map Generation + +dofile(minetest.get_modpath("flowers") .. "/mapgen.lua") + + +-- +-- Flowers +-- + +-- Aliases for original flowers mod + +minetest.register_alias("flowers:flower_rose", "flowers:rose") +minetest.register_alias("flowers:flower_tulip", "flowers:tulip") +minetest.register_alias("flowers:flower_dandelion_yellow", "flowers:dandelion_yellow") +minetest.register_alias("flowers:flower_geranium", "flowers:geranium") +minetest.register_alias("flowers:flower_viola", "flowers:viola") +minetest.register_alias("flowers:flower_dandelion_white", "flowers:dandelion_white") + + +-- Flower registration + +local function add_simple_flower(name, desc, box, f_groups) + -- Common flowers' groups + f_groups.snappy = 3 + f_groups.flower = 1 + f_groups.flora = 1 + f_groups.attached_node = 1 + + minetest.register_node("flowers:" .. name, { + description = desc, + drawtype = "plantlike", + waving = 1, + tiles = {"flowers_" .. name .. ".png"}, + inventory_image = "flowers_" .. name .. ".png", + wield_image = "flowers_" .. name .. ".png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + groups = f_groups, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = box + } + }) +end + +flowers.datas = { + { + "rose", + S("Red Rose"), + {-2 / 16, -0.5, -2 / 16, 2 / 16, 5 / 16, 2 / 16}, + {color_red = 1, flammable = 1} + }, + { + "tulip", + S("Orange Tulip"), + {-2 / 16, -0.5, -2 / 16, 2 / 16, 3 / 16, 2 / 16}, + {color_orange = 1, flammable = 1} + }, + { + "dandelion_yellow", + S("Yellow Dandelion"), + {-4 / 16, -0.5, -4 / 16, 4 / 16, -2 / 16, 4 / 16}, + {color_yellow = 1, flammable = 1} + }, + { + "chrysanthemum_green", + S("Green Chrysanthemum"), + {-4 / 16, -0.5, -4 / 16, 4 / 16, -1 / 16, 4 / 16}, + {color_green = 1, flammable = 1} + }, + { + "geranium", + S("Blue Geranium"), + {-2 / 16, -0.5, -2 / 16, 2 / 16, 2 / 16, 2 / 16}, + {color_blue = 1, flammable = 1} + }, + { + "viola", + S("Viola"), + {-5 / 16, -0.5, -5 / 16, 5 / 16, -1 / 16, 5 / 16}, + {color_violet = 1, flammable = 1} + }, + { + "dandelion_white", + S("White Dandelion"), + {-5 / 16, -0.5, -5 / 16, 5 / 16, -2 / 16, 5 / 16}, + {color_white = 1, flammable = 1} + }, + { + "tulip_black", + S("Black Tulip"), + {-2 / 16, -0.5, -2 / 16, 2 / 16, 3 / 16, 2 / 16}, + {color_black = 1, flammable = 1} + }, +} + +for _,item in pairs(flowers.datas) do + add_simple_flower(unpack(item)) +end + + +-- Flower spread +-- Public function to enable override by mods + +function flowers.flower_spread(pos, node) + pos.y = pos.y - 1 + local under = minetest.get_node(pos) + pos.y = pos.y + 1 + -- Replace flora with dry shrub in desert sand and silver sand, + -- as this is the only way to generate them. + -- However, preserve grasses in sand dune biomes. + if minetest.get_item_group(under.name, "sand") == 1 and + under.name ~= "default:sand" then + minetest.set_node(pos, {name = "default:dry_shrub"}) + return + end + + if minetest.get_item_group(under.name, "soil") == 0 then + return + end + + local light = minetest.get_node_light(pos) + if not light or light < 13 then + return + end + + local pos0 = vector.subtract(pos, 4) + local pos1 = vector.add(pos, 4) + -- Testing shows that a threshold of 3 results in an appropriate maximum + -- density of approximately 7 flora per 9x9 area. + if #minetest.find_nodes_in_area(pos0, pos1, "group:flora") > 3 then + return + end + + local soils = minetest.find_nodes_in_area_under_air( + pos0, pos1, "group:soil") + local num_soils = #soils + if num_soils >= 1 then + for si = 1, math.min(3, num_soils) do + local soil = soils[math.random(num_soils)] + local soil_name = minetest.get_node(soil).name + local soil_above = {x = soil.x, y = soil.y + 1, z = soil.z} + light = minetest.get_node_light(soil_above) + if light and light >= 13 and + -- Only spread to same surface node + soil_name == under.name and + -- Desert sand is in the soil group + soil_name ~= "default:desert_sand" then + minetest.set_node(soil_above, {name = node.name}) + end + end + end +end + +minetest.register_abm({ + label = "Flower spread", + nodenames = {"group:flora"}, + interval = 13, + chance = 300, + action = function(...) + flowers.flower_spread(...) + end, +}) + + +-- +-- Mushrooms +-- + +minetest.register_node("flowers:mushroom_red", { + description = S("Red Mushroom"), + tiles = {"flowers_mushroom_red.png"}, + inventory_image = "flowers_mushroom_red.png", + wield_image = "flowers_mushroom_red.png", + drawtype = "plantlike", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {mushroom = 1, snappy = 3, attached_node = 1, flammable = 1}, + sounds = default.node_sound_leaves_defaults(), + on_use = minetest.item_eat(-5), + selection_box = { + type = "fixed", + fixed = {-4 / 16, -0.5, -4 / 16, 4 / 16, -1 / 16, 4 / 16}, + } +}) + +minetest.register_node("flowers:mushroom_brown", { + description = S("Brown Mushroom"), + tiles = {"flowers_mushroom_brown.png"}, + inventory_image = "flowers_mushroom_brown.png", + wield_image = "flowers_mushroom_brown.png", + drawtype = "plantlike", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + buildable_to = true, + groups = {mushroom = 1, food_mushroom = 1, snappy = 3, attached_node = 1, flammable = 1}, + sounds = default.node_sound_leaves_defaults(), + on_use = minetest.item_eat(1), + selection_box = { + type = "fixed", + fixed = {-3 / 16, -0.5, -3 / 16, 3 / 16, -2 / 16, 3 / 16}, + } +}) + + +-- Mushroom spread and death + +function flowers.mushroom_spread(pos, node) + if minetest.get_node_light(pos, 0.5) > 3 then + if minetest.get_node_light(pos, nil) == 15 then + minetest.remove_node(pos) + end + return + end + local positions = minetest.find_nodes_in_area_under_air( + {x = pos.x - 1, y = pos.y - 2, z = pos.z - 1}, + {x = pos.x + 1, y = pos.y + 1, z = pos.z + 1}, + {"group:soil", "group:tree"}) + if #positions == 0 then + return + end + local pos2 = positions[math.random(#positions)] + pos2.y = pos2.y + 1 + if minetest.get_node_light(pos2, 0.5) <= 3 then + minetest.set_node(pos2, {name = node.name}) + end +end + +minetest.register_abm({ + label = "Mushroom spread", + nodenames = {"flowers:mushroom_brown", "flowers:mushroom_red"}, + interval = 11, + chance = 150, + action = function(...) + flowers.mushroom_spread(...) + end, +}) + + +-- These old mushroom related nodes can be simplified now + +minetest.register_alias("flowers:mushroom_spores_brown", "flowers:mushroom_brown") +minetest.register_alias("flowers:mushroom_spores_red", "flowers:mushroom_red") +minetest.register_alias("flowers:mushroom_fertile_brown", "flowers:mushroom_brown") +minetest.register_alias("flowers:mushroom_fertile_red", "flowers:mushroom_red") +minetest.register_alias("mushroom:brown_natural", "flowers:mushroom_brown") +minetest.register_alias("mushroom:red_natural", "flowers:mushroom_red") + + +-- +-- Waterlily +-- + +local waterlily_def = { + description = S("Waterlily"), + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + tiles = {"flowers_waterlily.png", "flowers_waterlily_bottom.png"}, + inventory_image = "flowers_waterlily.png", + wield_image = "flowers_waterlily.png", + liquids_pointable = true, + walkable = false, + buildable_to = true, + floodable = true, + groups = {snappy = 3, flower = 1, flammable = 1}, + sounds = default.node_sound_leaves_defaults(), + node_placement_prediction = "", + node_box = { + type = "fixed", + fixed = {-0.5, -31 / 64, -0.5, 0.5, -15 / 32, 0.5} + }, + selection_box = { + type = "fixed", + fixed = {-7 / 16, -0.5, -7 / 16, 7 / 16, -15 / 32, 7 / 16} + }, + + on_place = function(itemstack, placer, pointed_thing) + local pos = pointed_thing.above + local node = minetest.get_node(pointed_thing.under) + local def = minetest.registered_nodes[node.name] + + if def and def.on_rightclick then + return def.on_rightclick(pointed_thing.under, node, placer, itemstack, + pointed_thing) + end + + if def and def.liquidtype == "source" and + minetest.get_item_group(node.name, "water") > 0 then + local player_name = placer and placer:get_player_name() or "" + if not minetest.is_protected(pos, player_name) then + minetest.set_node(pos, {name = "flowers:waterlily" .. + (def.waving == 3 and "_waving" or ""), + param2 = math.random(0, 3)}) + if not (creative and creative.is_enabled_for + and creative.is_enabled_for(player_name)) then + itemstack:take_item() + end + else + minetest.chat_send_player(player_name, "Node is protected") + minetest.record_protection_violation(pos, player_name) + end + end + + return itemstack + end +} + +local waterlily_waving_def = table.copy(waterlily_def) +waterlily_waving_def.waving = 3 +waterlily_waving_def.drop = "flowers:waterlily" +waterlily_waving_def.groups.not_in_creative_inventory = 1 + +minetest.register_node("flowers:waterlily", waterlily_def) +minetest.register_node("flowers:waterlily_waving", waterlily_waving_def) + diff --git a/mods/flowers/license.txt b/mods/flowers/license.txt new file mode 100644 index 0000000..419ebe5 --- /dev/null +++ b/mods/flowers/license.txt @@ -0,0 +1,63 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Ironzorg, VanessaE +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2014-2016 RHRhino +Copyright (C) 2015-2016 Gambit +Copyright (C) 2016 yyt16384 +Copyright (C) 2017 paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/mods/flowers/locale/flowers.de.tr b/mods/flowers/locale/flowers.de.tr new file mode 100644 index 0000000..18afb2a --- /dev/null +++ b/mods/flowers/locale/flowers.de.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=Rote Rose +Orange Tulip=Orange Tulpe +Yellow Dandelion=Gelber Löwenzahn +Green Chrysanthemum=Grüne Chrysantheme +Blue Geranium=Blaue Geranie +Viola=Veilchen +White Dandelion=Weißer Löwenzahn +Black Tulip=Schwarze Tulpe +Red Mushroom=Roter Pilz +Brown Mushroom=Brauner Pilz +Waterlily=Wasserlilie diff --git a/mods/flowers/locale/flowers.es.tr b/mods/flowers/locale/flowers.es.tr new file mode 100644 index 0000000..e9c345d --- /dev/null +++ b/mods/flowers/locale/flowers.es.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=Rosa roja +Orange Tulip=Tulipán naranja +Yellow Dandelion=Diente de León amarillo +Green Chrysanthemum=Crisantemo verde +Blue Geranium=Geranio azul +Viola=Violeta +White Dandelion=Diente de León blanco +Black Tulip=Tulipán negro +Red Mushroom=Champiñón rojo +Brown Mushroom=Champiñón café +Waterlily=Nenúfar diff --git a/mods/flowers/locale/flowers.fr.tr b/mods/flowers/locale/flowers.fr.tr new file mode 100644 index 0000000..41e0d00 --- /dev/null +++ b/mods/flowers/locale/flowers.fr.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=Rose rouge +Orange Tulip=Tulipe orange +Yellow Dandelion=Pissenlit jaune +Green Chrysanthemum=Chrysanthème vert +Blue Geranium=Géranium bleu +Viola=Violette +White Dandelion=Pissenlit blanc +Black Tulip=Tulipe noire +Red Mushroom=Champignon rouge +Brown Mushroom=Champignon brun +Waterlily=Nénuphar diff --git a/mods/flowers/locale/flowers.it.tr b/mods/flowers/locale/flowers.it.tr new file mode 100644 index 0000000..e273941 --- /dev/null +++ b/mods/flowers/locale/flowers.it.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=Rosa rossa +Orange Tulip=Tulipano arancione +Yellow Dandelion=Dente di leone giallo +Green Chrysanthemum=Crisantemo verde +Blue Geranium=Geranio blu +Viola=Viola +White Dandelion=Dente di leone bianco +Black Tulip=Tulipano nero +Red Mushroom=Fungo rosso +Brown Mushroom=Fungo marrone +Waterlily=Ninfea \ No newline at end of file diff --git a/mods/flowers/locale/flowers.ms.tr b/mods/flowers/locale/flowers.ms.tr new file mode 100644 index 0000000..4e846eb --- /dev/null +++ b/mods/flowers/locale/flowers.ms.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=Ros Merah +Orange Tulip=Tulip Jingga +Yellow Dandelion=Dandelion Kuning +Green Chrysanthemum=Kekwa Hijau +Blue Geranium=Geranium Biru +Viola=Violet +White Dandelion=Dandelion Putih +Black Tulip=Tulip Hitam +Red Mushroom=Cendawan Merah +Brown Mushroom=Cendawan Perang +Waterlily=Teratai diff --git a/mods/flowers/locale/flowers.ru.tr b/mods/flowers/locale/flowers.ru.tr new file mode 100644 index 0000000..d861e2a --- /dev/null +++ b/mods/flowers/locale/flowers.ru.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=КраÑÐ½Ð°Ñ Ð Ð¾Ð·Ð° +Orange Tulip=Оранжевый Тюльпан +Yellow Dandelion=Желтый Одуванчик +Green Chrysanthemum=Ð—ÐµÐ»Ñ‘Ð½Ð°Ñ Ð¥Ñ€Ð¸Ð·Ð°Ð½Ñ‚ÐµÐ¼Ð° +Blue Geranium=СинÑÑ Ð“ÐµÑ€Ð°Ð½ÑŒ +Viola=Фиалка +White Dandelion=Белый Одуванчик +Black Tulip=Черный Тюльпан +Red Mushroom=Мухомор +Brown Mushroom=Коричневый Гриб +Waterlily=Кувшинка diff --git a/mods/flowers/locale/flowers.se.tr b/mods/flowers/locale/flowers.se.tr new file mode 100644 index 0000000..1bee645 --- /dev/null +++ b/mods/flowers/locale/flowers.se.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=Röd ros +Orange Tulip=Orange Tulpan +Yellow Dandelion=Gul Maskros +Green Chrysanthemum=Grön Krysantemum +Blue Geranium=BlÃ¥ Geranium +Viola=Violett Viola +White Dandelion=Vit Maskros +Black Tulip=Svart Tulpan +Red Mushroom=Röd Svamp +Brown Mushroom=Brun Svamp +Waterlily=Näckros \ No newline at end of file diff --git a/mods/flowers/locale/flowers.zh_CN.tr b/mods/flowers/locale/flowers.zh_CN.tr new file mode 100644 index 0000000..3139dfb --- /dev/null +++ b/mods/flowers/locale/flowers.zh_CN.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=红玫瑰 +Orange Tulip=æ©™éƒé‡‘香 +Yellow Dandelion=黄蒲公英 +Green Chrysanthemum=绿èŠèŠ± +Blue Geranium=è“天竺葵 +Viola=三色堇 +White Dandelion=白蒲公英 +Black Tulip=黑éƒé‡‘香 +Red Mushroom=çº¢è˜‘è‡ +Brown Mushroom=æ£•è˜‘è‡ +Waterlily=ç¡èŽ² diff --git a/mods/flowers/locale/flowers.zh_TW.tr b/mods/flowers/locale/flowers.zh_TW.tr new file mode 100644 index 0000000..a3a3ec5 --- /dev/null +++ b/mods/flowers/locale/flowers.zh_TW.tr @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose=紅玫瑰 +Orange Tulip=橙鬱金香 +Yellow Dandelion=黃蒲公英 +Green Chrysanthemum=綠èŠèŠ± +Blue Geranium=è—天竺葵 +Viola=三色堇 +White Dandelion=白蒲公英 +Black Tulip=黑鬱金香 +Red Mushroom=ç´…è˜‘è‡ +Brown Mushroom=æ£•è˜‘è‡ +Waterlily=ç¡è“® diff --git a/mods/flowers/locale/template.txt b/mods/flowers/locale/template.txt new file mode 100644 index 0000000..a3a687f --- /dev/null +++ b/mods/flowers/locale/template.txt @@ -0,0 +1,12 @@ +# textdomain: flowers +Red Rose= +Orange Tulip= +Yellow Dandelion= +Green Chrysanthemum= +Blue Geranium= +Viola= +White Dandelion= +Black Tulip= +Red Mushroom= +Brown Mushroom= +Waterlily= diff --git a/mods/flowers/mapgen.lua b/mods/flowers/mapgen.lua new file mode 100644 index 0000000..f282f50 --- /dev/null +++ b/mods/flowers/mapgen.lua @@ -0,0 +1,181 @@ +-- +-- Mgv6 +-- + +local function register_mgv6_flower(flower_name) + minetest.register_decoration({ + name = "flowers:"..flower_name, + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.006, + spread = {x = 100, y = 100, z = 100}, + seed = 436, + octaves = 3, + persist = 0.6 + }, + y_max = 30, + y_min = 1, + decoration = "flowers:"..flower_name, + }) +end + +local function register_mgv6_mushroom(mushroom_name) + minetest.register_decoration({ + name = "flowers:"..mushroom_name, + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.04, + spread = {x = 100, y = 100, z = 100}, + seed = 7133, + octaves = 3, + persist = 0.6 + }, + y_max = 30, + y_min = 1, + decoration = "flowers:"..mushroom_name, + spawn_by = "default:tree", + num_spawn_by = 1, + }) +end + +local function register_mgv6_waterlily() + minetest.register_decoration({ + name = "flowers:waterlily", + deco_type = "simple", + place_on = {"default:dirt"}, + sidelen = 16, + noise_params = { + offset = -0.12, + scale = 0.3, + spread = {x = 100, y = 100, z = 100}, + seed = 33, + octaves = 3, + persist = 0.7 + }, + y_max = 0, + y_min = 0, + decoration = "flowers:waterlily_waving", + param2 = 0, + param2_max = 3, + place_offset_y = 1, + }) +end + +function flowers.register_mgv6_decorations() + register_mgv6_flower("rose") + register_mgv6_flower("tulip") + register_mgv6_flower("dandelion_yellow") + register_mgv6_flower("geranium") + register_mgv6_flower("viola") + register_mgv6_flower("dandelion_white") + + register_mgv6_mushroom("mushroom_brown") + register_mgv6_mushroom("mushroom_red") + + register_mgv6_waterlily() +end + + +-- +-- All other biome API mapgens +-- + +local function register_flower(seed, flower_name) + minetest.register_decoration({ + name = "flowers:"..flower_name, + deco_type = "simple", + place_on = {"default:dirt_with_grass"}, + sidelen = 16, + noise_params = { + offset = -0.02, + scale = 0.04, + spread = {x = 200, y = 200, z = 200}, + seed = seed, + octaves = 3, + persist = 0.6 + }, + biomes = {"grassland", "deciduous_forest"}, + y_max = 31000, + y_min = 1, + decoration = "flowers:"..flower_name, + }) +end + +local function register_mushroom(mushroom_name) + minetest.register_decoration({ + name = "flowers:"..mushroom_name, + deco_type = "simple", + place_on = {"default:dirt_with_grass", "default:dirt_with_coniferous_litter"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.006, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.66 + }, + biomes = {"deciduous_forest", "coniferous_forest"}, + y_max = 31000, + y_min = 1, + decoration = "flowers:"..mushroom_name, + }) +end + +local function register_waterlily() + minetest.register_decoration({ + name = "default:waterlily", + deco_type = "simple", + place_on = {"default:dirt"}, + sidelen = 16, + noise_params = { + offset = -0.12, + scale = 0.3, + spread = {x = 200, y = 200, z = 200}, + seed = 33, + octaves = 3, + persist = 0.7 + }, + biomes = {"rainforest_swamp", "savanna_shore", "deciduous_forest_shore"}, + y_max = 0, + y_min = 0, + decoration = "flowers:waterlily_waving", + param2 = 0, + param2_max = 3, + place_offset_y = 1, + }) +end + +function flowers.register_decorations() + register_flower(436, "rose") + register_flower(19822, "tulip") + register_flower(1220999, "dandelion_yellow") + register_flower(800081, "chrysanthemum_green") + register_flower(36662, "geranium") + register_flower(1133, "viola") + register_flower(73133, "dandelion_white") + register_flower(42, "tulip_black") + + register_mushroom("mushroom_brown") + register_mushroom("mushroom_red") + + register_waterlily() +end + + +-- +-- Detect mapgen to select functions +-- + +local mg_name = minetest.get_mapgen_setting("mg_name") +if mg_name == "v6" then + flowers.register_mgv6_decorations() +else + flowers.register_decorations() +end diff --git a/mods/flowers/mod.conf b/mods/flowers/mod.conf new file mode 100644 index 0000000..cdafe64 --- /dev/null +++ b/mods/flowers/mod.conf @@ -0,0 +1,3 @@ +name = flowers +description = Minetest Game mod: flowers +depends = default diff --git a/mods/flowers/textures/flowers_chrysanthemum_green.png b/mods/flowers/textures/flowers_chrysanthemum_green.png new file mode 100644 index 0000000..1198046 Binary files /dev/null and b/mods/flowers/textures/flowers_chrysanthemum_green.png differ diff --git a/mods/flowers/textures/flowers_dandelion_white.png b/mods/flowers/textures/flowers_dandelion_white.png new file mode 100644 index 0000000..1bc02fb Binary files /dev/null and b/mods/flowers/textures/flowers_dandelion_white.png differ diff --git a/mods/flowers/textures/flowers_dandelion_yellow.png b/mods/flowers/textures/flowers_dandelion_yellow.png new file mode 100644 index 0000000..544f60c Binary files /dev/null and b/mods/flowers/textures/flowers_dandelion_yellow.png differ diff --git a/mods/flowers/textures/flowers_geranium.png b/mods/flowers/textures/flowers_geranium.png new file mode 100644 index 0000000..88de1d7 Binary files /dev/null and b/mods/flowers/textures/flowers_geranium.png differ diff --git a/mods/flowers/textures/flowers_mushroom_brown.png b/mods/flowers/textures/flowers_mushroom_brown.png new file mode 100644 index 0000000..33ffcd4 Binary files /dev/null and b/mods/flowers/textures/flowers_mushroom_brown.png differ diff --git a/mods/flowers/textures/flowers_mushroom_red.png b/mods/flowers/textures/flowers_mushroom_red.png new file mode 100644 index 0000000..a68f5d5 Binary files /dev/null and b/mods/flowers/textures/flowers_mushroom_red.png differ diff --git a/mods/flowers/textures/flowers_rose.png b/mods/flowers/textures/flowers_rose.png new file mode 100644 index 0000000..e3b841d Binary files /dev/null and b/mods/flowers/textures/flowers_rose.png differ diff --git a/mods/flowers/textures/flowers_tulip.png b/mods/flowers/textures/flowers_tulip.png new file mode 100644 index 0000000..471fcd3 Binary files /dev/null and b/mods/flowers/textures/flowers_tulip.png differ diff --git a/mods/flowers/textures/flowers_tulip_black.png b/mods/flowers/textures/flowers_tulip_black.png new file mode 100644 index 0000000..1dd09f7 Binary files /dev/null and b/mods/flowers/textures/flowers_tulip_black.png differ diff --git a/mods/flowers/textures/flowers_viola.png b/mods/flowers/textures/flowers_viola.png new file mode 100644 index 0000000..ca2d750 Binary files /dev/null and b/mods/flowers/textures/flowers_viola.png differ diff --git a/mods/flowers/textures/flowers_waterlily.png b/mods/flowers/textures/flowers_waterlily.png new file mode 100644 index 0000000..305c445 Binary files /dev/null and b/mods/flowers/textures/flowers_waterlily.png differ diff --git a/mods/flowers/textures/flowers_waterlily_bottom.png b/mods/flowers/textures/flowers_waterlily_bottom.png new file mode 100644 index 0000000..3dbeaf4 Binary files /dev/null and b/mods/flowers/textures/flowers_waterlily_bottom.png differ diff --git a/mods/food/init.lua b/mods/food/init.lua new file mode 100644 index 0000000..0aa7571 --- /dev/null +++ b/mods/food/init.lua @@ -0,0 +1 @@ +dofile(minetest.get_modpath('food')..'/meats.lua') diff --git a/mods/food/license.txt b/mods/food/license.txt new file mode 100644 index 0000000..e69de29 diff --git a/mods/food/meats.lua b/mods/food/meats.lua new file mode 100644 index 0000000..f378c25 --- /dev/null +++ b/mods/food/meats.lua @@ -0,0 +1,25 @@ +minetest.register_craftitem('food:steak_raw', { + description = 'Raw Steak', + inventory_image = 'food_steak_raw.png', + groups = {raw_meat = 1, not_in_creative_inventory=1}, + on_use = minetest.item_eat(3) +}) + +minetest.register_craftitem('food:pork_raw', { + description = 'Raw Pork', + inventory_image = 'food_steak_raw.png', + groups = {raw_meat = 1, not_in_creative_inventory=1}, + on_use = minetest.item_eat(3) +}) + +minetest.register_craftitem('food:chicken_raw', { + description = 'Raw Chicken', + inventory_image = 'food_steak_raw.png', + groups = {raw_meat = 1, not_in_creative_inventory=1}, + on_use = minetest.item_eat(3) +}) +--hbhunger.register_food(name, hunger_change, replace_with_item, poisen, heal, sound) + +hbhunger.register_food('food:steak_raw', 1, '', 5) +hbhunger.register_food('food:pork_raw', 3, '', 3) +hbhunger.register_food('food:chicken_raw', 3, '', 3) diff --git a/mods/food/mod.conf b/mods/food/mod.conf new file mode 100644 index 0000000..9a87ba5 --- /dev/null +++ b/mods/food/mod.conf @@ -0,0 +1,2 @@ +name = food +depends = hbhunger diff --git a/mods/food/veggies.lua b/mods/food/veggies.lua new file mode 100644 index 0000000..e69de29 diff --git a/mods/furniture/bedroom.lua b/mods/furniture/bedroom.lua new file mode 100644 index 0000000..69ec29a --- /dev/null +++ b/mods/furniture/bedroom.lua @@ -0,0 +1,47 @@ +local dye_table = dye.dyes + +for i in ipairs(dye_table) do + local name = dye_table[i][1] + local desc = dye_table[i][2] + local hex = dye_table[i][3] + + minetest.register_node('furniture:bed1_'..name, { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Bed with '..desc..' Blankets', + drawtype = 'mesh', + mesh = 'furniture_bed1.obj', + tiles = {'furniture_bed1_wood.png', 'furniture_bed1_sheets.png'}, + overlay_tiles = {{name = '(furniture_bed1_sheets.png^[multiply:'..hex..')^furniture_bed1_mask.png', color = 'white'}}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {{-.5, -.5, -.5, .5, 0, 1.5}, + {-.5, 0, 1.35, .5, .5, 1.5}} + }, + collision_box = { + type = 'fixed', + fixed = {{-.5, -.5, -.5, .5, 0, 1.5}, + {-.5, 0, 1.35, .5, .5, 1.5}} + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + after_place_node = function(pos, placer, itemstack) + if not epic.space_to_front(pos) then + minetest.remove_node(pos) + return itemstack + end + end, + after_dig_node = function(pos, oldnode) + epic.remove_front_node(pos, oldnode) + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + beds.on_rightclick(pos, clicker) + return itemstack + end, + on_rotate = function(pos, node) + return false + end, + }) + +end diff --git a/mods/furniture/craftitems.lua b/mods/furniture/craftitems.lua new file mode 100644 index 0000000..4cfba16 --- /dev/null +++ b/mods/furniture/craftitems.lua @@ -0,0 +1,32 @@ +minetest.register_craftitem('furniture:brush', { + description = 'Stain Brush', + inventory_image = 'furniture_brush.png', + groups = {stain_brush = 1} +}) + +minetest.register_craftitem('furniture:hinge', { + description = 'Hinge', + inventory_image = 'furniture_hinge.png' +}) + +minetest.register_craftitem('furniture:lock', { + description = 'Lock', + inventory_image = 'furniture_lock.png' +}) + +minetest.register_craftitem('furniture:thread', { + description = 'Spool of Thread', + inventory_image = 'furniture_thread.png', + groups = {thread=1, not_in_creative_inventory=1} +}) + +minetest.register_craftitem('furniture:wheel', { + description = 'Wooden Wheel', + inventory_image = 'furniture_wheel.png' +}) + +minetest.register_craftitem('furniture:fabric', { + description = 'Fabric', + inventory_image = 'furniture_fabric.png', + groups = {fabric=1, not_in_creative_inventory=1} +}) diff --git a/mods/furniture/crafts.lua b/mods/furniture/crafts.lua new file mode 100644 index 0000000..cf0bbfe --- /dev/null +++ b/mods/furniture/crafts.lua @@ -0,0 +1,35 @@ +minetest.register_craft({ + type = 'shapeless', + output = 'furniture:lectern_encyclopedia', + recipe = { + 'doc_encyclopedia:encyclopedia', + 'furniture:lectern' + } +}) + +minetest.register_craft({ + type = 'shapeless', + output = 'furniture:bookshelf_locked', + recipe = { + 'default:bookshelf', + 'furniture:lock' + } +}) + +minetest.register_craft({ + type = 'shapeless', + output = 'furniture:shelf_vessel_locked', + recipe = { + 'vessels:shelf', + 'furniture:lock' + } +}) + +minetest.register_craft({ + type = 'shapeless', + output = 'furniture:multishelf_locked', + recipe = { + 'xdecor:multishelf', + 'furniture:lock' + } +}) diff --git a/mods/furniture/decor.lua b/mods/furniture/decor.lua new file mode 100644 index 0000000..09bffd9 --- /dev/null +++ b/mods/furniture/decor.lua @@ -0,0 +1,98 @@ +local dye_table = dye.dyes + +for i in ipairs(dye_table) do + local name = dye_table[i][1] + local desc = dye_table[i][2] + local hex = dye_table[i][3] + + minetest.register_node('furniture:curtain_short_'..name..'_0', { + description = 'Short '..desc..' Curtain Closed', + drawtype = 'mesh', + mesh = 'furniture_curtain_short.obj', + tiles = {'furniture_curtain_short_0.png^[multiply:'..hex}, + paramtype = 'light', + paramtype2 = 'facedir', + drop = 'furniture:curtain_short_'..name..'_1', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, .4, .5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, .4, .5, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 3, snappy=3, not_in_creative_inventory=1}, + on_rightclick = function(pos, node) + minetest.set_node(pos, {name='furniture:curtain_short_'..name..'_1', param2 = node.param2}) + end + }) + + minetest.register_node('furniture:curtain_short_'..name..'_1', { + description = 'Short '..desc..' Curtain Open', + drawtype = 'mesh', + mesh = 'furniture_curtain_short.obj', + tiles = {'furniture_curtain_short_1.png^[multiply:'..hex}, + inventory_image = 'furniture_curtain_short_1.png^[multiply:'..hex, + paramtype = 'light', + paramtype2 = 'facedir', + sunlight_propagates = true, + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, .4, .5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, .4, .5, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 3, snappy=3}, + on_rightclick = function(pos, node) + minetest.set_node(pos, {name='furniture:curtain_short_'..name..'_0', param2 = node.param2}) + end + }) + + minetest.register_node('furniture:curtain_tall_'..name..'_0', { + description = 'Tall '..desc..' Curtain Closed', + drawtype = 'mesh', + mesh = 'furniture_curtain_tall.obj', + tiles = {'furniture_curtain_tall_0.png^[multiply:'..hex}, + paramtype = 'light', + paramtype2 = 'facedir', + drop = 'furniture:curtain_tall_'..name..'_1', + selection_box = { + type = 'fixed', + fixed = {-.5, -1.3, .4, .5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -1.3, .4, .5, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 3, snappy=3, not_in_creative_inventory=1}, + on_rightclick = function(pos, node) + minetest.set_node(pos, {name='furniture:curtain_tall_'..name..'_1', param2 = node.param2}) + end + }) + + minetest.register_node('furniture:curtain_tall_'..name..'_1', { + description = 'Tall '..desc..' Curtain Open', + drawtype = 'mesh', + mesh = 'furniture_curtain_tall.obj', + tiles = {'furniture_curtain_tall_1.png^[multiply:'..hex}, + inventory_image = 'furniture_curtain_tall_1.png^[multiply:'..hex, + paramtype = 'light', + paramtype2 = 'facedir', + sunlight_propagates = true, + selection_box = { + type = 'fixed', + fixed = {-.5, -1.3, .4, .5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -1.3, .4, .5, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 3, snappy=3}, + on_rightclick = function(pos, node) + minetest.set_node(pos, {name='furniture:curtain_tall_'..name..'_0', param2 = node.param2}) + end + }) + +end diff --git a/mods/furniture/fabricandthread.lua b/mods/furniture/fabricandthread.lua new file mode 100644 index 0000000..fc9017a --- /dev/null +++ b/mods/furniture/fabricandthread.lua @@ -0,0 +1,25 @@ +local dye_table = dye.dyes + +for i in ipairs(dye_table) do + local name = dye_table[i][1] + local desc = dye_table[i][2] + local hex = dye_table[i][3] + + minetest.register_craftitem('furniture:fabric_'..name, { + description = (desc..' Fabric'), + inventory_image = 'furniture_fabric.png^[multiply:'..hex, + groups = {fabric=1} + }) + + minetest.register_craftitem('furniture:thread_'..name, { + description = (desc..' Spool of Thread'), + inventory_image = '(furniture_thread.png^[multiply:'..hex..')^furniture_thread_mask.png', + groups = {thread=1} + }) + + minetest.register_craftitem('furniture:cushion_'..name, { + description = (desc..' Cushion'), + inventory_image = 'furniture_cushion_pad_inv.png^[multiply:'..hex, + }) + +end diff --git a/mods/furniture/fences.lua b/mods/furniture/fences.lua new file mode 100644 index 0000000..1ecb72e --- /dev/null +++ b/mods/furniture/fences.lua @@ -0,0 +1,104 @@ +minetest.register_node('furniture:fence_1_a', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Fence', + drawtype = 'mesh', + mesh = 'furniture_fence_1_a.obj', + tiles = {'furniture_fence.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.0625, .5, .5, .0625}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.0625, .5, .5, .0625}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node) + minetest.set_node(pos, {name='furniture:fence_1_d', param2 = node.param2}) + end, +}) + +minetest.register_node('furniture:fence_1_b', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Fence', + drawtype = 'mesh', + mesh = 'furniture_fence_1_b.obj', + tiles = {'furniture_fence.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = { + {0.0625, -0.5, -0.0625, 0.5, 0.5, 0.0625}, + {-0.0625, -0.5, -0.5, 0.0625, 0.5, 0.0625} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {0.0625, -0.5, -0.0625, 0.5, 0.5, 0.0625}, + {-0.0625, -0.5, -0.5, 0.0625, 0.5, 0.0625} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, +}) + +minetest.register_node('furniture:fence_1_c', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Fence', + drawtype = 'mesh', + mesh = 'furniture_fence_1_c.obj', + tiles = {'furniture_fence.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = { + {-0.5, -0.5, -0.0625, -0.0625, 0.5, 0.0625}, + {-0.0625, -0.5, -0.0625, 0.0625, 0.5, 0.5} + }, + }, + collision_box = { + type = 'fixed', + fixed = { + {-0.5, -0.5, -0.0625, -0.0625, 0.5, 0.0625}, + {-0.0625, -0.5, -0.0625, 0.0625, 0.5, 0.5} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, +}) + +minetest.register_node('furniture:fence_1_d', { + description = 'Gate', + drawtype = 'mesh', + mesh = 'furniture_fence_1_d.obj', + tiles = {'furniture_fence.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = { + {0.375, -0.5, -0.0625, 0.5, 0.5, 0.0625}, + {-0.5, -0.5, -0.0625, -0.375, 0.5, 0.0625}, + {-0.375, -0.5, -0.0625, -0.25, 0.375, 0.75} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {0.375, -0.5, -0.0625, 0.5, 0.5, 0.0625}, + {-0.5, -0.5, -0.0625, -0.375, 0.5, 0.0625}, + {-0.375, -0.5, -0.0625, -0.25, 0.375, 0.75} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1, not_in_creative_inventory=1}, + on_rightclick = function(pos, node) + minetest.set_node(pos, {name='furniture:fence_1_a', param2 = node.param2}) + end, +}) diff --git a/mods/furniture/formspecs.lua b/mods/furniture/formspecs.lua new file mode 100644 index 0000000..a56578d --- /dev/null +++ b/mods/furniture/formspecs.lua @@ -0,0 +1,72 @@ +local esc = minetest.formspec_escape +local title, text = '', '' + +function furniture.storage_24_form(pos, name) + local meta = minetest.get_meta(pos) + local spos = pos.x .. "," .. pos.y .. "," .. pos.z + local existing_name = meta:get_string('infotext') + name = name or existing_name + local formspec = + 'size[8,7.75]'.. + 'list[nodemeta:'..spos..';main;0,0;8,3;]'.. + 'field[1.3,3.3;2,1;description;;'..name..']'.. + 'button[3,3;1,1;save;Save]'.. + 'button[4,3;1,1;sort;Sort]'.. + 'list[current_player;main;0,4;8,4;]'.. + 'listring[]' + return formspec +end + +function furniture.storage_32_form(pos, name) + local meta = minetest.get_meta(pos) + local existing_name = meta:get_string('infotext') + name = name or existing_name + local formspec = + 'size[8,8.75]'.. + 'list[current_name;main;0,0;8,4;]'.. + 'field[1.3,4.3;2,1;description;;'..name..']'.. + 'button[3,4;1,1;save;Save]'.. + 'button[4,4;1,1;sort;Sort]'.. + 'list[current_player;main;0,5;8,4;]'.. + 'listring[]' + return formspec +end + +function furniture.storage_60_form(pos, name) + local meta = minetest.get_meta(pos) + local existing_name = meta:get_string('infotext') + name = name or existing_name + local formspec = + 'size[10,10.75]'.. + 'list[current_name;main;0,0;10,6;]'.. + 'field[2.3,6.3;2,1;description;;'..name..']'.. + 'button[4,6;1,1;save;Save]'.. + 'button[5,6;1,1;sort;Sort]'.. + 'list[current_player;main;1,7;8,4;]'.. + 'listring[]' + return formspec +end + +local lectern_formspec = + 'size[11,8]'.. + 'no_prepend[]'.. + 'bgcolor[#080808BB;true]'.. + 'background[0,0;11,8;furniture_lectern_formspec.png]' + +function furniture.lectern_edit_sign(title, content) + local formspec = + lectern_formspec.. + "field[0.5,1;7.5,0;title;"..esc("Title:")..";"..esc(title) .. "]" .. + "label[0.25,1.1;Body:]".. + "textarea[0.5,1.5;10.6,5.5;content;;"..esc(content).."]" .. + "button_exit[4,6.5;4,1;save;Save]" + return formspec +end + +function furniture.lectern_view_sign(title, content) + local formspec = + lectern_formspec.. + 'hypertext[0,0;11,1;;
]'.. + "textarea[0.5,1.5;10.6,6.5;;;"..esc(content).."]" + return formspec +end diff --git a/mods/furniture/functions.lua b/mods/furniture/functions.lua new file mode 100644 index 0000000..3402e11 --- /dev/null +++ b/mods/furniture/functions.lua @@ -0,0 +1,120 @@ +--Mostly stolen code from Xdecor. + +local function top_face(pointed_thing) + if not pointed_thing then return end + return pointed_thing.above.y > pointed_thing.under.y +end + +function furniture.sit(pos, node, clicker, pointed_thing, rotate) + if not top_face(pointed_thing) then return end + local player_name = clicker:get_player_name() + local objs = minetest.get_objects_inside_radius(pos, 0.1) + local vel = clicker:get_player_velocity() + local ctrl = clicker:get_player_control() + local fdir = node.param2 % 32 + for _, obj in pairs(objs) do + if obj:is_player() and obj:get_player_name() ~= player_name then + return + end + end + if default.player_attached[player_name] then + pos.y = pos.y - 0.5 + clicker:set_pos(pos) + clicker:set_eye_offset(vector.new(), vector.new()) + clicker:set_physics_override(furniture.players[player_name]) + default.player_attached[player_name] = false + default.player_set_animation(clicker, "stand", 30) + elseif not default.player_attached[player_name] and fdir <= 3 and + not ctrl.sneak and vector.equals(vel, vector.new()) then + furniture.players[player_name] = clicker:get_physics_override() + clicker:set_eye_offset({x = 0, y = -7, z = 2}, vector.new()) + clicker:set_physics_override({speed = 0, jump = 0, gravity = 1}) + clicker:set_pos(pos) + default.player_attached[player_name] = true + default.player_set_animation(clicker, "sit", 30) + if rotate then + if fdir == 0 then + clicker:set_look_yaw(3.15) + elseif fdir == 1 then + clicker:set_look_yaw(7.9) + elseif fdir == 2 then + clicker:set_look_yaw(6.28) + elseif fdir == 3 then + clicker:set_look_yaw(4.75) + end + end + end +end + +function furniture.sort_inventory(inv) -- Copied from the Technic_chests mod. + local inlist = inv:get_list("main") + local typecnt = {} + local typekeys = {} + for _, st in ipairs(inlist) do + if not st:is_empty() then + local n = st:get_name() + local w = st:get_wear() + local m = st:get_metadata() + local k = string.format("%s %05d %s", n, w, m) + if not typecnt[k] then + typecnt[k] = { + name = n, + wear = w, + metadata = m, + stack_max = st:get_stack_max(), + count = 0, + } + table.insert(typekeys, k) + end + typecnt[k].count = typecnt[k].count + st:get_count() + end + end + table.sort(typekeys) + local outlist = {} + for _, k in ipairs(typekeys) do + local tc = typecnt[k] + while tc.count > 0 do + local c = math.min(tc.count, tc.stack_max) + table.insert(outlist, ItemStack({ + name = tc.name, + wear = tc.wear, + metadata = tc.metadata, + count = c, + })) + tc.count = tc.count - c + end + end + if #outlist > #inlist then return end + while #outlist < #inlist do + table.insert(outlist, ItemStack(nil)) + end + inv:set_list("main", outlist) +end + +function furniture.inv_take_put(pos, listname, index, stack, player) + local player_name = player:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(player, 'protection_bypass') then + return 0 + else + return 99 + end +end + +function furniture.inv_manipulate(pos, from_list, from_index, to_list, to_index, count, player) + local player_name = player:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(player, 'protection_bypass') then + return 0 + else + return 99 + end +end + +function furniture.inv_take(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. " takes " .. stack:get_name() .. + " from storage at " .. minetest.pos_to_string(pos)) +end + +function furniture.inv_put(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. " moves " .. stack:get_name() .. + " to storage at " .. minetest.pos_to_string(pos)) +end diff --git a/mods/furniture/init.lua b/mods/furniture/init.lua new file mode 100644 index 0000000..1ff419c --- /dev/null +++ b/mods/furniture/init.lua @@ -0,0 +1,16 @@ +furniture = {} +furniture.players = {} +dofile(minetest.get_modpath('furniture')..'/bedroom.lua') --Things you'd find in a bedroom. +dofile(minetest.get_modpath('furniture')..'/craftitems.lua') --Items used in recipes. +dofile(minetest.get_modpath('furniture')..'/crafts.lua') +dofile(minetest.get_modpath('furniture')..'/decor.lua') +dofile(minetest.get_modpath('furniture')..'/fabricandthread.lua') +dofile(minetest.get_modpath('furniture')..'/fences.lua') --Fences are here, duh! +dofile(minetest.get_modpath('furniture')..'/formspecs.lua') --Formspecs for the nodes. +dofile(minetest.get_modpath('furniture')..'/functions.lua') --Different functions to control stuff. +dofile(minetest.get_modpath('furniture')..'/library.lua') --Books things. +dofile(minetest.get_modpath('furniture')..'/lighting.lua') --Things that add light. +dofile(minetest.get_modpath('furniture')..'/seating.lua') --chairs, benches, stools +dofile(minetest.get_modpath('furniture')..'/stain.lua') --Brushes for coloring furniture +dofile(minetest.get_modpath('furniture')..'/storage.lua') --Chests, boxes, etc. +dofile(minetest.get_modpath('furniture')..'/tables.lua') --Not sure if I'll ever have more than one table. diff --git a/mods/furniture/library.lua b/mods/furniture/library.lua new file mode 100644 index 0000000..6948105 --- /dev/null +++ b/mods/furniture/library.lua @@ -0,0 +1,74 @@ +minetest.register_node('furniture:lectern', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Lectern', + drawtype = 'mesh', + mesh = 'furniture_lectern.obj', + tiles = {'furniture_lectern.png',}, + overlay_tiles = {{name='furniture_lectern_overlay.png', color='white'}}, + sounds = default.node_sound_wood_defaults(), + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-.3, -.5, -.3, .3, .5, .3}, + }, + collision_box = { + type = 'fixed', + fixed = {-.3, -.5, -.3, .3, .5, .3}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string('owner', placer:get_player_name()) + meta:set_string('infotext', '') + meta:set_string('title', '') + meta:set_string('content', '') + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local name = clicker:get_player_name() + local meta = minetest.get_meta(pos) + local owner = meta:get_string('owner') + local title = meta:get_string('title') + local content = meta:get_string('content') + if owner == name then + meta:set_string('formspec', furniture.lectern_edit_sign(title, content)) + else + meta:set_string('formspec', furniture.lectern_view_sign(title, content)) + end + end, + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if fields ['save'] then + local player_name = sender:get_player_name() + meta:set_string('infotext', fields.title) + meta:set_string('title', fields.title) + meta:set_string('content', fields.content) + minetest.log("action", (player_name or "").." wrote \""..fields.title.."\" to lectern at "..minetest.pos_to_string(pos)) + end + end, +}) + +minetest.register_node('furniture:lectern_encyclopedia', { + description = 'Lectern with Encyclopedia', + drawtype = 'mesh', + mesh = 'furniture_lectern.obj', + tiles = {'furniture_lectern.png',}, + overlay_tiles = {{name='furniture_lectern_encylopedia_overlay.png', color='white'}}, + sounds = default.node_sound_wood_defaults(), + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-.3, -.5, -.3, .3, .5, .3}, + }, + collision_box = { + type = 'fixed', + fixed = {-.3, -.5, -.3, .3, .5, .3}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker) + doc.show_doc(clicker:get_player_name()) + end, +}) diff --git a/mods/furniture/license.txt b/mods/furniture/license.txt new file mode 100644 index 0000000..2a0f97b --- /dev/null +++ b/mods/furniture/license.txt @@ -0,0 +1,7 @@ +Textures based off of https://renderman.pixar.com/pixar-one-twenty-eight +Code is licensed MIT, Textures CC by SA 4.0 +Copyright 2020 Nathan Salapat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/furniture/lighting.lua b/mods/furniture/lighting.lua new file mode 100644 index 0000000..f5b4355 --- /dev/null +++ b/mods/furniture/lighting.lua @@ -0,0 +1,58 @@ +local function particles_lantern(pos) + minetest.add_particlespawner({ + amount = 48, + time = 4, + minpos = {x=pos.x - 0.25, y=pos.y, z=pos.z - 0.25}, + maxpos = {x=pos.x + 0.25, y=pos.y + 0.25, z=pos.z + 0.25}, + minvel = {x=-.3, y=-.03, z=-.3}, maxvel = {x=.3, y=.05, z=.3}, + minacc = {x=-.1, y=.02, z=-.1}, maxacc = {x=.1, y=.02, z=.1}, + minexptime = 1, maxexptime = 3, + minsize = 1, maxsize = 2, + collisiondetection = false, + texture = 'furniture_lantern_particle.png', + glow = 10, + }) +end + +minetest.register_node('furniture:lantern_ceiling', { + _doc_items_crafting = 'This is crafted in the Smithy Station.', + description = 'Ceiling Lantern', + drawtype = 'mesh', + mesh = 'furniture_lantern.obj', + tiles = {'furniture_lantern.png'}, + paramtype = 'light', + light_source = 14, + walkable = false, + paramtype2 = 'facedir', + selection_box = { + type = 'fixed', + fixed = {-.375, 0, -.375, .375, 0.5, .375}, + }, + collision_box = { + type = 'fixed', + fixed = {-.375, 0, -.375, .375, 0.5, .375}, + }, + groups = {oddly_breakable_by_hand = 2, cracky=3}, + on_rightclick = function(pos) + particles_lantern(pos) + end, +}) + +minetest.register_abm({ + label = 'Lantern effects', + nodenames = {'furniture:lantern_ceiling'}, + interval = 13, + chance = 7, + action = function(pos, node) + particles_lantern(pos) + local objs = minetest.get_objects_inside_radius(pos, 4) + for _, obj in pairs(objs) do + if obj:is_player() then + local name = obj:get_player_name() + local hunger = tonumber(hbhunger.hunger[name]) + 6 + hbhunger.hunger[name] = math.min(30, hunger) + hbhunger.set_hunger_raw(obj) + end + end + end +}) diff --git a/mods/furniture/mod.conf b/mods/furniture/mod.conf new file mode 100644 index 0000000..298c01e --- /dev/null +++ b/mods/furniture/mod.conf @@ -0,0 +1,2 @@ +name = furniture +depends = xdecor, epic, beds diff --git a/mods/furniture/models/furniture_bed1.obj b/mods/furniture/models/furniture_bed1.obj new file mode 100644 index 0000000..c985f80 --- /dev/null +++ b/mods/furniture/models/furniture_bed1.obj @@ -0,0 +1,290 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Bed_Cube.010 +v -0.437500 -0.437500 1.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 -0.437500 -0.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 -0.437500 1.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 -0.437500 -0.437500 +v 0.437500 0.000000 -0.437500 +v 0.375000 0.062500 -0.500000 +v 0.375000 -0.500000 -0.500000 +v 0.375000 0.062500 -0.375000 +v 0.375000 -0.500000 -0.375000 +v 0.500000 -0.500000 -0.375000 +v 0.500000 0.062500 -0.375000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.062500 -0.500000 +v 0.375000 0.500000 1.375000 +v 0.375000 -0.500000 1.375000 +v 0.375000 0.500000 1.500000 +v 0.375000 -0.500000 1.500000 +v 0.500000 -0.500000 1.500000 +v 0.500000 0.500000 1.500000 +v 0.500000 -0.500000 1.375000 +v 0.500000 0.500000 1.375000 +v -0.375000 0.062500 1.468750 +v -0.375000 0.437500 1.468750 +v -0.375000 0.062500 1.406250 +v -0.375000 0.437500 1.406250 +v 0.375000 0.062500 1.468750 +v 0.375000 0.437500 1.468750 +v 0.375000 0.062500 1.406250 +v 0.375000 0.437500 1.406250 +v -0.375000 0.000000 1.375000 +v -0.375000 0.062500 1.375000 +v -0.375000 0.000000 1.062500 +v -0.375000 0.062500 1.062500 +v 0.375000 0.000000 1.375000 +v 0.375000 0.062500 1.375000 +v 0.375000 0.000000 1.062500 +v 0.375000 0.062500 1.062500 +v -0.500000 0.062500 -0.375000 +v -0.500000 -0.500000 -0.375000 +v -0.375000 0.062500 -0.375000 +v -0.375000 -0.500000 -0.375000 +v -0.375000 -0.500000 -0.500000 +v -0.375000 0.062500 -0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 0.062500 -0.500000 +v -0.375000 0.500000 1.375000 +v -0.375000 -0.500000 1.375000 +v -0.500000 0.500000 1.375000 +v -0.500000 -0.500000 1.375000 +v -0.500000 -0.500000 1.500000 +v -0.500000 0.500000 1.500000 +v -0.375000 -0.500000 1.500000 +v -0.375000 0.500000 1.500000 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +v -0.437500 0.000000 1.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 0.000000 1.437500 +v 0.437500 0.000000 -0.437500 +vt 0.437500 0.890625 +vt 0.328125 0.890625 +vt 0.328125 0.421875 +vt 0.437500 0.421875 +vt 0.328125 0.312500 +vt 0.109375 0.421875 +vt 0.109375 0.312500 +vt 0.000000 0.421875 +vt 0.109375 0.890625 +vt 0.000000 0.890625 +vt 0.109375 1.000000 +vt 0.328125 1.000000 +vt 0.109375 0.421875 +vt 0.109375 0.890625 +vt 0.734375 0.000000 +vt 0.734375 0.140625 +vt 0.703125 0.140625 +vt 0.703125 0.000000 +vt 0.671875 0.140625 +vt 0.671875 0.000000 +vt 0.640625 0.140625 +vt 0.640625 0.000000 +vt 0.609375 0.140625 +vt 0.609375 0.000000 +vt 0.703125 0.171875 +vt 0.734375 0.171875 +vt 0.031250 0.000000 +vt 0.031250 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.000000 +vt 0.125000 0.000000 +vt 0.125000 0.250000 +vt 0.093750 0.250000 +vt 0.093750 0.000000 +vt 0.062500 0.250000 +vt 0.062500 0.000000 +vt 0.000000 0.281250 +vt 0.031250 0.281250 +vt 0.476562 0.187500 +vt 0.382812 0.187500 +vt 0.382812 0.000000 +vt 0.476562 0.000000 +vt 0.273438 0.000000 +vt 0.367188 0.000000 +vt 0.367188 0.187500 +vt 0.273438 0.187500 +vt 0.257812 0.187500 +vt 0.257812 0.000000 +vt 0.453125 0.906250 +vt 0.468750 0.906250 +vt 0.468750 0.984375 +vt 0.453125 0.984375 +vt 0.468750 1.000000 +vt 0.656250 0.984375 +vt 0.656250 1.000000 +vt 0.671875 0.984375 +vt 0.656250 0.906250 +vt 0.671875 0.906250 +vt 0.656250 0.890625 +vt 0.468750 0.890625 +vt 0.609375 0.000000 +vt 0.609375 0.140625 +vt 0.578125 0.140625 +vt 0.578125 0.000000 +vt 0.546875 0.140625 +vt 0.546875 0.000000 +vt 0.515625 0.140625 +vt 0.515625 0.000000 +vt 0.484375 0.140625 +vt 0.484375 0.000000 +vt 0.578125 0.171875 +vt 0.609375 0.171875 +vt 0.156250 0.000000 +vt 0.156250 0.250000 +vt 0.125000 0.250000 +vt 0.125000 0.000000 +vt 0.250000 0.000000 +vt 0.250000 0.250000 +vt 0.218750 0.250000 +vt 0.218750 0.000000 +vt 0.187500 0.250000 +vt 0.187500 0.000000 +vt 0.125000 0.281250 +vt 0.156250 0.281250 +vt 0.328125 0.890625 +vt 0.109375 0.890625 +vt 0.328125 0.890625 +vt 0.328125 0.421875 +vt 0.109375 0.421875 +vt 0.109375 0.421875 +vt 0.109375 0.890625 +vt 0.328125 0.421875 +vt 0.328125 0.890625 +vt 0.109375 0.890625 +vt 0.328125 0.890625 +vt 0.328125 0.421875 +vt 0.109375 0.421875 +vt 0.328125 0.421875 +vt 0.328125 0.421875 +vt 0.109375 0.421875 +vt 0.109375 0.890625 +vt 0.109375 0.421875 +vt 0.109375 0.890625 +vt 0.328125 0.890625 +vt 0.328125 0.890625 +vt 0.109375 0.890625 +vt 0.328125 0.890625 +vt 0.328125 0.421875 +vt 0.109375 0.421875 +vt 0.109375 0.421875 +vt 0.109375 0.890625 +vt 0.328125 0.421875 +vt 0.109375 0.421875 +vt 0.109375 0.890625 +vt 0.328125 0.890625 +vt 0.328125 0.421875 +vt 0.328125 0.421875 +vt 0.328125 0.890625 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 6/9/4 8/6/4 60/13/4 59/14/4 +f 12/15/1 11/16/1 9/17/1 10/18/1 +f 10/18/2 9/17/2 16/19/2 15/20/2 +f 15/20/3 16/19/3 14/21/3 13/22/3 +f 13/22/4 14/21/4 11/23/4 12/24/4 +f 16/25/5 9/17/5 11/16/5 14/26/5 +f 20/27/1 19/28/1 17/29/1 18/30/1 +f 18/31/2 17/32/2 24/33/2 23/34/2 +f 23/34/3 24/33/3 22/35/3 21/36/3 +f 21/36/4 22/35/4 19/28/4 20/27/4 +f 24/37/5 17/29/5 19/28/5 22/38/5 +f 27/39/2 28/40/2 32/41/2 31/42/2 +f 29/43/4 30/44/4 26/45/4 25/46/4 +f 27/47/6 31/48/6 29/43/6 25/46/6 +f 32/41/5 28/40/5 26/45/5 30/44/5 +f 33/49/1 34/50/1 36/51/1 35/52/1 +f 35/53/2 36/51/2 40/54/2 39/55/2 +f 39/56/3 40/54/3 38/57/3 37/58/3 +f 37/59/4 38/57/4 34/50/4 33/60/4 +f 40/54/5 36/51/5 34/50/5 38/57/5 +f 44/61/4 43/62/4 41/63/4 42/64/4 +f 42/64/1 41/63/1 48/65/1 47/66/1 +f 47/66/2 48/65/2 46/67/2 45/68/2 +f 45/68/3 46/67/3 43/69/3 44/70/3 +f 48/71/5 41/63/5 43/62/5 46/72/5 +f 52/73/2 51/74/2 49/75/2 50/76/2 +f 50/77/3 49/78/3 56/79/3 55/80/3 +f 55/80/4 56/79/4 54/81/4 53/82/4 +f 53/82/1 54/81/1 51/74/1 52/73/1 +f 56/83/5 49/75/5 51/74/5 54/84/5 +f 57/85/4 59/14/4 63/86/4 61/87/4 +f 4/3/4 2/2/4 57/85/4 58/88/4 +f 2/2/4 6/9/4 59/14/4 57/85/4 +f 8/6/4 4/3/4 58/88/4 60/13/4 +f 63/86/4 64/89/4 68/90/4 67/91/4 +f 60/13/4 58/88/4 62/92/4 64/89/4 +f 59/14/4 60/13/4 64/89/4 63/86/4 +f 58/88/4 57/85/4 61/87/4 62/92/4 +f 65/93/4 67/91/4 71/94/4 69/95/4 +f 62/92/4 61/87/4 65/93/4 66/96/4 +f 61/87/4 63/86/4 67/91/4 65/93/4 +f 64/89/4 62/92/4 66/96/4 68/90/4 +f 72/97/4 70/98/4 74/99/4 76/100/4 +f 68/90/4 66/96/4 70/98/4 72/97/4 +f 67/91/4 68/90/4 72/97/4 71/94/4 +f 66/96/4 65/93/4 69/95/4 70/98/4 +f 75/101/4 76/100/4 80/102/4 79/103/4 +f 71/94/4 72/97/4 76/100/4 75/101/4 +f 70/98/4 69/95/4 73/104/4 74/99/4 +f 69/95/4 71/94/4 75/101/4 73/104/4 +f 77/105/4 79/103/4 83/106/4 81/107/4 +f 74/99/4 73/104/4 77/105/4 78/108/4 +f 73/104/4 75/101/4 79/103/4 77/105/4 +f 76/100/4 74/99/4 78/108/4 80/102/4 +f 83/106/4 84/109/4 88/110/4 87/111/4 +f 80/102/4 78/108/4 82/112/4 84/109/4 +f 79/103/4 80/102/4 84/109/4 83/106/4 +f 78/108/4 77/105/4 81/107/4 82/112/4 +f 87/111/4 88/110/4 92/113/4 91/114/4 +f 82/112/4 81/107/4 85/115/4 86/116/4 +f 81/107/4 83/106/4 87/111/4 85/115/4 +f 84/109/4 82/112/4 86/116/4 88/110/4 +f 92/113/5 90/117/5 89/118/5 91/114/5 +f 86/116/4 85/115/4 89/118/4 90/117/4 +f 85/115/4 87/111/4 91/114/4 89/118/4 +f 88/110/4 86/116/4 90/117/4 92/113/4 diff --git a/mods/furniture/models/furniture_bench.obj b/mods/furniture/models/furniture_bench.obj new file mode 100644 index 0000000..9ca9db7 --- /dev/null +++ b/mods/furniture/models/furniture_bench.obj @@ -0,0 +1,128 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Bench_short_Cube.003 +v -1.375000 -0.125000 0.375000 +v -1.375000 0.000000 0.375000 +v -1.375000 -0.125000 -0.375000 +v -1.375000 0.000000 -0.375000 +v 0.375000 -0.125000 0.375000 +v 0.375000 0.000000 0.375000 +v 0.375000 -0.125000 -0.375000 +v 0.375000 0.000000 -0.375000 +v -1.312500 -0.125000 0.312500 +v -1.312500 -0.125000 0.187500 +v -1.187500 -0.125000 0.312500 +v -1.187500 -0.125000 0.187500 +v -1.312500 -0.500000 0.187500 +v -1.312500 -0.500000 0.312500 +v -1.187500 -0.500000 0.187500 +v -1.187500 -0.500000 0.312500 +v -1.312500 -0.125000 -0.312500 +v -1.187500 -0.125000 -0.312500 +v -1.312500 -0.125000 -0.187500 +v -1.187500 -0.125000 -0.187500 +v -1.187500 -0.500000 -0.312500 +v -1.312500 -0.500000 -0.312500 +v -1.187500 -0.500000 -0.187500 +v -1.312500 -0.500000 -0.187500 +v 0.312500 -0.125000 -0.312500 +v 0.312500 -0.125000 -0.187500 +v 0.187500 -0.125000 -0.312500 +v 0.187500 -0.125000 -0.187500 +v 0.312500 -0.500000 -0.187500 +v 0.312500 -0.500000 -0.312500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.500000 -0.312500 +v 0.312500 -0.125000 0.312500 +v 0.187500 -0.125000 0.312500 +v 0.312500 -0.125000 0.187500 +v 0.187500 -0.125000 0.187500 +v 0.187500 -0.500000 0.312500 +v 0.312500 -0.500000 0.312500 +v 0.187500 -0.500000 0.187500 +v 0.312500 -0.500000 0.187500 +vt 1.000000 0.937500 +vt 0.937500 0.937500 +vt 0.937500 0.562500 +vt 1.000000 0.562500 +vt 0.937500 0.500000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.000000 0.562500 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.937500 1.000000 +vt 0.937500 0.562500 +vt 0.062500 0.562500 +vt 0.062500 0.937500 +vt 0.937500 0.937500 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.187500 +vt 0.000000 0.187500 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.250000 0.187500 +vt 0.250000 0.000000 +vt 0.500000 0.187500 +vt 0.437500 0.187500 +vt 0.437500 0.000000 +vt 0.500000 0.000000 +vt 0.375000 0.187500 +vt 0.312500 0.187500 +vt 0.312500 0.000000 +vt 0.375000 0.000000 +vt 0.562500 0.187500 +vt 0.562500 0.000000 +vt 0.187500 0.406250 +vt 0.125000 0.406250 +vt 0.125000 0.218750 +vt 0.187500 0.218750 +vt 0.062500 0.406250 +vt 0.000000 0.406250 +vt 0.000000 0.218750 +vt 0.062500 0.218750 +vt 0.250000 0.406250 +vt 0.250000 0.218750 +vt 0.500000 0.406250 +vt 0.437500 0.406250 +vt 0.437500 0.218750 +vt 0.500000 0.218750 +vt 0.375000 0.406250 +vt 0.312500 0.406250 +vt 0.312500 0.218750 +vt 0.375000 0.218750 +vt 0.562500 0.406250 +vt 0.562500 0.218750 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 11/17/4 9/18/4 14/19/4 16/20/4 +f 10/21/2 12/22/2 15/23/2 13/24/2 +f 12/25/3 11/17/3 16/20/3 15/26/3 +f 9/18/1 10/21/1 13/24/1 14/19/1 +f 19/27/1 17/28/1 22/29/1 24/30/1 +f 18/31/3 20/32/3 23/33/3 21/34/3 +f 20/35/4 19/27/4 24/30/4 23/36/4 +f 17/28/2 18/31/2 21/34/2 22/29/2 +f 27/37/2 25/38/2 30/39/2 32/40/2 +f 26/41/4 28/42/4 31/43/4 29/44/4 +f 28/45/1 27/37/1 32/40/1 31/46/1 +f 25/38/3 26/41/3 29/44/3 30/39/3 +f 35/47/3 33/48/3 38/49/3 40/50/3 +f 34/51/1 36/52/1 39/53/1 37/54/1 +f 36/55/2 35/47/2 40/50/2 39/56/2 +f 33/48/4 34/51/4 37/54/4 38/49/4 diff --git a/mods/furniture/models/furniture_bench_picnic.obj b/mods/furniture/models/furniture_bench_picnic.obj new file mode 100644 index 0000000..f0bee6b --- /dev/null +++ b/mods/furniture/models/furniture_bench_picnic.obj @@ -0,0 +1,352 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Bench_picnic_Cube.013 +v -1.375000 -0.125000 1.375000 +v -1.375000 0.000000 1.375000 +v -1.375000 -0.125000 1.000000 +v -1.375000 0.000000 1.000000 +v 0.375000 -0.125000 1.375000 +v 0.375000 0.000000 1.375000 +v 0.375000 -0.125000 1.000000 +v 0.375000 0.000000 1.000000 +v -1.312500 -0.125000 1.250000 +v -1.312500 -0.125000 1.125000 +v -1.187500 -0.125000 1.250000 +v -1.187500 -0.125000 1.125000 +v -1.312500 -0.500000 1.125000 +v -1.312500 -0.500000 1.250000 +v -1.187500 -0.500000 1.125000 +v -1.187500 -0.500000 1.250000 +v 0.375000 0.500000 -0.062500 +v 0.375000 0.375000 -0.062500 +v 0.375000 0.500000 1.062500 +v 0.375000 0.375000 1.062500 +v -1.375000 0.500000 -0.062500 +v -1.375000 0.375000 -0.062500 +v -1.375000 0.500000 1.062500 +v -1.375000 0.375000 1.062500 +v 0.312500 -0.125000 1.250000 +v 0.187500 -0.125000 1.250000 +v 0.312500 -0.125000 1.125000 +v 0.187500 -0.125000 1.125000 +v 0.187500 -0.500000 1.250000 +v 0.312500 -0.500000 1.250000 +v 0.187500 -0.500000 1.125000 +v 0.312500 -0.500000 1.125000 +v -1.375000 -0.125000 0.000000 +v -1.375000 0.000000 0.000000 +v -1.375000 -0.125000 -0.375000 +v -1.375000 0.000000 -0.375000 +v 0.375000 -0.125000 0.000000 +v 0.375000 0.000000 0.000000 +v 0.375000 -0.125000 -0.375000 +v 0.375000 0.000000 -0.375000 +v -1.312500 -0.125000 -0.125000 +v -1.312500 -0.125000 -0.250000 +v -1.187500 -0.125000 -0.125000 +v -1.187500 -0.125000 -0.250000 +v -1.312500 -0.500000 -0.250000 +v -1.312500 -0.500000 -0.125000 +v -1.187500 -0.500000 -0.250000 +v -1.187500 -0.500000 -0.125000 +v 0.312500 -0.125000 -0.125000 +v 0.187500 -0.125000 -0.125000 +v 0.312500 -0.125000 -0.250000 +v 0.187500 -0.125000 -0.250000 +v 0.187500 -0.500000 -0.125000 +v 0.312500 -0.500000 -0.125000 +v 0.187500 -0.500000 -0.250000 +v 0.312500 -0.500000 -0.250000 +v 0.187500 -0.187500 1.312500 +v 0.125000 -0.187500 1.312500 +v 0.187500 -0.375000 1.312500 +v 0.125000 -0.375000 1.312500 +v 0.187500 -0.187500 -0.312500 +v 0.125000 -0.187500 -0.312500 +v 0.187500 -0.375000 -0.312500 +v 0.125000 -0.375000 -0.312500 +v -1.125000 -0.187500 1.312500 +v -1.187500 -0.187500 1.312500 +v -1.125000 -0.375000 1.312500 +v -1.187500 -0.375000 1.312500 +v -1.125000 -0.187500 -0.312500 +v -1.187500 -0.187500 -0.312500 +v -1.125000 -0.375000 -0.312500 +v -1.187500 -0.375000 -0.312500 +v 0.187500 0.375000 1.000000 +v 0.125000 0.375000 1.000000 +v 0.187500 0.250000 1.000000 +v 0.125000 0.250000 1.000000 +v 0.187500 0.375000 0.000000 +v 0.125000 0.375000 0.000000 +v 0.187500 0.250000 0.000000 +v 0.125000 0.250000 0.000000 +v -1.125000 0.375000 1.000000 +v -1.187500 0.375000 1.000000 +v -1.125000 0.250000 1.000000 +v -1.187500 0.250000 1.000000 +v -1.125000 0.375000 0.000000 +v -1.187500 0.375000 0.000000 +v -1.125000 0.250000 0.000000 +v -1.187500 0.250000 0.000000 +v -1.125000 0.375000 0.562500 +v -1.125000 0.375000 0.437500 +v -1.000000 0.375000 0.562500 +v -1.000000 0.375000 0.437500 +v -1.125000 -0.500000 0.437500 +v -1.125000 -0.500000 0.562500 +v -1.000000 -0.500000 0.437500 +v -1.000000 -0.500000 0.562500 +v 0.000000 0.375000 0.562500 +v 0.000000 0.375000 0.437500 +v 0.125000 0.375000 0.562500 +v 0.125000 0.375000 0.437500 +v 0.000000 -0.500000 0.437500 +v 0.000000 -0.500000 0.562500 +v 0.125000 -0.500000 0.437500 +v 0.125000 -0.500000 0.562500 +vt 1.000000 0.937500 +vt 0.937500 0.937500 +vt 0.937500 0.750000 +vt 1.000000 0.750000 +vt 0.937500 0.687500 +vt 0.062500 0.750000 +vt 0.062500 0.687500 +vt 0.000000 0.750000 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.937500 1.000000 +vt 0.937500 0.750000 +vt 0.062500 0.750000 +vt 0.062500 0.937500 +vt 0.937500 0.937500 +vt 0.187500 0.062500 +vt 0.187500 0.125000 +vt 0.000000 0.125000 +vt 0.000000 0.062500 +vt 0.187500 0.187500 +vt 0.187500 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.187500 +vt 0.187500 0.000000 +vt 0.000000 0.000000 +vt 0.062500 0.750000 +vt 0.937500 0.750000 +vt 0.937500 0.937500 +vt 0.062500 0.937500 +vt 0.937500 0.750000 +vt 0.062500 0.750000 +vt 0.062500 0.937500 +vt 0.937500 0.937500 +vt 0.062500 1.000000 +vt 0.937500 1.000000 +vt 0.000000 0.750000 +vt 0.000000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 0.750000 +vt 0.531250 0.250000 +vt 0.531250 0.312500 +vt 0.343750 0.312500 +vt 0.343750 0.250000 +vt 0.531250 0.375000 +vt 0.531250 0.437500 +vt 0.343750 0.437500 +vt 0.343750 0.375000 +vt 0.531250 0.187500 +vt 0.343750 0.187500 +vt 0.062500 0.687500 +vt 0.937500 0.687500 +vt 1.000000 0.937500 +vt 0.937500 0.937500 +vt 0.937500 0.750000 +vt 1.000000 0.750000 +vt 0.937500 0.687500 +vt 0.062500 0.750000 +vt 0.062500 0.687500 +vt 0.000000 0.750000 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.937500 1.000000 +vt 0.937500 0.750000 +vt 0.062500 0.750000 +vt 0.062500 0.937500 +vt 0.937500 0.937500 +vt 0.187500 0.062500 +vt 0.187500 0.125000 +vt 0.000000 0.125000 +vt 0.000000 0.062500 +vt 0.187500 0.187500 +vt 0.187500 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.187500 +vt 0.187500 0.000000 +vt 0.000000 0.000000 +vt 0.531250 0.250000 +vt 0.531250 0.312500 +vt 0.343750 0.312500 +vt 0.343750 0.250000 +vt 0.531250 0.375000 +vt 0.531250 0.437500 +vt 0.343750 0.437500 +vt 0.343750 0.375000 +vt 0.531250 0.187500 +vt 0.343750 0.187500 +vt 0.890625 0.218750 +vt 0.859375 0.218750 +vt 0.859375 0.125000 +vt 0.890625 0.125000 +vt 0.859375 0.093750 +vt 0.046875 0.125000 +vt 0.046875 0.093750 +vt 0.015625 0.125000 +vt 0.046875 0.218750 +vt 0.015625 0.218750 +vt 0.046875 0.250000 +vt 0.859375 0.250000 +vt 0.859375 0.125000 +vt 0.046875 0.125000 +vt 0.046875 0.218750 +vt 0.859375 0.218750 +vt 0.953125 0.328125 +vt 0.921875 0.328125 +vt 0.921875 0.234375 +vt 0.953125 0.234375 +vt 0.921875 0.203125 +vt 0.109375 0.234375 +vt 0.109375 0.203125 +vt 0.078125 0.234375 +vt 0.109375 0.328125 +vt 0.078125 0.328125 +vt 0.109375 0.359375 +vt 0.921875 0.359375 +vt 0.921875 0.234375 +vt 0.109375 0.234375 +vt 0.109375 0.328125 +vt 0.921875 0.328125 +vt 0.734375 0.187500 +vt 0.703125 0.187500 +vt 0.703125 0.125000 +vt 0.734375 0.125000 +vt 0.703125 0.093750 +vt 0.046875 0.125000 +vt 0.046875 0.093750 +vt 0.015625 0.125000 +vt 0.046875 0.187500 +vt 0.015625 0.187500 +vt 0.046875 0.218750 +vt 0.703125 0.218750 +vt 0.703125 0.125000 +vt 0.046875 0.125000 +vt 0.046875 0.187500 +vt 0.703125 0.187500 +vt 0.734375 0.187500 +vt 0.703125 0.187500 +vt 0.703125 0.125000 +vt 0.734375 0.125000 +vt 0.703125 0.093750 +vt 0.046875 0.125000 +vt 0.046875 0.093750 +vt 0.015625 0.125000 +vt 0.046875 0.187500 +vt 0.015625 0.187500 +vt 0.046875 0.218750 +vt 0.703125 0.218750 +vt 0.703125 0.125000 +vt 0.046875 0.125000 +vt 0.046875 0.187500 +vt 0.703125 0.187500 +vt 0.437500 0.062500 +vt 0.437500 0.125000 +vt 0.000000 0.125000 +vt 0.000000 0.062500 +vt 0.437500 0.187500 +vt 0.437500 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.187500 +vt 0.437500 0.000000 +vt 0.000000 0.000000 +vt 0.437500 0.062500 +vt 0.437500 0.125000 +vt 0.000000 0.125000 +vt 0.000000 0.062500 +vt 0.437500 0.187500 +vt 0.437500 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.187500 +vt 0.437500 0.000000 +vt 0.000000 0.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 11/17/4 9/18/4 14/19/4 16/20/4 +f 10/21/2 12/22/2 15/23/2 13/24/2 +f 12/25/3 11/17/3 16/20/3 15/26/3 +f 9/18/1 10/21/1 13/24/1 14/19/1 +f 17/27/6 21/28/6 23/29/6 19/30/6 +f 22/31/5 18/32/5 20/33/5 24/34/5 +f 20/35/4 19/30/4 23/29/4 24/36/4 +f 18/37/3 17/27/3 19/30/3 20/38/3 +f 24/39/1 23/29/1 21/28/1 22/40/1 +f 27/41/3 25/42/3 30/43/3 32/44/3 +f 26/45/1 28/46/1 31/47/1 29/48/1 +f 28/49/2 27/41/2 32/44/2 31/50/2 +f 25/42/4 26/45/4 29/48/4 30/43/4 +f 18/51/2 22/52/2 21/28/2 17/27/2 +f 33/53/1 34/54/1 36/55/1 35/56/1 +f 35/57/2 36/55/2 40/58/2 39/59/2 +f 39/60/3 40/58/3 38/61/3 37/62/3 +f 37/63/4 38/61/4 34/54/4 33/64/4 +f 35/65/5 39/66/5 37/67/5 33/68/5 +f 40/58/6 36/55/6 34/54/6 38/61/6 +f 43/69/4 41/70/4 46/71/4 48/72/4 +f 42/73/2 44/74/2 47/75/2 45/76/2 +f 44/77/3 43/69/3 48/72/3 47/78/3 +f 41/70/1 42/73/1 45/76/1 46/71/1 +f 51/79/3 49/80/3 54/81/3 56/82/3 +f 50/83/1 52/84/1 55/85/1 53/86/1 +f 52/87/2 51/79/2 56/82/2 55/88/2 +f 49/80/4 50/83/4 53/86/4 54/81/4 +f 57/89/4 58/90/4 60/91/4 59/92/4 +f 59/93/5 60/91/5 64/94/5 63/95/5 +f 63/96/2 64/94/2 62/97/2 61/98/2 +f 61/99/6 62/97/6 58/90/6 57/100/6 +f 59/101/3 63/102/3 61/103/3 57/104/3 +f 64/94/1 60/91/1 58/90/1 62/97/1 +f 65/105/4 66/106/4 68/107/4 67/108/4 +f 67/109/5 68/107/5 72/110/5 71/111/5 +f 71/112/2 72/110/2 70/113/2 69/114/2 +f 69/115/6 70/113/6 66/106/6 65/116/6 +f 67/117/3 71/118/3 69/119/3 65/120/3 +f 72/110/1 68/107/1 66/106/1 70/113/1 +f 73/121/4 74/122/4 76/123/4 75/124/4 +f 75/125/5 76/123/5 80/126/5 79/127/5 +f 79/128/2 80/126/2 78/129/2 77/130/2 +f 77/131/6 78/129/6 74/122/6 73/132/6 +f 75/133/3 79/134/3 77/135/3 73/136/3 +f 80/126/1 76/123/1 74/122/1 78/129/1 +f 81/137/4 82/138/4 84/139/4 83/140/4 +f 83/141/5 84/139/5 88/142/5 87/143/5 +f 87/144/2 88/142/2 86/145/2 85/146/2 +f 85/147/6 86/145/6 82/138/6 81/148/6 +f 83/149/3 87/150/3 85/151/3 81/152/3 +f 88/142/1 84/139/1 82/138/1 86/145/1 +f 91/153/4 89/154/4 94/155/4 96/156/4 +f 90/157/2 92/158/2 95/159/2 93/160/2 +f 92/161/3 91/153/3 96/156/3 95/162/3 +f 89/154/1 90/157/1 93/160/1 94/155/1 +f 99/163/4 97/164/4 102/165/4 104/166/4 +f 98/167/2 100/168/2 103/169/2 101/170/2 +f 100/171/3 99/163/3 104/166/3 103/172/3 +f 97/164/1 98/167/1 101/170/1 102/165/1 diff --git a/mods/furniture/models/furniture_bench_with_back.obj b/mods/furniture/models/furniture_bench_with_back.obj new file mode 100644 index 0000000..42c1957 --- /dev/null +++ b/mods/furniture/models/furniture_bench_with_back.obj @@ -0,0 +1,202 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Bench_with_back_Cube.009 +v -1.375000 -0.125000 0.437500 +v -1.375000 0.000000 0.437500 +v -1.375000 -0.125000 -0.375000 +v -1.375000 0.000000 -0.375000 +v 0.375000 -0.125000 0.437500 +v 0.375000 0.000000 0.437500 +v 0.375000 -0.125000 -0.375000 +v 0.375000 0.000000 -0.375000 +v -1.312500 -0.125000 0.375000 +v -1.312500 -0.125000 0.250000 +v -1.187500 -0.125000 0.375000 +v -1.187500 -0.125000 0.250000 +v -1.312500 -0.500000 0.250000 +v -1.312500 -0.500000 0.375000 +v -1.187500 -0.500000 0.250000 +v -1.187500 -0.500000 0.375000 +v -1.312500 -0.125000 -0.312500 +v -1.187500 -0.125000 -0.312500 +v -1.312500 -0.125000 -0.187500 +v -1.187500 -0.125000 -0.187500 +v -1.187500 -0.500000 -0.312500 +v -1.312500 -0.500000 -0.312500 +v -1.187500 -0.500000 -0.187500 +v -1.312500 -0.500000 -0.187500 +v 0.312500 -0.125000 -0.312500 +v 0.312500 -0.125000 -0.187500 +v 0.187500 -0.125000 -0.312500 +v 0.187500 -0.125000 -0.187500 +v 0.312500 -0.500000 -0.187500 +v 0.312500 -0.500000 -0.312500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.500000 -0.312500 +v 0.312500 -0.125000 0.375000 +v 0.187500 -0.125000 0.375000 +v 0.312500 -0.125000 0.250000 +v 0.187500 -0.125000 0.250000 +v 0.187500 -0.500000 0.375000 +v 0.312500 -0.500000 0.375000 +v 0.187500 -0.500000 0.250000 +v 0.312500 -0.500000 0.250000 +v -1.312500 0.500000 0.375000 +v -1.312500 0.500000 0.250000 +v -1.187500 0.500000 0.375000 +v -1.187500 0.500000 0.250000 +v -1.312500 0.000000 0.250000 +v -1.312500 0.000000 0.375000 +v -1.187500 0.000000 0.250000 +v -1.187500 0.000000 0.375000 +v 0.312500 0.500000 0.375000 +v 0.187500 0.500000 0.375000 +v 0.312500 0.500000 0.250000 +v 0.187500 0.500000 0.250000 +v 0.187500 0.000000 0.375000 +v 0.312500 0.000000 0.375000 +v 0.187500 0.000000 0.250000 +v 0.312500 0.000000 0.250000 +v 0.187500 0.468750 0.343750 +v 0.187500 0.468750 0.281250 +v 0.187500 0.156250 0.343750 +v 0.187500 0.156250 0.281250 +v -1.187500 0.468750 0.281250 +v -1.187500 0.468750 0.343750 +v -1.187500 0.156250 0.343750 +v -1.187500 0.156250 0.281250 +vt 1.000000 0.937500 +vt 0.937500 0.937500 +vt 0.937500 0.531250 +vt 1.000000 0.531250 +vt 0.937500 0.468750 +vt 0.062500 0.531250 +vt 0.062500 0.468750 +vt 0.000000 0.531250 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.937500 1.000000 +vt 0.937500 0.531250 +vt 0.062500 0.531250 +vt 0.062500 0.937500 +vt 0.937500 0.937500 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.187500 +vt 0.000000 0.187500 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.250000 0.187500 +vt 0.250000 0.000000 +vt 0.437500 0.187500 +vt 0.375000 0.187500 +vt 0.375000 0.000000 +vt 0.437500 0.000000 +vt 0.312500 0.187500 +vt 0.250000 0.187500 +vt 0.250000 0.000000 +vt 0.312500 0.000000 +vt 0.500000 0.187500 +vt 0.500000 0.000000 +vt 0.187500 0.406250 +vt 0.125000 0.406250 +vt 0.125000 0.218750 +vt 0.187500 0.218750 +vt 0.062500 0.406250 +vt 0.000000 0.406250 +vt 0.000000 0.218750 +vt 0.062500 0.218750 +vt 0.250000 0.406250 +vt 0.250000 0.218750 +vt 0.437500 0.406250 +vt 0.375000 0.406250 +vt 0.375000 0.218750 +vt 0.437500 0.218750 +vt 0.312500 0.406250 +vt 0.250000 0.406250 +vt 0.250000 0.218750 +vt 0.312500 0.218750 +vt 0.500000 0.406250 +vt 0.500000 0.218750 +vt 0.937500 0.250000 +vt 0.875000 0.250000 +vt 0.875000 0.000000 +vt 0.937500 0.000000 +vt 0.812500 0.250000 +vt 0.750000 0.250000 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 1.000000 0.250000 +vt 1.000000 0.000000 +vt 0.687500 0.250000 +vt 0.625000 0.250000 +vt 0.625000 0.000000 +vt 0.687500 0.000000 +vt 0.562500 0.250000 +vt 0.500000 0.250000 +vt 0.500000 0.000000 +vt 0.562500 0.000000 +vt 0.750000 0.250000 +vt 0.750000 0.000000 +vt 0.625000 0.312500 +vt 0.687500 0.312500 +vt 0.625000 0.250000 +vt 0.875000 0.312500 +vt 0.937500 0.312500 +vt 0.875000 0.250000 +vt 1.000000 0.843750 +vt 1.000000 1.000000 +vt 0.312500 1.000000 +vt 0.312500 0.843750 +vt 1.000000 0.812500 +vt 0.312500 0.812500 +vt 1.000000 0.578125 +vt 0.312500 0.578125 +vt 1.000000 0.546875 +vt 0.312500 0.546875 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 11/17/4 9/18/4 14/19/4 16/20/4 +f 10/21/2 12/22/2 15/23/2 13/24/2 +f 12/25/3 11/17/3 16/20/3 15/26/3 +f 9/18/1 10/21/1 13/24/1 14/19/1 +f 19/27/1 17/28/1 22/29/1 24/30/1 +f 18/31/3 20/32/3 23/33/3 21/34/3 +f 20/35/4 19/27/4 24/30/4 23/36/4 +f 17/28/2 18/31/2 21/34/2 22/29/2 +f 27/37/2 25/38/2 30/39/2 32/40/2 +f 26/41/4 28/42/4 31/43/4 29/44/4 +f 28/45/1 27/37/1 32/40/1 31/46/1 +f 25/38/3 26/41/3 29/44/3 30/39/3 +f 35/47/3 33/48/3 38/49/3 40/50/3 +f 34/51/1 36/52/1 39/53/1 37/54/1 +f 36/55/2 35/47/2 40/50/2 39/56/2 +f 33/48/4 34/51/4 37/54/4 38/49/4 +f 43/57/4 41/58/4 46/59/4 48/60/4 +f 42/61/2 44/62/2 47/63/2 45/64/2 +f 44/65/3 43/57/3 48/60/3 47/66/3 +f 41/58/1 42/61/1 45/64/1 46/59/1 +f 51/67/3 49/68/3 54/69/3 56/70/3 +f 50/71/1 52/72/1 55/73/1 53/74/1 +f 52/75/2 51/67/2 56/70/2 55/76/2 +f 49/68/4 50/71/4 53/74/4 54/69/4 +f 50/77/6 49/78/6 51/67/6 52/79/6 +f 42/80/6 41/81/6 43/57/6 44/82/6 +f 58/83/2 60/84/2 64/85/2 61/86/2 +f 57/87/6 58/83/6 61/86/6 62/88/6 +f 59/89/4 57/87/4 62/88/4 63/90/4 +f 60/91/5 59/89/5 63/90/5 64/92/5 diff --git a/mods/furniture/models/furniture_cabinet_counter.obj b/mods/furniture/models/furniture_cabinet_counter.obj new file mode 100644 index 0000000..1a33335 --- /dev/null +++ b/mods/furniture/models/furniture_cabinet_counter.obj @@ -0,0 +1,151 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Cabinet_counter_Cube.008 +v -0.500000 -0.375000 0.500000 +v -0.500000 0.375000 0.500000 +v -0.500000 -0.375000 -0.375000 +v -0.500000 0.375000 -0.375000 +v 0.500000 -0.375000 0.500000 +v 0.500000 0.375000 0.500000 +v 0.500000 -0.375000 -0.375000 +v 0.500000 0.375000 -0.375000 +v -0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.375000 +v 0.500000 0.500000 -0.375000 +v 0.500000 0.500000 0.500000 +v -0.500000 0.375000 -0.500000 +v 0.500000 0.375000 -0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v 0.031250 -0.312500 -0.375000 +v 0.031250 0.312500 -0.375000 +v 0.437500 -0.312500 -0.375000 +v 0.437500 0.312500 -0.375000 +v -0.500000 -0.375000 -0.250000 +v -0.500000 0.375000 -0.250000 +v 0.500000 -0.375000 -0.250000 +v 0.500000 0.375000 -0.250000 +v -0.500000 0.500000 -0.250000 +v 0.500000 0.500000 -0.250000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 -0.500000 -0.250000 +v 0.500000 -0.500000 -0.250000 +v 0.031250 0.312500 -0.437500 +v 0.031250 -0.312500 -0.437500 +v 0.437500 -0.312500 -0.437500 +v 0.437500 0.312500 -0.437500 +v -0.437500 -0.312500 -0.375000 +v -0.437500 0.312500 -0.375000 +v -0.031250 -0.312500 -0.375000 +v -0.031250 0.312500 -0.375000 +v -0.437500 0.312500 -0.437500 +v -0.437500 -0.312500 -0.437500 +v -0.031250 -0.312500 -0.437500 +v -0.031250 0.312500 -0.437500 +vt 0.875000 0.562500 +vt 0.875000 0.937500 +vt 0.937500 0.937500 +vt 0.937500 0.562500 +vt 1.000000 0.125000 +vt 1.000000 0.500000 +vt 0.500000 0.500000 +vt 0.500000 0.125000 +vt 0.875000 0.562500 +vt 0.875000 0.937500 +vt 0.546875 0.937500 +vt 0.546875 0.562500 +vt 0.000000 0.375000 +vt 0.500000 0.375000 +vt 0.500000 0.437500 +vt 0.000000 0.437500 +vt 0.000000 0.625000 +vt 0.500000 0.625000 +vt 0.500000 1.000000 +vt 0.000000 1.000000 +vt 0.937500 0.937500 +vt 0.937500 1.000000 +vt 0.875000 1.000000 +vt 0.546875 0.937500 +vt 0.546875 1.000000 +vt 0.875000 1.000000 +vt 0.500000 0.500000 +vt 0.000000 0.500000 +vt 0.937500 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.937500 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.500000 0.562500 +vt 0.000000 0.562500 +vt 0.546875 1.000000 +vt 0.937500 0.562500 +vt 0.546875 0.562500 +vt 0.500000 0.062500 +vt 1.000000 0.062500 +vt 0.546875 0.500000 +vt 0.875000 0.500000 +vt 0.875000 0.500000 +vt 0.546875 0.500000 +vt 0.500000 0.000000 +vt 1.000000 0.000000 +vt 0.031250 0.031250 +vt 0.343750 0.031250 +vt 0.343750 0.234375 +vt 0.031250 0.234375 +vt 0.000000 0.234375 +vt 0.000000 0.031250 +vt 0.375000 0.031250 +vt 0.375000 0.234375 +vt 0.031250 0.000000 +vt 0.343750 0.000000 +vt 0.343750 0.265625 +vt 0.031250 0.265625 +vt 0.156250 0.140625 +vt 0.468750 0.140625 +vt 0.468750 0.343750 +vt 0.156250 0.343750 +vt 0.125000 0.343750 +vt 0.125000 0.140625 +vt 0.500000 0.140625 +vt 0.500000 0.343750 +vt 0.156250 0.109375 +vt 0.468750 0.109375 +vt 0.468750 0.375000 +vt 0.156250 0.375000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 21/1/1 22/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 23/9/3 24/10/3 6/11/3 5/12/3 +f 8/13/4 4/14/4 13/15/4 14/16/4 +f 26/17/5 25/18/5 9/19/5 12/20/5 +f 24/10/3 8/21/3 11/22/3 26/23/3 +f 22/2/1 2/24/1 9/25/1 25/26/1 +f 14/16/2 13/15/2 15/27/2 16/28/2 +f 4/3/1 10/29/1 15/30/1 13/31/1 +f 11/22/3 8/21/3 14/32/3 16/33/3 +f 10/34/5 11/35/5 16/28/5 15/27/5 +f 4/3/1 22/2/1 25/26/1 10/29/1 +f 6/11/3 24/10/3 26/23/3 12/36/3 +f 11/35/5 10/34/5 25/18/5 26/17/5 +f 7/37/3 8/21/3 24/10/3 23/9/3 +f 1/38/1 2/24/1 22/2/1 21/1/1 +f 3/5/4 7/8/4 23/39/4 21/40/4 +f 23/9/3 5/12/3 28/41/3 30/42/3 +f 1/38/1 21/1/1 29/43/1 27/44/1 +f 21/40/2 23/39/2 30/45/2 29/46/2 +f 32/47/2 31/48/2 34/49/2 33/50/2 +f 19/51/4 17/52/4 32/47/4 33/50/4 +f 18/53/5 20/54/5 34/49/5 31/48/5 +f 17/55/1 18/56/1 31/48/1 32/47/1 +f 20/57/3 19/58/3 33/50/3 34/49/3 +f 40/59/2 39/60/2 42/61/2 41/62/2 +f 37/63/4 35/64/4 40/59/4 41/62/4 +f 36/65/5 38/66/5 42/61/5 39/60/5 +f 35/67/1 36/68/1 39/60/1 40/59/1 +f 38/69/3 37/70/3 41/62/3 42/61/3 diff --git a/mods/furniture/models/furniture_cabinet_wall.obj b/mods/furniture/models/furniture_cabinet_wall.obj new file mode 100644 index 0000000..38583b7 --- /dev/null +++ b/mods/furniture/models/furniture_cabinet_wall.obj @@ -0,0 +1,90 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Cabinet_wall_Cube.007 +v -0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 -0.500000 -0.250000 +v -0.500000 0.500000 -0.250000 +v 0.500000 -0.500000 0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 -0.500000 -0.250000 +v 0.500000 0.500000 -0.250000 +v -0.437500 -0.437500 -0.312500 +v -0.437500 0.437500 -0.312500 +v -0.031250 -0.437500 -0.312500 +v -0.031250 0.437500 -0.312500 +v -0.437500 -0.437500 -0.250000 +v -0.437500 0.437500 -0.250000 +v -0.031250 -0.437500 -0.250000 +v -0.031250 0.437500 -0.250000 +v 0.031250 -0.437500 -0.312500 +v 0.031250 0.437500 -0.312500 +v 0.437500 -0.437500 -0.312500 +v 0.437500 0.437500 -0.312500 +v 0.031250 -0.437500 -0.250000 +v 0.031250 0.437500 -0.250000 +v 0.437500 -0.437500 -0.250000 +v 0.437500 0.437500 -0.250000 +vt 0.625000 0.500000 +vt 0.625000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.500000 +vt 0.500000 0.000000 +vt 0.500000 0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vt 0.625000 0.500000 +vt 0.625000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.500000 +vt 0.625000 1.000000 +vt 1.000000 1.000000 +vt 0.625000 1.000000 +vt 0.625000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.031250 0.734375 +vt 0.468750 0.734375 +vt 0.468750 0.531250 +vt 0.031250 0.531250 +vt 0.500000 0.734375 +vt 0.500000 0.531250 +vt 0.031250 0.765625 +vt 0.468750 0.765625 +vt 0.468750 0.500000 +vt 0.031250 0.500000 +vt 0.000000 0.531250 +vt 0.000000 0.734375 +vt 0.031250 0.968750 +vt 0.468750 0.968750 +vt 0.468750 0.765625 +vt 0.031250 0.765625 +vt 0.500000 0.968750 +vt 0.500000 0.765625 +vt 0.031250 1.000000 +vt 0.468750 1.000000 +vt 0.468750 0.734375 +vt 0.031250 0.734375 +vt 0.000000 0.765625 +vt 0.000000 0.968750 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 7/9/3 8/10/3 6/11/3 5/12/3 +f 3/13/4 7/9/4 5/12/4 1/14/4 +f 8/15/5 4/16/5 2/17/5 6/18/5 +f 9/19/2 10/20/2 12/21/2 11/22/2 +f 10/20/5 14/23/5 16/24/5 12/21/5 +f 9/19/1 13/25/1 14/26/1 10/20/1 +f 12/21/3 16/27/3 15/28/3 11/22/3 +f 11/22/4 15/29/4 13/30/4 9/19/4 +f 17/31/2 18/32/2 20/33/2 19/34/2 +f 18/32/5 22/35/5 24/36/5 20/33/5 +f 17/31/1 21/37/1 22/38/1 18/32/1 +f 20/33/3 24/39/3 23/40/3 19/34/3 +f 19/34/4 23/41/4 21/42/4 17/31/4 diff --git a/mods/furniture/models/furniture_chair.obj b/mods/furniture/models/furniture_chair.obj new file mode 100644 index 0000000..59de90c --- /dev/null +++ b/mods/furniture/models/furniture_chair.obj @@ -0,0 +1,156 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Chair_Cube.004 +v 0.375000 -0.125000 -0.375000 +v 0.375000 0.000000 -0.375000 +v 0.375000 -0.125000 0.375000 +v 0.375000 0.000000 0.375000 +v -0.375000 -0.125000 -0.375000 +v -0.375000 0.000000 -0.375000 +v -0.375000 -0.125000 0.375000 +v -0.375000 0.000000 0.375000 +v 0.312500 -0.125000 -0.312500 +v 0.312500 -0.125000 -0.187500 +v 0.187500 -0.125000 -0.312500 +v 0.187500 -0.125000 -0.187500 +v 0.312500 -0.500000 -0.187500 +v 0.312500 -0.500000 -0.312500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.500000 -0.312500 +v -0.312500 -0.125000 -0.312500 +v -0.187500 -0.125000 -0.312500 +v -0.312500 -0.125000 -0.187500 +v -0.187500 -0.125000 -0.187500 +v -0.187500 -0.500000 -0.312500 +v -0.312500 -0.500000 -0.312500 +v -0.187500 -0.500000 -0.187500 +v -0.312500 -0.500000 -0.187500 +v 0.312500 0.500000 0.312500 +v 0.187500 0.500000 0.312500 +v 0.312500 0.500000 0.187500 +v 0.187500 0.500000 0.187500 +v 0.187500 -0.500000 0.312500 +v 0.312500 -0.500000 0.312500 +v 0.187500 -0.500000 0.187500 +v 0.312500 -0.500000 0.187500 +v -0.312500 0.500000 0.312500 +v -0.312500 0.500000 0.187500 +v -0.187500 0.500000 0.312500 +v -0.187500 0.500000 0.187500 +v -0.312500 -0.500000 0.187500 +v -0.312500 -0.500000 0.312500 +v -0.187500 -0.500000 0.187500 +v -0.187500 -0.500000 0.312500 +v 0.187500 0.343750 0.218750 +v 0.187500 0.468750 0.218750 +v 0.187500 0.343750 0.281250 +v 0.187500 0.468750 0.281250 +v -0.187500 0.343750 0.218750 +v -0.187500 0.468750 0.218750 +v -0.187500 0.343750 0.281250 +v -0.187500 0.468750 0.281250 +vt 0.500000 0.937500 +vt 0.437500 0.937500 +vt 0.437500 0.562500 +vt 0.500000 0.562500 +vt 0.437500 0.500000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.000000 0.562500 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.437500 1.000000 +vt 0.437500 0.562500 +vt 0.062500 0.562500 +vt 0.062500 0.937500 +vt 0.437500 0.937500 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.187500 +vt 0.000000 0.187500 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.250000 0.187500 +vt 0.250000 0.000000 +vt 0.187500 0.390625 +vt 0.125000 0.390625 +vt 0.125000 0.203125 +vt 0.187500 0.203125 +vt 0.062500 0.390625 +vt 0.000000 0.390625 +vt 0.000000 0.203125 +vt 0.062500 0.203125 +vt 0.250000 0.390625 +vt 0.250000 0.203125 +vt 0.656250 0.500000 +vt 0.593750 0.500000 +vt 0.593750 0.000000 +vt 0.656250 0.000000 +vt 0.531250 0.500000 +vt 0.468750 0.500000 +vt 0.468750 0.000000 +vt 0.531250 0.000000 +vt 0.718750 0.500000 +vt 0.718750 0.000000 +vt 0.937500 0.500000 +vt 0.875000 0.500000 +vt 0.875000 0.000000 +vt 0.937500 0.000000 +vt 0.812500 0.500000 +vt 0.750000 0.500000 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 1.000000 0.500000 +vt 1.000000 0.000000 +vt 0.812500 0.562500 +vt 0.750000 0.562500 +vt 0.718750 0.562500 +vt 0.656250 0.562500 +vt 0.265625 0.000000 +vt 0.328125 0.000000 +vt 0.328125 0.187500 +vt 0.265625 0.187500 +vt 0.421875 0.187500 +vt 0.359375 0.187500 +vt 0.359375 0.000000 +vt 0.421875 0.000000 +vt 0.453125 0.000000 +vt 0.453125 0.187500 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 11/17/4 9/18/4 14/19/4 16/20/4 +f 10/21/2 12/22/2 15/23/2 13/24/2 +f 12/25/3 11/17/3 16/20/3 15/26/3 +f 9/18/1 10/21/1 13/24/1 14/19/1 +f 19/27/3 17/28/3 22/29/3 24/30/3 +f 18/31/1 20/32/1 23/33/1 21/34/1 +f 20/35/2 19/27/2 24/30/2 23/36/2 +f 17/28/4 18/31/4 21/34/4 22/29/4 +f 27/37/1 25/38/1 30/39/1 32/40/1 +f 26/41/3 28/42/3 31/43/3 29/44/3 +f 28/45/4 27/37/4 32/40/4 31/46/4 +f 25/38/2 26/41/2 29/44/2 30/39/2 +f 35/47/2 33/48/2 38/49/2 40/50/2 +f 34/51/4 36/52/4 39/53/4 37/54/4 +f 36/55/1 35/47/1 40/50/1 39/56/1 +f 33/48/3 34/51/3 37/54/3 38/49/3 +f 34/51/6 33/57/6 35/58/6 36/52/6 +f 26/59/6 25/60/6 27/37/6 28/45/6 +f 43/61/2 44/62/2 48/63/2 47/64/2 +f 45/65/4 46/66/4 42/67/4 41/68/4 +f 43/69/5 47/70/5 45/65/5 41/68/5 +f 48/63/6 44/62/6 42/67/6 46/66/6 diff --git a/mods/furniture/models/furniture_chair_cushion.obj b/mods/furniture/models/furniture_chair_cushion.obj new file mode 100644 index 0000000..5ac08cf --- /dev/null +++ b/mods/furniture/models/furniture_chair_cushion.obj @@ -0,0 +1,206 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Chair_Cube.004 +v 0.375000 -0.125000 -0.375000 +v 0.375000 0.000000 -0.375000 +v 0.375000 -0.125000 0.375000 +v 0.375000 0.000000 0.375000 +v -0.375000 -0.125000 -0.375000 +v -0.375000 0.000000 -0.375000 +v -0.375000 -0.125000 0.375000 +v -0.375000 0.000000 0.375000 +v 0.312500 -0.125000 -0.312500 +v 0.312500 -0.125000 -0.187500 +v 0.187500 -0.125000 -0.312500 +v 0.187500 -0.125000 -0.187500 +v 0.312500 -0.500000 -0.187500 +v 0.312500 -0.500000 -0.312500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.500000 -0.312500 +v -0.312500 -0.125000 -0.312500 +v -0.187500 -0.125000 -0.312500 +v -0.312500 -0.125000 -0.187500 +v -0.187500 -0.125000 -0.187500 +v -0.187500 -0.500000 -0.312500 +v -0.312500 -0.500000 -0.312500 +v -0.187500 -0.500000 -0.187500 +v -0.312500 -0.500000 -0.187500 +v 0.312500 0.500000 0.312500 +v 0.187500 0.500000 0.312500 +v 0.312500 0.500000 0.187500 +v 0.187500 0.500000 0.187500 +v 0.187500 -0.500000 0.312500 +v 0.312500 -0.500000 0.312500 +v 0.187500 -0.500000 0.187500 +v 0.312500 -0.500000 0.187500 +v -0.312500 0.500000 0.312500 +v -0.312500 0.500000 0.187500 +v -0.187500 0.500000 0.312500 +v -0.187500 0.500000 0.187500 +v -0.312500 -0.500000 0.187500 +v -0.312500 -0.500000 0.312500 +v -0.187500 -0.500000 0.187500 +v -0.187500 -0.500000 0.312500 +v 0.187500 0.343750 0.218750 +v 0.187500 0.468750 0.218750 +v 0.187500 0.343750 0.281250 +v 0.187500 0.468750 0.281250 +v -0.187500 0.343750 0.218750 +v -0.187500 0.468750 0.218750 +v -0.187500 0.343750 0.281250 +v -0.187500 0.468750 0.281250 +v -0.312500 0.000000 -0.312500 +v -0.312500 0.031250 -0.312500 +v 0.312500 0.000000 -0.312500 +v 0.312500 0.031250 -0.312500 +v -0.312500 0.000000 0.187500 +v -0.312500 0.031250 0.187500 +v 0.312500 0.000000 0.187500 +v 0.312500 0.031250 0.187500 +v -0.187500 0.000000 -0.312500 +v -0.187500 0.031250 -0.312500 +v -0.187500 0.000000 0.312500 +v -0.187500 0.031250 0.312500 +v -0.187500 0.031250 0.187500 +v 0.187500 0.031250 -0.312500 +v 0.187500 0.000000 0.312500 +v 0.187500 0.031250 0.187500 +v 0.187500 0.000000 -0.312500 +v 0.187500 0.031250 0.312500 +vt 0.500000 0.937500 +vt 0.437500 0.937500 +vt 0.437500 0.562500 +vt 0.500000 0.562500 +vt 0.437500 0.500000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.000000 0.562500 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.437500 1.000000 +vt 0.437500 0.562500 +vt 0.062500 0.562500 +vt 0.062500 0.937500 +vt 0.437500 0.937500 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.187500 +vt 0.000000 0.187500 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.250000 0.187500 +vt 0.250000 0.000000 +vt 0.187500 0.390625 +vt 0.125000 0.390625 +vt 0.125000 0.203125 +vt 0.187500 0.203125 +vt 0.062500 0.390625 +vt 0.000000 0.390625 +vt 0.000000 0.203125 +vt 0.062500 0.203125 +vt 0.250000 0.390625 +vt 0.250000 0.203125 +vt 0.656250 0.500000 +vt 0.593750 0.500000 +vt 0.593750 0.000000 +vt 0.656250 0.000000 +vt 0.531250 0.500000 +vt 0.468750 0.500000 +vt 0.468750 0.000000 +vt 0.531250 0.000000 +vt 0.718750 0.500000 +vt 0.718750 0.000000 +vt 0.937500 0.500000 +vt 0.875000 0.500000 +vt 0.875000 0.000000 +vt 0.937500 0.000000 +vt 0.812500 0.500000 +vt 0.750000 0.500000 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 1.000000 0.500000 +vt 1.000000 0.000000 +vt 0.812500 0.562500 +vt 0.750000 0.562500 +vt 0.718750 0.562500 +vt 0.656250 0.562500 +vt 0.265625 0.000000 +vt 0.328125 0.000000 +vt 0.328125 0.187500 +vt 0.265625 0.187500 +vt 0.421875 0.187500 +vt 0.359375 0.187500 +vt 0.359375 0.000000 +vt 0.421875 0.000000 +vt 0.453125 0.000000 +vt 0.453125 0.187500 +vt 1.000000 0.772727 +vt 0.954545 0.772727 +vt 0.954545 0.045455 +vt 1.000000 0.045455 +vt 0.227273 0.000000 +vt 0.227273 0.045455 +vt 0.045455 0.045455 +vt 0.045455 0.000000 +vt 0.772727 0.045455 +vt 0.772727 0.772727 +vt 0.000000 0.045455 +vt 0.045455 0.772727 +vt 0.000000 0.772727 +vt 0.227273 0.772727 +vt 0.772727 0.954545 +vt 0.227273 0.954545 +vt 0.227273 1.000000 +vt 0.772727 1.000000 +vt 0.954545 0.000000 +vt 0.772727 0.000000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +g Chair_Cube.004_Chair +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 11/17/4 9/18/4 14/19/4 16/20/4 +f 10/21/2 12/22/2 15/23/2 13/24/2 +f 12/25/3 11/17/3 16/20/3 15/26/3 +f 9/18/1 10/21/1 13/24/1 14/19/1 +f 19/27/3 17/28/3 22/29/3 24/30/3 +f 18/31/1 20/32/1 23/33/1 21/34/1 +f 20/35/2 19/27/2 24/30/2 23/36/2 +f 17/28/4 18/31/4 21/34/4 22/29/4 +f 27/37/1 25/38/1 30/39/1 32/40/1 +f 26/41/3 28/42/3 31/43/3 29/44/3 +f 28/45/4 27/37/4 32/40/4 31/46/4 +f 25/38/2 26/41/2 29/44/2 30/39/2 +f 35/47/2 33/48/2 38/49/2 40/50/2 +f 34/51/4 36/52/4 39/53/4 37/54/4 +f 36/55/1 35/47/1 40/50/1 39/56/1 +f 33/48/3 34/51/3 37/54/3 38/49/3 +f 34/51/6 33/57/6 35/58/6 36/52/6 +f 26/59/6 25/60/6 27/37/6 28/45/6 +f 43/61/2 44/62/2 48/63/2 47/64/2 +f 45/65/4 46/66/4 42/67/4 41/68/4 +f 43/69/5 47/70/5 45/65/5 41/68/5 +f 48/63/6 44/62/6 42/67/6 46/66/6 +g Chair_Cube.004_Cushion +f 53/71/3 54/72/3 50/73/3 49/74/3 +f 65/75/4 62/76/4 52/77/4 51/78/4 +f 58/79/6 50/73/6 54/72/6 61/80/6 +f 51/81/1 52/77/1 56/82/1 55/83/1 +f 62/76/6 58/79/6 61/80/6 64/84/6 +f 64/84/6 61/80/6 60/85/6 66/86/6 +f 63/87/2 66/86/2 60/85/2 59/88/2 +f 49/89/4 50/73/4 58/79/4 57/90/4 +f 52/77/6 62/76/6 64/84/6 56/82/6 +f 57/90/4 58/79/4 62/76/4 65/75/4 diff --git a/mods/furniture/models/furniture_chest.obj b/mods/furniture/models/furniture_chest.obj new file mode 100644 index 0000000..68bce83 --- /dev/null +++ b/mods/furniture/models/furniture_chest.obj @@ -0,0 +1,70 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Chest_Chest_small_Cube.001 +v -0.500000 -0.500000 -0.187500 +v -0.500000 0.375000 -0.187500 +v -0.500000 0.187500 -0.375000 +v -0.500000 -0.500000 -0.375000 +v 0.500000 0.187500 -0.375000 +v 0.500000 -0.500000 -0.375000 +v 0.500000 -0.500000 0.312500 +v 0.500000 0.375000 0.312500 +v 0.500000 0.187500 0.500000 +v 0.500000 -0.500000 0.500000 +v -0.500000 0.187500 0.500000 +v -0.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.187500 +v 0.500000 0.375000 -0.187500 +v -0.500000 0.375000 0.312500 +v -0.500000 -0.500000 0.312500 +vt 0.000000 0.656250 +vt 0.437500 0.656250 +vt 0.343750 0.562500 +vt 0.000000 0.562500 +vt 1.000000 0.500000 +vt 0.656250 0.500000 +vt 0.656250 1.000000 +vt 1.000000 1.000000 +vt 0.000000 0.906250 +vt 0.437500 0.906250 +vt 0.343750 1.000000 +vt 0.000000 1.000000 +vt 1.000000 0.500000 +vt 0.656250 0.500000 +vt 0.656250 0.000000 +vt 1.000000 0.000000 +vt 0.000000 0.656250 +vt 0.437500 0.656250 +vt 0.562500 0.500000 +vt 0.562500 0.000000 +vt 0.000000 0.562500 +vt 0.343750 0.562500 +vt 0.437500 0.906250 +vt 0.000000 0.906250 +vt 0.312500 0.500000 +vt 0.312500 0.000000 +vt 0.218750 0.000000 +vt 0.218750 0.500000 +vt 0.000000 1.000000 +vt 0.343750 1.000000 +vt 0.312500 0.500000 +vt 0.312500 0.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 0.7071 0.7071 +vn 0.0000 0.7071 -0.7071 +vn 0.0000 1.0000 0.0000 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 4/5/2 3/6/2 5/7/2 6/8/2 +f 7/9/3 8/10/3 9/11/3 10/12/3 +f 10/13/4 9/14/4 11/15/4 12/16/4 +f 7/9/3 13/17/3 14/18/3 8/10/3 +f 8/19/5 15/20/5 11/15/5 9/14/5 +f 6/21/3 5/22/3 14/18/3 13/17/3 +f 15/23/1 2/2/1 1/1/1 16/24/1 +f 5/25/6 3/26/6 2/27/6 14/28/6 +f 12/29/1 11/30/1 15/23/1 16/24/1 +f 8/19/7 14/31/7 2/32/7 15/20/7 diff --git a/mods/furniture/models/furniture_chest_large.obj b/mods/furniture/models/furniture_chest_large.obj new file mode 100644 index 0000000..7d7944d --- /dev/null +++ b/mods/furniture/models/furniture_chest_large.obj @@ -0,0 +1,70 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Chest_large_Chest_small_Cube.002 +v -1.500000 -0.500000 -0.250000 +v -1.500000 0.437500 -0.250000 +v -1.500000 0.250000 -0.437500 +v -1.500000 -0.500000 -0.437500 +v 0.500000 0.250000 -0.437500 +v 0.500000 -0.500000 -0.437500 +v 0.500000 -0.500000 0.312500 +v 0.500000 0.437500 0.312500 +v 0.500000 0.250000 0.500000 +v 0.500000 -0.500000 0.500000 +v -1.500000 0.250000 0.500000 +v -1.500000 -0.500000 0.500000 +v 0.500000 -0.500000 -0.250000 +v 0.500000 0.437500 -0.250000 +v -1.500000 0.437500 0.312500 +v -1.500000 -0.500000 0.312500 +vt 0.000000 0.445312 +vt 0.234375 0.445312 +vt 0.187500 0.492188 +vt 0.000000 0.492188 +vt 0.000000 1.000000 +vt 0.187500 1.000000 +vt 0.187500 0.500000 +vt 0.000000 0.500000 +vt 0.609375 0.445312 +vt 0.375000 0.445312 +vt 0.421875 0.492188 +vt 0.609375 0.492188 +vt 0.609375 0.500000 +vt 0.421875 0.500000 +vt 0.421875 1.000000 +vt 0.609375 1.000000 +vt 0.609375 0.304688 +vt 0.375000 0.304688 +vt 0.375000 0.500000 +vt 0.375000 1.000000 +vt 0.609375 0.257812 +vt 0.421875 0.257812 +vt 0.234375 0.304688 +vt 0.000000 0.304688 +vt 0.234375 0.500000 +vt 0.234375 1.000000 +vt 0.187500 1.000000 +vt 0.187500 0.500000 +vt 0.000000 0.257812 +vt 0.187500 0.257812 +vt 0.234375 0.500000 +vt 0.234375 1.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 0.7071 0.7071 +vn 0.0000 0.7071 -0.7071 +vn 0.0000 1.0000 0.0000 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 4/5/2 3/6/2 5/7/2 6/8/2 +f 7/9/3 8/10/3 9/11/3 10/12/3 +f 10/13/4 9/14/4 11/15/4 12/16/4 +f 7/9/3 13/17/3 14/18/3 8/10/3 +f 8/19/5 15/20/5 11/15/5 9/14/5 +f 6/21/3 5/22/3 14/18/3 13/17/3 +f 15/23/1 2/2/1 1/1/1 16/24/1 +f 5/25/6 3/26/6 2/27/6 14/28/6 +f 12/29/1 11/30/1 15/23/1 16/24/1 +f 8/19/7 14/31/7 2/32/7 15/20/7 diff --git a/mods/furniture/models/furniture_chest_small.obj b/mods/furniture/models/furniture_chest_small.obj new file mode 100644 index 0000000..be4e20e --- /dev/null +++ b/mods/furniture/models/furniture_chest_small.obj @@ -0,0 +1,66 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Chest_small_Cube.005 +v -0.437500 -0.500000 0.437500 +v -0.437500 0.062500 0.437500 +v -0.437500 -0.500000 -0.312500 +v -0.437500 0.062500 -0.312500 +v 0.437500 -0.500000 0.437500 +v 0.437500 0.062500 0.437500 +v 0.437500 -0.500000 -0.312500 +v 0.437500 0.062500 -0.312500 +v -0.437500 0.250000 -0.125000 +v 0.437500 -0.500000 -0.125000 +v -0.437500 -0.500000 -0.125000 +v 0.437500 0.250000 -0.125000 +v -0.437500 -0.500000 0.250000 +v 0.437500 0.250000 0.250000 +v -0.437500 0.250000 0.250000 +v 0.437500 -0.500000 0.250000 +vt 0.281250 0.625000 +vt 0.281250 1.000000 +vt 0.375000 0.906250 +vt 0.375000 0.625000 +vt 0.000000 0.000000 +vt 0.281250 0.000000 +vt 0.281250 0.437500 +vt 0.000000 0.437500 +vt 0.500000 0.625000 +vt 0.500000 1.000000 +vt 0.406250 0.906250 +vt 0.406250 0.625000 +vt 0.937500 0.437500 +vt 0.656250 0.437500 +vt 0.656250 0.000000 +vt 0.937500 0.000000 +vt 0.687500 0.625000 +vt 0.687500 1.000000 +vt 0.562500 0.437500 +vt 0.562500 0.000000 +vt 0.781250 0.625000 +vt 0.781250 0.906250 +vt 0.093750 1.000000 +vt 0.093750 0.625000 +vt 0.375000 0.000000 +vt 0.375000 0.437500 +vt 0.000000 0.625000 +vt 0.000000 0.906250 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.7071 0.7071 +vn 0.0000 0.7071 -0.7071 +vn 0.0000 1.0000 0.0000 +s off +f 11/1/1 9/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 16/9/3 14/10/3 6/11/3 5/12/3 +f 5/13/4 6/14/4 2/15/4 1/16/4 +f 16/9/3 10/17/3 12/18/3 14/10/3 +f 14/19/5 15/20/5 2/15/5 6/14/5 +f 7/21/3 8/22/3 12/18/3 10/17/3 +f 15/23/1 9/2/1 11/1/1 13/24/1 +f 8/7/6 4/6/6 9/25/6 12/26/6 +f 1/27/1 2/28/1 15/23/1 13/24/1 +f 14/19/7 12/26/7 9/25/7 15/20/7 diff --git a/mods/furniture/models/furniture_curtain_short.obj b/mods/furniture/models/furniture_curtain_short.obj new file mode 100644 index 0000000..f727ecd --- /dev/null +++ b/mods/furniture/models/furniture_curtain_short.obj @@ -0,0 +1,15 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Curtain_short_Plane +v -0.500000 -0.562500 0.468750 +v 0.500000 -0.562500 0.468750 +v -0.500000 0.500000 0.468750 +v 0.500000 0.500000 0.468750 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 0.0000 1.0000 +g Curtain_short_Plane_None +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 diff --git a/mods/furniture/models/furniture_curtain_tall.obj b/mods/furniture/models/furniture_curtain_tall.obj new file mode 100644 index 0000000..388d260 --- /dev/null +++ b/mods/furniture/models/furniture_curtain_tall.obj @@ -0,0 +1,15 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Curtain_short_Plane +v -0.500000 -1.562500 0.468750 +v 0.500000 -1.562500 0.468750 +v -0.500000 0.500000 0.468750 +v 0.500000 0.500000 0.468750 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 0.0000 1.0000 +g Curtain_short_Plane_None +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 diff --git a/mods/furniture/models/furniture_fence_1_a.obj b/mods/furniture/models/furniture_fence_1_a.obj new file mode 100644 index 0000000..52ef413 --- /dev/null +++ b/mods/furniture/models/furniture_fence_1_a.obj @@ -0,0 +1,304 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Fence_1_straight_Cube.022 +v 0.171875 0.406250 -0.000000 +v 0.109375 0.406250 -0.000000 +v 0.171875 0.406250 -0.062500 +v 0.109375 0.406250 -0.062500 +v 0.171875 -0.468750 -0.000000 +v 0.109375 -0.468750 -0.000000 +v 0.171875 -0.468750 -0.062500 +v 0.109375 -0.468750 -0.062500 +v -0.500000 -0.500000 0.062500 +v -0.500000 0.500000 0.062500 +v -0.500000 -0.500000 -0.062500 +v -0.500000 0.500000 -0.062500 +v -0.375000 -0.500000 0.062500 +v -0.375000 0.500000 0.062500 +v -0.375000 -0.500000 -0.062500 +v -0.375000 0.500000 -0.062500 +v 0.203125 -0.468750 -0.062500 +v 0.265625 -0.468750 -0.062500 +v 0.203125 -0.468750 -0.000000 +v 0.265625 -0.468750 -0.000000 +v 0.203125 0.406250 -0.062500 +v 0.265625 0.406250 -0.062500 +v 0.203125 0.406250 -0.000000 +v 0.265625 0.406250 -0.000000 +v -0.203125 0.406250 0.000000 +v -0.265625 0.406250 0.000000 +v -0.203125 0.406250 -0.062500 +v -0.265625 0.406250 -0.062500 +v -0.203125 -0.468750 0.000000 +v -0.265625 -0.468750 0.000000 +v -0.203125 -0.468750 -0.062500 +v -0.265625 -0.468750 -0.062500 +v 0.375000 0.500000 -0.062500 +v 0.375000 -0.500000 -0.062500 +v 0.500000 0.500000 -0.062500 +v 0.500000 -0.500000 -0.062500 +v 0.375000 0.500000 0.062500 +v 0.375000 -0.500000 0.062500 +v 0.500000 0.500000 0.062500 +v 0.500000 -0.500000 0.062500 +v -0.375000 0.312500 0.031250 +v -0.375000 0.250000 0.031250 +v -0.375000 0.312500 -0.031250 +v -0.375000 0.250000 -0.031250 +v 0.375000 0.312500 0.031250 +v 0.375000 0.250000 0.031250 +v 0.375000 0.312500 -0.031250 +v 0.375000 0.250000 -0.031250 +v -0.359375 -0.468750 -0.062500 +v -0.296875 -0.468750 -0.062500 +v -0.359375 -0.468750 0.000000 +v -0.296875 -0.468750 0.000000 +v -0.359375 0.406250 -0.062500 +v -0.296875 0.406250 -0.062500 +v -0.359375 0.406250 0.000000 +v -0.296875 0.406250 0.000000 +v 0.375000 -0.250000 0.031250 +v 0.375000 -0.312500 0.031250 +v 0.375000 -0.250000 -0.031250 +v 0.375000 -0.312500 -0.031250 +v -0.375000 -0.312500 -0.031250 +v -0.375000 -0.250000 -0.031250 +v -0.375000 -0.312500 0.031250 +v -0.375000 -0.250000 0.031250 +v -0.015625 0.406250 0.000000 +v -0.078125 0.406250 0.000000 +v -0.015625 0.406250 -0.062500 +v -0.078125 0.406250 -0.062500 +v -0.015625 -0.468750 -0.000000 +v -0.078125 -0.468750 -0.000000 +v -0.015625 -0.468750 -0.062500 +v -0.078125 -0.468750 -0.062500 +v 0.078125 0.406250 -0.000000 +v 0.015625 0.406250 -0.000000 +v 0.078125 0.406250 -0.062500 +v 0.015625 0.406250 -0.062500 +v 0.078125 -0.468750 -0.000000 +v 0.015625 -0.468750 -0.000000 +v 0.078125 -0.468750 -0.062500 +v 0.015625 -0.468750 -0.062500 +v -0.171875 -0.468750 -0.062500 +v -0.109375 -0.468750 -0.062500 +v -0.171875 -0.468750 -0.000000 +v -0.109375 -0.468750 0.000000 +v -0.171875 0.406250 -0.062500 +v -0.109375 0.406250 -0.062500 +v -0.171875 0.406250 0.000000 +v -0.109375 0.406250 0.000000 +v 0.296875 -0.468750 -0.062500 +v 0.359375 -0.468750 -0.062500 +v 0.296875 -0.468750 -0.000000 +v 0.359375 -0.468750 -0.000000 +v 0.296875 0.406250 -0.062500 +v 0.359375 0.406250 -0.062500 +v 0.296875 0.406250 -0.000000 +v 0.359375 0.406250 -0.000000 +vt 1.000000 0.515625 +vt 1.000000 0.546875 +vt 0.562500 0.546875 +vt 0.562500 0.515625 +vt 0.000000 0.000000 +vt 0.500000 0.000000 +vt 0.500000 0.062500 +vt 0.000000 0.062500 +vt 0.531250 0.031250 +vt 0.531250 0.000000 +vt 0.562500 0.000000 +vt 0.562500 0.031250 +vt 0.000000 0.187500 +vt 0.500000 0.187500 +vt 0.500000 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.500000 +vt 0.500000 0.500000 +vt 0.500000 0.562500 +vt 0.000000 0.562500 +vt 0.562500 0.093750 +vt 1.000000 0.093750 +vt 1.000000 0.125000 +vt 0.562500 0.125000 +vt 0.562500 0.406250 +vt 1.000000 0.406250 +vt 1.000000 0.437500 +vt 0.562500 0.437500 +vt 0.531250 0.343750 +vt 0.531250 0.312500 +vt 0.562500 0.312500 +vt 0.562500 0.343750 +vt 1.000000 0.312500 +vt 1.000000 0.343750 +vt 0.000000 0.312500 +vt 0.500000 0.312500 +vt 0.500000 0.375000 +vt 0.000000 0.375000 +vt 0.000000 0.437500 +vt 0.500000 0.437500 +vt 1.000000 0.375000 +vt 0.562500 0.375000 +vt 1.000000 0.937500 +vt 1.000000 0.968750 +vt 0.562500 0.968750 +vt 0.562500 0.937500 +vt 1.000000 0.234375 +vt 1.000000 0.265625 +vt 0.562500 0.265625 +vt 0.562500 0.234375 +vt 1.000000 0.796875 +vt 1.000000 0.828125 +vt 0.562500 0.828125 +vt 0.562500 0.796875 +vt 0.562500 0.765625 +vt 1.000000 0.765625 +vt 0.562500 0.734375 +vt 1.000000 0.734375 +vt 0.531250 0.765625 +vt 0.531250 0.734375 +vt 1.000000 0.859375 +vt 0.562500 0.859375 +vt 0.500000 0.125000 +vt 0.000000 0.125000 +vt 0.562500 0.000000 +vt 0.562500 0.062500 +vt 0.312500 0.593750 +vt 0.312500 0.625000 +vt 0.000000 0.625000 +vt 0.000000 0.593750 +vt 0.312500 0.718750 +vt 0.000000 0.718750 +vt 0.000000 0.687500 +vt 0.312500 0.687500 +vt 0.000000 0.656250 +vt 0.312500 0.656250 +vt 0.562500 0.312500 +vt 0.562500 0.375000 +vt 0.562500 0.687500 +vt 1.000000 0.687500 +vt 1.000000 0.718750 +vt 0.562500 0.718750 +vt 0.531250 0.625000 +vt 0.531250 0.593750 +vt 0.562500 0.593750 +vt 0.562500 0.625000 +vt 1.000000 0.593750 +vt 1.000000 0.625000 +vt 1.000000 0.656250 +vt 0.562500 0.656250 +vt 0.312500 0.812500 +vt 0.000000 0.812500 +vt 0.000000 0.781250 +vt 0.312500 0.781250 +vt 0.312500 0.750000 +vt 0.000000 0.750000 +vt 0.000000 0.718750 +vt 0.312500 0.718750 +vt 0.000000 0.843750 +vt 0.312500 0.843750 +vt 0.562500 0.203125 +vt 1.000000 0.203125 +vt 0.562500 0.171875 +vt 1.000000 0.171875 +vt 0.531250 0.203125 +vt 0.531250 0.171875 +vt 1.000000 0.296875 +vt 0.562500 0.296875 +vt 0.468750 0.937500 +vt 0.468750 0.968750 +vt 0.031250 0.968750 +vt 0.031250 0.937500 +vt 0.031250 0.906250 +vt 0.468750 0.906250 +vt 0.031250 0.875000 +vt 0.468750 0.875000 +vt 0.000000 0.906250 +vt 0.000000 0.875000 +vt 0.468750 1.000000 +vt 0.031250 1.000000 +vt 1.000000 0.578125 +vt 0.562500 0.578125 +vt 0.531250 0.484375 +vt 0.531250 0.453125 +vt 0.562500 0.453125 +vt 0.562500 0.484375 +vt 1.000000 1.000000 +vt 0.562500 1.000000 +vt 0.531250 0.906250 +vt 0.531250 0.875000 +vt 0.562500 0.875000 +vt 0.562500 0.906250 +vt 1.000000 0.875000 +vt 1.000000 0.906250 +vt 1.000000 0.062500 +vt 0.562500 0.062500 +vt 1.000000 0.031250 +vt 1.000000 0.000000 +vt 1.000000 0.484375 +vt 1.000000 0.453125 +vn -0.0000 -0.0000 1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 -0.0000 +vn -0.0000 0.0000 -1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +s off +f 83/1/1 84/2/1 88/3/1 87/4/1 +f 15/5/2 16/6/2 14/7/2 13/8/2 +f 2/9/3 1/10/3 3/11/3 4/12/3 +f 11/13/4 12/14/4 16/15/4 15/16/4 +f 38/17/5 37/18/5 33/19/5 34/20/5 +f 1/21/2 5/22/2 7/23/2 3/24/2 +f 24/25/2 20/26/2 18/27/2 22/28/2 +f 23/29/3 24/30/3 22/31/3 21/32/3 +f 21/32/4 22/31/4 18/33/4 17/34/4 +f 34/35/4 33/36/4 35/37/4 36/38/4 +f 40/39/1 39/40/1 37/18/1 38/17/1 +f 19/41/5 23/42/5 21/32/5 17/34/5 +f 19/41/1 20/26/1 24/25/1 23/42/1 +f 91/43/1 92/44/1 96/45/1 95/46/1 +f 70/47/1 69/48/1 65/49/1 66/50/1 +f 30/51/1 29/52/1 25/53/1 26/54/1 +f 30/51/5 26/54/5 28/55/5 32/56/5 +f 28/55/4 27/57/4 31/58/4 32/56/4 +f 26/59/3 25/60/3 27/57/3 28/55/3 +f 25/53/2 29/52/2 31/61/2 27/62/2 +f 13/8/1 14/7/1 10/63/1 9/64/1 +f 16/6/3 12/65/3 10/66/3 14/7/3 +f 9/64/5 10/63/5 12/14/5 11/13/5 +f 46/67/1 45/68/1 41/69/1 42/70/1 +f 46/71/6 42/72/6 44/73/6 48/74/6 +f 44/73/4 43/75/4 47/76/4 48/74/4 +f 33/36/3 37/77/3 39/78/3 35/37/3 +f 41/69/3 45/68/3 47/76/3 43/75/3 +f 56/79/2 52/80/2 50/81/2 54/82/2 +f 55/83/3 56/84/3 54/85/3 53/86/3 +f 53/86/4 54/85/4 50/87/4 49/88/4 +f 51/89/5 55/90/5 53/86/5 49/88/5 +f 51/89/1 52/80/1 56/79/1 55/90/1 +f 64/91/3 57/92/3 59/93/3 62/94/3 +f 36/38/2 35/37/2 39/40/2 40/39/2 +f 61/95/4 62/94/4 59/93/4 60/96/4 +f 58/97/6 63/98/6 61/95/6 60/96/6 +f 58/99/1 57/92/1 64/91/1 63/100/1 +f 70/47/5 66/50/5 68/101/5 72/102/5 +f 68/101/4 67/103/4 71/104/4 72/102/4 +f 66/105/3 65/106/3 67/103/3 68/101/3 +f 65/49/2 69/48/2 71/107/2 67/108/2 +f 78/109/1 77/110/1 73/111/1 74/112/1 +f 78/109/5 74/112/5 76/113/5 80/114/5 +f 76/113/4 75/115/4 79/116/4 80/114/4 +f 74/117/3 73/118/3 75/115/3 76/113/3 +f 73/111/2 77/110/2 79/119/2 75/120/2 +f 88/3/2 84/2/2 82/121/2 86/122/2 +f 87/123/3 88/124/3 86/125/3 85/126/3 +f 96/45/2 92/44/2 90/127/2 94/128/2 +f 95/129/3 96/130/3 94/131/3 93/132/3 +f 93/132/4 94/131/4 90/133/4 89/134/4 +f 91/43/5 95/46/5 93/132/5 89/134/5 +f 6/135/1 5/22/1 1/21/1 2/136/1 +f 6/135/5 2/136/5 4/12/5 8/137/5 +f 4/12/4 3/11/4 7/138/4 8/137/4 +f 83/1/5 87/4/5 85/126/5 81/139/5 +f 85/126/4 86/125/4 82/140/4 81/139/4 diff --git a/mods/furniture/models/furniture_fence_1_b.obj b/mods/furniture/models/furniture_fence_1_b.obj new file mode 100644 index 0000000..e85aaf9 --- /dev/null +++ b/mods/furniture/models/furniture_fence_1_b.obj @@ -0,0 +1,323 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Fence_1_b_Cube +v -0.062500 -0.500000 -0.500000 +v -0.062500 0.500000 -0.500000 +v 0.062500 -0.500000 -0.500000 +v 0.062500 0.500000 -0.500000 +v -0.062500 -0.500000 -0.375000 +v -0.062500 0.500000 -0.375000 +v 0.062500 -0.500000 -0.375000 +v 0.062500 0.500000 -0.375000 +v -0.031250 0.250000 -0.375000 +v -0.031250 0.312500 -0.375000 +v 0.031250 0.250000 -0.375000 +v 0.031250 0.312500 -0.375000 +v -0.031250 0.250000 -0.062500 +v -0.031250 0.312500 -0.062500 +v 0.031250 0.250000 -0.062500 +v 0.031250 0.312500 -0.062500 +v -0.500000 -0.500000 0.062500 +v -0.500000 0.500000 0.062500 +v -0.500000 -0.500000 -0.062500 +v -0.500000 0.500000 -0.062500 +v -0.375000 -0.500000 0.062500 +v -0.375000 0.500000 0.062500 +v -0.375000 -0.500000 -0.062500 +v -0.375000 0.500000 -0.062500 +v 0.031250 -0.250000 -0.375000 +v 0.031250 -0.312500 -0.375000 +v -0.031250 -0.250000 -0.375000 +v -0.031250 -0.312500 -0.375000 +v -0.031250 -0.312500 -0.062500 +v -0.031250 -0.250000 -0.062500 +v 0.031250 -0.312500 -0.062500 +v 0.031250 -0.250000 -0.062500 +v -0.187500 0.406250 0.000000 +v -0.250000 0.406250 0.000000 +v -0.187500 0.406250 -0.062500 +v -0.250000 0.406250 -0.062500 +v -0.187500 -0.468750 -0.000000 +v -0.250000 -0.468750 -0.000000 +v -0.187500 -0.468750 -0.062500 +v -0.250000 -0.468750 -0.062500 +v -0.062500 0.500000 -0.062500 +v -0.062500 -0.500000 -0.062500 +v 0.062500 0.500000 -0.062500 +v 0.062500 -0.500000 -0.062500 +v -0.062500 0.500000 0.062500 +v -0.062500 -0.500000 0.062500 +v 0.062500 0.500000 0.062500 +v 0.062500 -0.500000 0.062500 +v -0.375000 0.312500 0.031250 +v -0.375000 0.250000 0.031250 +v -0.375000 0.312500 -0.031250 +v -0.375000 0.250000 -0.031250 +v -0.062500 0.312500 0.031250 +v -0.062500 0.250000 0.031250 +v -0.062500 0.312500 -0.031250 +v -0.062500 0.250000 -0.031250 +v -0.343750 -0.468750 -0.062500 +v -0.281250 -0.468750 -0.062500 +v -0.343750 -0.468750 -0.000000 +v -0.281250 -0.468750 0.000000 +v -0.343750 0.406250 -0.062500 +v -0.281250 0.406250 -0.062500 +v -0.343750 0.406250 0.000000 +v -0.281250 0.406250 0.000000 +v -0.062500 -0.250000 0.031250 +v -0.062500 -0.312500 0.031250 +v -0.062500 -0.250000 -0.031250 +v -0.062500 -0.312500 -0.031250 +v -0.375000 -0.312500 -0.031250 +v -0.375000 -0.250000 -0.031250 +v -0.375000 -0.312500 0.031250 +v -0.375000 -0.250000 0.031250 +v -0.093750 0.406250 0.000000 +v -0.156250 0.406250 0.000000 +v -0.093750 0.406250 -0.062500 +v -0.156250 0.406250 -0.062500 +v -0.093750 -0.468750 -0.000000 +v -0.156250 -0.468750 -0.000000 +v -0.093750 -0.468750 -0.062500 +v -0.156250 -0.468750 -0.062500 +v -0.062500 0.406250 -0.187500 +v -0.062500 0.406250 -0.250000 +v -0.000000 0.406250 -0.187500 +v -0.000000 0.406250 -0.250000 +v -0.062500 -0.468750 -0.187500 +v -0.062500 -0.468750 -0.250000 +v -0.000000 -0.468750 -0.187500 +v -0.000000 -0.468750 -0.250000 +v -0.000000 -0.468750 -0.343750 +v -0.000000 -0.468750 -0.281250 +v -0.062500 -0.468750 -0.343750 +v -0.062500 -0.468750 -0.281250 +v -0.000000 0.406250 -0.343750 +v -0.000000 0.406250 -0.281250 +v -0.062500 0.406250 -0.343750 +v -0.062500 0.406250 -0.281250 +v -0.062500 0.406250 -0.093750 +v -0.062500 0.406250 -0.156250 +v -0.000000 0.406250 -0.093750 +v -0.000000 0.406250 -0.156250 +v -0.062500 -0.468750 -0.093750 +v -0.062500 -0.468750 -0.156250 +v -0.000000 -0.468750 -0.093750 +v -0.000000 -0.468750 -0.156250 +vt 0.000000 0.875000 +vt 0.500000 0.875000 +vt 0.500000 0.937500 +vt 0.000000 0.937500 +vt 0.500000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.750000 +vt 0.500000 0.750000 +vt 0.500000 0.812500 +vt 0.000000 0.812500 +vt 0.000000 0.453125 +vt 0.500000 0.453125 +vt 0.500000 0.515625 +vt 0.000000 0.515625 +vt 0.562500 0.750000 +vt 0.562500 0.812500 +vt 0.859375 0.093750 +vt 0.703125 0.093750 +vt 0.703125 0.062500 +vt 0.859375 0.062500 +vt 0.000000 0.640625 +vt 0.500000 0.640625 +vt 0.500000 0.703125 +vt 0.000000 0.703125 +vt 0.000000 0.187500 +vt 0.500000 0.187500 +vt 0.500000 0.250000 +vt 0.000000 0.250000 +vt 0.859375 0.031250 +vt 0.703125 0.031250 +vt 0.703125 0.000000 +vt 0.859375 0.000000 +vt 0.703125 0.125000 +vt 0.859375 0.125000 +vt 0.500000 0.390625 +vt 0.343750 0.390625 +vt 0.343750 0.359375 +vt 0.500000 0.359375 +vt 0.000000 0.000000 +vt 0.500000 0.000000 +vt 0.500000 0.062500 +vt 0.000000 0.062500 +vt 0.000000 0.125000 +vt 0.500000 0.125000 +vt 0.500000 0.328125 +vt 0.343750 0.328125 +vt 0.343750 0.296875 +vt 0.500000 0.296875 +vt 0.343750 0.421875 +vt 0.500000 0.421875 +vt 1.000000 0.937500 +vt 1.000000 0.968750 +vt 0.562500 0.968750 +vt 0.562500 0.937500 +vt 1.000000 0.781250 +vt 1.000000 0.812500 +vt 0.562500 0.812500 +vt 0.562500 0.781250 +vt 0.562500 0.750000 +vt 1.000000 0.750000 +vt 0.562500 0.718750 +vt 1.000000 0.718750 +vt 0.531250 0.750000 +vt 0.531250 0.718750 +vt 1.000000 0.843750 +vt 0.562500 0.843750 +vt 0.500000 0.578125 +vt 0.000000 0.578125 +vt 0.562500 0.453125 +vt 0.562500 0.515625 +vt 0.156250 0.296875 +vt 0.156250 0.328125 +vt 0.000000 0.328125 +vt 0.000000 0.296875 +vt 0.156250 0.421875 +vt 0.000000 0.421875 +vt 0.000000 0.390625 +vt 0.156250 0.390625 +vt 0.000000 0.359375 +vt 0.156250 0.359375 +vt 0.562500 0.000000 +vt 0.562500 0.062500 +vt 0.562500 0.671875 +vt 1.000000 0.671875 +vt 1.000000 0.703125 +vt 0.562500 0.703125 +vt 0.531250 0.609375 +vt 0.531250 0.578125 +vt 0.562500 0.578125 +vt 0.562500 0.609375 +vt 1.000000 0.578125 +vt 1.000000 0.609375 +vt 1.000000 0.640625 +vt 0.562500 0.640625 +vt 0.328125 0.390625 +vt 0.171875 0.390625 +vt 0.171875 0.359375 +vt 0.328125 0.359375 +vt 0.328125 0.328125 +vt 0.171875 0.328125 +vt 0.171875 0.296875 +vt 0.328125 0.296875 +vt 0.171875 0.421875 +vt 0.328125 0.421875 +vt 0.562500 0.906250 +vt 1.000000 0.906250 +vt 0.562500 0.875000 +vt 1.000000 0.875000 +vt 0.531250 0.906250 +vt 0.531250 0.875000 +vt 1.000000 1.000000 +vt 0.562500 1.000000 +vt 1.000000 0.500000 +vt 1.000000 0.531250 +vt 0.562500 0.531250 +vt 0.562500 0.500000 +vt 1.000000 0.359375 +vt 1.000000 0.390625 +vt 0.562500 0.390625 +vt 0.562500 0.359375 +vt 0.562500 0.328125 +vt 1.000000 0.328125 +vt 0.562500 0.296875 +vt 1.000000 0.296875 +vt 0.531250 0.328125 +vt 0.531250 0.296875 +vt 1.000000 0.421875 +vt 0.562500 0.421875 +vt 0.562500 0.234375 +vt 1.000000 0.234375 +vt 1.000000 0.265625 +vt 0.562500 0.265625 +vt 0.531250 0.171875 +vt 0.531250 0.140625 +vt 0.562500 0.140625 +vt 0.562500 0.171875 +vt 1.000000 0.140625 +vt 1.000000 0.171875 +vt 1.000000 0.203125 +vt 0.562500 0.203125 +vt 0.562500 0.468750 +vt 1.000000 0.468750 +vt 0.562500 0.437500 +vt 1.000000 0.437500 +vt 0.531250 0.468750 +vt 0.531250 0.437500 +vt 1.000000 0.562500 +vt 0.562500 0.562500 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 -0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/7/3 8/8/3 6/9/3 5/10/3 +f 5/10/4 6/9/4 2/2/4 1/1/4 +f 23/11/2 24/12/2 22/13/2 21/14/2 +f 8/8/5 4/15/5 2/16/5 6/9/5 +f 16/17/5 12/18/5 10/19/5 14/20/5 +f 19/21/1 20/22/1 24/23/1 23/24/1 +f 46/25/4 45/26/4 41/27/4 42/28/4 +f 13/29/4 14/20/4 10/19/4 9/30/4 +f 11/31/6 15/32/6 13/29/6 9/30/6 +f 11/33/2 12/18/2 16/17/2 15/34/2 +f 32/35/5 25/36/5 27/37/5 30/38/5 +f 42/39/1 41/40/1 43/41/1 44/42/1 +f 48/43/3 47/44/3 45/26/3 46/25/3 +f 29/45/4 30/38/4 27/37/4 28/46/4 +f 26/47/6 31/48/6 29/45/6 28/46/6 +f 26/49/2 25/36/2 32/35/2 31/50/2 +f 78/51/3 77/52/3 73/53/3 74/54/3 +f 38/55/3 37/56/3 33/57/3 34/58/3 +f 38/55/4 34/58/4 36/59/4 40/60/4 +f 36/59/1 35/61/1 39/62/1 40/60/1 +f 34/63/5 33/64/5 35/61/5 36/59/5 +f 33/57/2 37/56/2 39/65/2 35/66/2 +f 21/14/3 22/13/3 18/67/3 17/68/3 +f 24/12/5 20/69/5 18/70/5 22/13/5 +f 17/68/4 18/67/4 20/22/4 19/21/4 +f 54/71/3 53/72/3 49/73/3 50/74/3 +f 54/75/6 50/76/6 52/77/6 56/78/6 +f 52/77/1 51/79/1 55/80/1 56/78/1 +f 41/40/5 45/81/5 47/82/5 43/41/5 +f 49/73/5 53/72/5 55/80/5 51/79/5 +f 64/83/2 60/84/2 58/85/2 62/86/2 +f 63/87/5 64/88/5 62/89/5 61/90/5 +f 61/90/1 62/89/1 58/91/1 57/92/1 +f 59/93/4 63/94/4 61/90/4 57/92/4 +f 59/93/3 60/84/3 64/83/3 63/94/3 +f 72/95/5 65/96/5 67/97/5 70/98/5 +f 44/42/2 43/41/2 47/44/2 48/43/2 +f 69/99/1 70/98/1 67/97/1 68/100/1 +f 66/101/6 71/102/6 69/99/6 68/100/6 +f 66/103/3 65/96/3 72/95/3 71/104/3 +f 78/51/4 74/54/4 76/105/4 80/106/4 +f 76/105/1 75/107/1 79/108/1 80/106/1 +f 74/109/5 73/110/5 75/107/5 76/105/5 +f 73/53/2 77/52/2 79/111/2 75/112/2 +f 102/113/4 101/114/4 97/115/4 98/116/4 +f 86/117/4 85/118/4 81/119/4 82/120/4 +f 86/117/1 82/120/1 84/121/1 88/122/1 +f 84/121/2 83/123/2 87/124/2 88/122/2 +f 82/125/5 81/126/5 83/123/5 84/121/5 +f 81/119/3 85/118/3 87/127/3 83/128/3 +f 96/129/3 92/130/3 90/131/3 94/132/3 +f 95/133/5 96/134/5 94/135/5 93/136/5 +f 93/136/2 94/135/2 90/137/2 89/138/2 +f 91/139/1 95/140/1 93/136/1 89/138/1 +f 91/139/4 92/130/4 96/129/4 95/140/4 +f 102/113/1 98/116/1 100/141/1 104/142/1 +f 100/141/2 99/143/2 103/144/2 104/142/2 +f 98/145/5 97/146/5 99/143/5 100/141/5 +f 97/115/3 101/114/3 103/147/3 99/148/3 diff --git a/mods/furniture/models/furniture_fence_1_c.obj b/mods/furniture/models/furniture_fence_1_c.obj new file mode 100644 index 0000000..f8e59f4 --- /dev/null +++ b/mods/furniture/models/furniture_fence_1_c.obj @@ -0,0 +1,323 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Fence_1_c_Cube.021 +v 0.062500 -0.500000 0.500000 +v 0.062500 0.500000 0.500000 +v -0.062500 -0.500000 0.500000 +v -0.062500 0.500000 0.500000 +v 0.062500 -0.500000 0.375000 +v 0.062500 0.500000 0.375000 +v -0.062500 -0.500000 0.375000 +v -0.062500 0.500000 0.375000 +v 0.031250 0.250000 0.375000 +v 0.031250 0.312500 0.375000 +v -0.031250 0.250000 0.375000 +v -0.031250 0.312500 0.375000 +v 0.031250 0.250000 0.062500 +v 0.031250 0.312500 0.062500 +v -0.031250 0.250000 0.062500 +v -0.031250 0.312500 0.062500 +v 0.500000 -0.500000 -0.062500 +v 0.500000 0.500000 -0.062500 +v 0.500000 -0.500000 0.062500 +v 0.500000 0.500000 0.062500 +v 0.375000 -0.500000 -0.062500 +v 0.375000 0.500000 -0.062500 +v 0.375000 -0.500000 0.062500 +v 0.375000 0.500000 0.062500 +v -0.031250 -0.250000 0.375000 +v -0.031250 -0.312500 0.375000 +v 0.031250 -0.250000 0.375000 +v 0.031250 -0.312500 0.375000 +v 0.031250 -0.312500 0.062500 +v 0.031250 -0.250000 0.062500 +v -0.031250 -0.312500 0.062500 +v -0.031250 -0.250000 0.062500 +v 0.187500 0.406250 -0.062500 +v 0.250000 0.406250 -0.062500 +v 0.187500 0.406250 -0.000000 +v 0.250000 0.406250 0.000000 +v 0.187500 -0.468750 -0.062500 +v 0.250000 -0.468750 -0.062500 +v 0.187500 -0.468750 0.000000 +v 0.250000 -0.468750 0.000000 +v 0.062500 0.500000 0.062500 +v 0.062500 -0.500000 0.062500 +v -0.062500 0.500000 0.062500 +v -0.062500 -0.500000 0.062500 +v 0.062500 0.500000 -0.062500 +v 0.062500 -0.500000 -0.062500 +v -0.062500 0.500000 -0.062500 +v -0.062500 -0.500000 -0.062500 +v 0.375000 0.312500 -0.031250 +v 0.375000 0.250000 -0.031250 +v 0.375000 0.312500 0.031250 +v 0.375000 0.250000 0.031250 +v 0.062500 0.312500 -0.031250 +v 0.062500 0.250000 -0.031250 +v 0.062500 0.312500 0.031250 +v 0.062500 0.250000 0.031250 +v 0.343750 -0.468750 0.000000 +v 0.281250 -0.468750 0.000000 +v 0.343750 -0.468750 -0.062500 +v 0.281250 -0.468750 -0.062500 +v 0.343750 0.406250 0.000000 +v 0.281250 0.406250 -0.000000 +v 0.343750 0.406250 -0.062500 +v 0.281250 0.406250 -0.062500 +v 0.062500 -0.250000 -0.031250 +v 0.062500 -0.312500 -0.031250 +v 0.062500 -0.250000 0.031250 +v 0.062500 -0.312500 0.031250 +v 0.375000 -0.312500 0.031250 +v 0.375000 -0.250000 0.031250 +v 0.375000 -0.312500 -0.031250 +v 0.375000 -0.250000 -0.031250 +v 0.093750 0.406250 -0.062500 +v 0.156250 0.406250 -0.062500 +v 0.093750 0.406250 -0.000000 +v 0.156250 0.406250 0.000000 +v 0.093750 -0.468750 -0.062500 +v 0.156250 -0.468750 -0.062500 +v 0.093750 -0.468750 0.000000 +v 0.156250 -0.468750 0.000000 +v -0.000000 0.406250 0.187500 +v -0.000000 0.406250 0.250000 +v -0.062500 0.406250 0.187500 +v -0.062500 0.406250 0.250000 +v -0.000000 -0.468750 0.187500 +v -0.000000 -0.468750 0.250000 +v -0.062500 -0.468750 0.187500 +v -0.062500 -0.468750 0.250000 +v -0.062500 -0.468750 0.343750 +v -0.062500 -0.468750 0.281250 +v -0.000000 -0.468750 0.343750 +v -0.000000 -0.468750 0.281250 +v -0.062500 0.406250 0.343750 +v -0.062500 0.406250 0.281250 +v -0.000000 0.406250 0.343750 +v -0.000000 0.406250 0.281250 +v 0.000000 0.406250 0.093750 +v -0.000000 0.406250 0.156250 +v -0.062500 0.406250 0.093750 +v -0.062500 0.406250 0.156250 +v -0.000000 -0.468750 0.093750 +v -0.000000 -0.468750 0.156250 +v -0.062500 -0.468750 0.093750 +v -0.062500 -0.468750 0.156250 +vt 0.000000 0.875000 +vt 0.500000 0.875000 +vt 0.500000 0.937500 +vt 0.000000 0.937500 +vt 0.500000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.750000 +vt 0.500000 0.750000 +vt 0.500000 0.812500 +vt 0.000000 0.812500 +vt 0.000000 0.468750 +vt 0.500000 0.468750 +vt 0.500000 0.531250 +vt 0.000000 0.531250 +vt 0.562500 0.750000 +vt 0.562500 0.812500 +vt 0.328125 0.390625 +vt 0.171875 0.390625 +vt 0.171875 0.359375 +vt 0.328125 0.359375 +vt 0.000000 0.656250 +vt 0.500000 0.656250 +vt 0.500000 0.718750 +vt 0.000000 0.718750 +vt 0.000000 0.187500 +vt 0.500000 0.187500 +vt 0.500000 0.250000 +vt 0.000000 0.250000 +vt 0.328125 0.328125 +vt 0.171875 0.328125 +vt 0.171875 0.296875 +vt 0.328125 0.296875 +vt 0.171875 0.421875 +vt 0.328125 0.421875 +vt 0.812500 0.093750 +vt 0.656250 0.093750 +vt 0.656250 0.062500 +vt 0.812500 0.062500 +vt 0.000000 0.000000 +vt 0.500000 0.000000 +vt 0.500000 0.062500 +vt 0.000000 0.062500 +vt 0.000000 0.125000 +vt 0.500000 0.125000 +vt 0.812500 0.031250 +vt 0.656250 0.031250 +vt 0.656250 0.000000 +vt 0.812500 0.000000 +vt 0.656250 0.125000 +vt 0.812500 0.125000 +vt 1.000000 0.937500 +vt 1.000000 0.968750 +vt 0.562500 0.968750 +vt 0.562500 0.937500 +vt 1.000000 0.781250 +vt 1.000000 0.812500 +vt 0.562500 0.812500 +vt 0.562500 0.781250 +vt 0.562500 0.750000 +vt 1.000000 0.750000 +vt 0.562500 0.718750 +vt 1.000000 0.718750 +vt 0.531250 0.750000 +vt 0.531250 0.718750 +vt 1.000000 0.843750 +vt 0.562500 0.843750 +vt 0.500000 0.593750 +vt 0.000000 0.593750 +vt 0.562500 0.468750 +vt 0.562500 0.531250 +vt 0.156250 0.296875 +vt 0.156250 0.328125 +vt 0.000000 0.328125 +vt 0.000000 0.296875 +vt 0.156250 0.421875 +vt 0.000000 0.421875 +vt 0.000000 0.390625 +vt 0.156250 0.390625 +vt 0.000000 0.359375 +vt 0.156250 0.359375 +vt 0.562500 0.000000 +vt 0.562500 0.062500 +vt 0.562500 0.671875 +vt 1.000000 0.671875 +vt 1.000000 0.703125 +vt 0.562500 0.703125 +vt 0.531250 0.609375 +vt 0.531250 0.578125 +vt 0.562500 0.578125 +vt 0.562500 0.609375 +vt 1.000000 0.578125 +vt 1.000000 0.609375 +vt 1.000000 0.640625 +vt 0.562500 0.640625 +vt 0.500000 0.390625 +vt 0.343750 0.390625 +vt 0.343750 0.359375 +vt 0.500000 0.359375 +vt 0.500000 0.328125 +vt 0.343750 0.328125 +vt 0.343750 0.296875 +vt 0.500000 0.296875 +vt 0.343750 0.421875 +vt 0.500000 0.421875 +vt 0.562500 0.906250 +vt 1.000000 0.906250 +vt 0.562500 0.875000 +vt 1.000000 0.875000 +vt 0.531250 0.906250 +vt 0.531250 0.875000 +vt 1.000000 1.000000 +vt 0.562500 1.000000 +vt 1.000000 0.500000 +vt 1.000000 0.531250 +vt 0.562500 0.531250 +vt 0.562500 0.500000 +vt 1.000000 0.359375 +vt 1.000000 0.390625 +vt 0.562500 0.390625 +vt 0.562500 0.359375 +vt 0.562500 0.328125 +vt 1.000000 0.328125 +vt 0.562500 0.296875 +vt 1.000000 0.296875 +vt 0.531250 0.328125 +vt 0.531250 0.296875 +vt 1.000000 0.421875 +vt 0.562500 0.421875 +vt 0.562500 0.234375 +vt 1.000000 0.234375 +vt 1.000000 0.265625 +vt 0.562500 0.265625 +vt 0.531250 0.171875 +vt 0.531250 0.140625 +vt 0.562500 0.140625 +vt 0.562500 0.171875 +vt 1.000000 0.140625 +vt 1.000000 0.171875 +vt 1.000000 0.203125 +vt 0.562500 0.203125 +vt 0.562500 0.468750 +vt 1.000000 0.468750 +vt 0.562500 0.437500 +vt 1.000000 0.437500 +vt 0.531250 0.468750 +vt 0.531250 0.437500 +vt 1.000000 0.562500 +vt 0.562500 0.562500 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 -0.0000 +vn 0.0000 -1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/7/3 8/8/3 6/9/3 5/10/3 +f 5/10/4 6/9/4 2/2/4 1/1/4 +f 23/11/2 24/12/2 22/13/2 21/14/2 +f 8/8/5 4/15/5 2/16/5 6/9/5 +f 16/17/5 12/18/5 10/19/5 14/20/5 +f 19/21/1 20/22/1 24/23/1 23/24/1 +f 46/25/4 45/26/4 41/27/4 42/28/4 +f 13/29/4 14/20/4 10/19/4 9/30/4 +f 11/31/6 15/32/6 13/29/6 9/30/6 +f 11/33/2 12/18/2 16/17/2 15/34/2 +f 32/35/5 25/36/5 27/37/5 30/38/5 +f 42/39/1 41/40/1 43/41/1 44/42/1 +f 48/43/3 47/44/3 45/26/3 46/25/3 +f 29/45/4 30/38/4 27/37/4 28/46/4 +f 26/47/6 31/48/6 29/45/6 28/46/6 +f 26/49/2 25/36/2 32/35/2 31/50/2 +f 78/51/3 77/52/3 73/53/3 74/54/3 +f 38/55/3 37/56/3 33/57/3 34/58/3 +f 38/55/4 34/58/4 36/59/4 40/60/4 +f 36/59/1 35/61/1 39/62/1 40/60/1 +f 34/63/5 33/64/5 35/61/5 36/59/5 +f 33/57/2 37/56/2 39/65/2 35/66/2 +f 21/14/3 22/13/3 18/67/3 17/68/3 +f 24/12/5 20/69/5 18/70/5 22/13/5 +f 17/68/4 18/67/4 20/22/4 19/21/4 +f 54/71/3 53/72/3 49/73/3 50/74/3 +f 54/75/6 50/76/6 52/77/6 56/78/6 +f 52/77/1 51/79/1 55/80/1 56/78/1 +f 41/40/5 45/81/5 47/82/5 43/41/5 +f 49/73/5 53/72/5 55/80/5 51/79/5 +f 64/83/2 60/84/2 58/85/2 62/86/2 +f 63/87/5 64/88/5 62/89/5 61/90/5 +f 61/90/1 62/89/1 58/91/1 57/92/1 +f 59/93/4 63/94/4 61/90/4 57/92/4 +f 59/93/3 60/84/3 64/83/3 63/94/3 +f 72/95/5 65/96/5 67/97/5 70/98/5 +f 44/42/2 43/41/2 47/44/2 48/43/2 +f 69/99/1 70/98/1 67/97/1 68/100/1 +f 66/101/6 71/102/6 69/99/6 68/100/6 +f 66/103/3 65/96/3 72/95/3 71/104/3 +f 78/51/4 74/54/4 76/105/4 80/106/4 +f 76/105/1 75/107/1 79/108/1 80/106/1 +f 74/109/5 73/110/5 75/107/5 76/105/5 +f 73/53/2 77/52/2 79/111/2 75/112/2 +f 102/113/4 101/114/4 97/115/4 98/116/4 +f 86/117/4 85/118/4 81/119/4 82/120/4 +f 86/117/1 82/120/1 84/121/1 88/122/1 +f 84/121/2 83/123/2 87/124/2 88/122/2 +f 82/125/5 81/126/5 83/123/5 84/121/5 +f 81/119/3 85/118/3 87/127/3 83/128/3 +f 96/129/3 92/130/3 90/131/3 94/132/3 +f 95/133/5 96/134/5 94/135/5 93/136/5 +f 93/136/2 94/135/2 90/137/2 89/138/2 +f 91/139/1 95/140/1 93/136/1 89/138/1 +f 91/139/4 92/130/4 96/129/4 95/140/4 +f 102/113/1 98/116/1 100/141/1 104/142/1 +f 100/141/2 99/143/2 103/144/2 104/142/2 +f 98/145/5 97/146/5 99/143/5 100/141/5 +f 97/115/3 101/114/3 103/147/3 99/148/3 diff --git a/mods/furniture/models/furniture_fence_1_d.obj b/mods/furniture/models/furniture_fence_1_d.obj new file mode 100644 index 0000000..078aa32 --- /dev/null +++ b/mods/furniture/models/furniture_fence_1_d.obj @@ -0,0 +1,321 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Fence_1_d_Cube.023 +v 0.343750 0.406250 0.203125 +v 0.343750 0.406250 0.265625 +v 0.281250 0.406250 0.203125 +v 0.281250 0.406250 0.265625 +v 0.343750 -0.468750 0.203125 +v 0.343750 -0.468750 0.265625 +v 0.281250 -0.468750 0.203125 +v 0.281250 -0.468750 0.265625 +v -0.500000 -0.500000 0.062500 +v -0.500000 0.500000 0.062500 +v -0.500000 -0.500000 -0.062500 +v -0.500000 0.500000 -0.062500 +v -0.375000 -0.500000 0.062500 +v -0.375000 0.500000 0.062500 +v -0.375000 -0.500000 -0.062500 +v -0.375000 0.500000 -0.062500 +v 0.281250 -0.468750 0.171875 +v 0.281250 -0.468750 0.109375 +v 0.343750 -0.468750 0.171875 +v 0.343750 -0.468750 0.109375 +v 0.281250 0.406250 0.171875 +v 0.281250 0.406250 0.109375 +v 0.343750 0.406250 0.171875 +v 0.343750 0.406250 0.109375 +v 0.343750 0.406250 0.578125 +v 0.343750 0.406250 0.640625 +v 0.281250 0.406250 0.578125 +v 0.281250 0.406250 0.640625 +v 0.343750 -0.468750 0.578125 +v 0.343750 -0.468750 0.640625 +v 0.281250 -0.468750 0.578125 +v 0.281250 -0.468750 0.640625 +v 0.375000 0.500000 -0.062500 +v 0.375000 -0.500000 -0.062500 +v 0.500000 0.500000 -0.062500 +v 0.500000 -0.500000 -0.062500 +v 0.375000 0.500000 0.062500 +v 0.375000 -0.500000 0.062500 +v 0.500000 0.500000 0.062500 +v 0.500000 -0.500000 0.062500 +v 0.375000 0.312500 0.750000 +v 0.375000 0.250000 0.750000 +v 0.312500 0.312500 0.750000 +v 0.312500 0.250000 0.750000 +v 0.375000 0.312500 -0.000000 +v 0.375000 0.250000 -0.000000 +v 0.312500 0.312500 -0.000000 +v 0.312500 0.250000 -0.000000 +v 0.281250 -0.468750 0.734375 +v 0.281250 -0.468750 0.671875 +v 0.343750 -0.468750 0.734375 +v 0.343750 -0.468750 0.671875 +v 0.281250 0.406250 0.734375 +v 0.281250 0.406250 0.671875 +v 0.343750 0.406250 0.734375 +v 0.343750 0.406250 0.671875 +v 0.375000 -0.250000 -0.000000 +v 0.375000 -0.312500 -0.000000 +v 0.312500 -0.250000 -0.000000 +v 0.312500 -0.312500 -0.000000 +v 0.312500 -0.312500 0.750000 +v 0.312500 -0.250000 0.750000 +v 0.375000 -0.312500 0.750000 +v 0.375000 -0.250000 0.750000 +v 0.343750 0.406250 0.390625 +v 0.343750 0.406250 0.453125 +v 0.281250 0.406250 0.390625 +v 0.281250 0.406250 0.453125 +v 0.343750 -0.468750 0.390625 +v 0.343750 -0.468750 0.453125 +v 0.281250 -0.468750 0.390625 +v 0.281250 -0.468750 0.453125 +v 0.343750 0.406250 0.296875 +v 0.343750 0.406250 0.359375 +v 0.281250 0.406250 0.296875 +v 0.281250 0.406250 0.359375 +v 0.343750 -0.468750 0.296875 +v 0.343750 -0.468750 0.359375 +v 0.281250 -0.468750 0.296875 +v 0.281250 -0.468750 0.359375 +v 0.281250 -0.468750 0.546875 +v 0.281250 -0.468750 0.484375 +v 0.343750 -0.468750 0.546875 +v 0.343750 -0.468750 0.484375 +v 0.281250 0.406250 0.546875 +v 0.281250 0.406250 0.484375 +v 0.343750 0.406250 0.546875 +v 0.343750 0.406250 0.484375 +v 0.281250 -0.468750 0.078125 +v 0.281250 -0.468750 0.015625 +v 0.343750 -0.468750 0.078125 +v 0.343750 -0.468750 0.015625 +v 0.281250 0.406250 0.078125 +v 0.281250 0.406250 0.015625 +v 0.343750 0.406250 0.078125 +v 0.343750 0.406250 0.015625 +vt 1.000000 0.515625 +vt 1.000000 0.546875 +vt 0.562500 0.546875 +vt 0.562500 0.515625 +vt 0.000000 0.000000 +vt 0.500000 0.000000 +vt 0.500000 0.062500 +vt 0.000000 0.062500 +vt 0.531250 0.031250 +vt 0.531250 0.000000 +vt 0.562500 0.000000 +vt 0.562500 0.031250 +vt 0.000000 0.187500 +vt 0.500000 0.187500 +vt 0.500000 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.500000 +vt 0.500000 0.500000 +vt 0.500000 0.562500 +vt 0.000000 0.562500 +vt 0.562500 0.093750 +vt 1.000000 0.093750 +vt 1.000000 0.125000 +vt 0.562500 0.125000 +vt 0.562500 0.406250 +vt 1.000000 0.406250 +vt 1.000000 0.437500 +vt 0.562500 0.437500 +vt 0.531250 0.343750 +vt 0.531250 0.312500 +vt 0.562500 0.312500 +vt 0.562500 0.343750 +vt 1.000000 0.312500 +vt 1.000000 0.343750 +vt 0.000000 0.312500 +vt 0.500000 0.312500 +vt 0.500000 0.375000 +vt 0.000000 0.375000 +vt 0.000000 0.437500 +vt 0.500000 0.437500 +vt 1.000000 0.375000 +vt 0.562500 0.375000 +vt 1.000000 0.937500 +vt 1.000000 0.968750 +vt 0.562500 0.968750 +vt 0.562500 0.937500 +vt 1.000000 0.234375 +vt 1.000000 0.265625 +vt 0.562500 0.265625 +vt 0.562500 0.234375 +vt 1.000000 0.796875 +vt 1.000000 0.828125 +vt 0.562500 0.828125 +vt 0.562500 0.796875 +vt 0.562500 0.765625 +vt 1.000000 0.765625 +vt 0.562500 0.734375 +vt 1.000000 0.734375 +vt 0.531250 0.765625 +vt 0.531250 0.734375 +vt 1.000000 0.859375 +vt 0.562500 0.859375 +vt 0.500000 0.125000 +vt 0.000000 0.125000 +vt 0.562500 0.000000 +vt 0.562500 0.062500 +vt 0.312500 0.593750 +vt 0.312500 0.625000 +vt 0.000000 0.625000 +vt 0.000000 0.593750 +vt 0.312500 0.718750 +vt 0.000000 0.718750 +vt 0.000000 0.687500 +vt 0.312500 0.687500 +vt 0.000000 0.656250 +vt 0.312500 0.656250 +vt 0.562500 0.312500 +vt 0.562500 0.375000 +vt 0.562500 0.687500 +vt 1.000000 0.687500 +vt 1.000000 0.718750 +vt 0.562500 0.718750 +vt 0.531250 0.625000 +vt 0.531250 0.593750 +vt 0.562500 0.593750 +vt 0.562500 0.625000 +vt 1.000000 0.593750 +vt 1.000000 0.625000 +vt 1.000000 0.656250 +vt 0.562500 0.656250 +vt 0.312500 0.812500 +vt 0.000000 0.812500 +vt 0.000000 0.781250 +vt 0.312500 0.781250 +vt 0.312500 0.750000 +vt 0.000000 0.750000 +vt 0.000000 0.718750 +vt 0.312500 0.718750 +vt 0.000000 0.843750 +vt 0.312500 0.843750 +vt 0.562500 0.203125 +vt 1.000000 0.203125 +vt 0.562500 0.171875 +vt 1.000000 0.171875 +vt 0.531250 0.203125 +vt 0.531250 0.171875 +vt 1.000000 0.296875 +vt 0.562500 0.296875 +vt 0.468750 0.937500 +vt 0.468750 0.968750 +vt 0.031250 0.968750 +vt 0.031250 0.937500 +vt 0.031250 0.906250 +vt 0.468750 0.906250 +vt 0.031250 0.875000 +vt 0.468750 0.875000 +vt 0.000000 0.906250 +vt 0.000000 0.875000 +vt 0.468750 1.000000 +vt 0.031250 1.000000 +vt 1.000000 0.578125 +vt 0.562500 0.578125 +vt 0.531250 0.484375 +vt 0.531250 0.453125 +vt 0.562500 0.453125 +vt 0.562500 0.484375 +vt 1.000000 1.000000 +vt 0.562500 1.000000 +vt 0.531250 0.906250 +vt 0.531250 0.875000 +vt 0.562500 0.875000 +vt 0.562500 0.906250 +vt 1.000000 0.875000 +vt 1.000000 0.906250 +vt 1.000000 0.062500 +vt 0.562500 0.062500 +vt 1.000000 0.031250 +vt 1.000000 0.000000 +vt 1.000000 0.484375 +vt 1.000000 0.453125 +vt 0.281250 0.687500 +vt 0.312500 0.687500 +vt 0.281250 0.718750 +vt 0.000000 0.812500 +vt 0.031250 0.812500 +vt 0.031250 0.843750 +vt 0.031250 0.687500 +vt 0.000000 0.687500 +vt 0.000000 0.656250 +vt 0.031250 0.656250 +vt 0.281250 0.781250 +vt 0.281250 0.750000 +vt 0.312500 0.781250 +vn 1.0000 0.0000 -0.0000 +vn 0.0000 1.0000 0.0000 +vn -0.0000 0.0000 -1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +s off +f 83/1/1 84/2/1 88/3/1 87/4/1 +f 15/5/1 16/6/1 14/7/1 13/8/1 +f 2/9/2 1/10/2 3/11/2 4/12/2 +f 11/13/3 12/14/3 16/15/3 15/16/3 +f 38/17/4 37/18/4 33/19/4 34/20/4 +f 1/21/3 5/22/3 7/23/3 3/24/3 +f 24/25/3 20/26/3 18/27/3 22/28/3 +f 23/29/2 24/30/2 22/31/2 21/32/2 +f 21/32/4 22/31/4 18/33/4 17/34/4 +f 34/35/3 33/36/3 35/37/3 36/38/3 +f 40/39/5 39/40/5 37/18/5 38/17/5 +f 19/41/5 23/42/5 21/32/5 17/34/5 +f 19/41/1 20/26/1 24/25/1 23/42/1 +f 91/43/1 92/44/1 96/45/1 95/46/1 +f 70/47/1 69/48/1 65/49/1 66/50/1 +f 30/51/1 29/52/1 25/53/1 26/54/1 +f 30/51/5 26/54/5 28/55/5 32/56/5 +f 28/55/4 27/57/4 31/58/4 32/56/4 +f 26/59/2 25/60/2 27/57/2 28/55/2 +f 25/53/3 29/52/3 31/61/3 27/62/3 +f 13/8/5 14/7/5 10/63/5 9/64/5 +f 16/6/2 12/65/2 10/66/2 14/7/2 +f 9/64/4 10/63/4 12/14/4 11/13/4 +f 46/67/1 45/68/1 41/69/1 42/70/1 +f 46/71/6 42/72/6 44/73/6 48/74/6 +f 44/73/4 43/75/4 47/76/4 48/74/4 +f 33/36/2 37/77/2 39/78/2 35/37/2 +f 41/69/2 45/68/2 47/76/2 43/75/2 +f 56/79/3 52/80/3 50/81/3 54/82/3 +f 55/83/2 56/84/2 54/85/2 53/86/2 +f 53/86/4 54/85/4 50/87/4 49/88/4 +f 51/89/5 55/90/5 53/86/5 49/88/5 +f 51/89/1 52/80/1 56/79/1 55/90/1 +f 64/91/2 57/92/2 59/93/2 62/94/2 +f 36/38/1 35/37/1 39/40/1 40/39/1 +f 61/95/4 62/94/4 59/93/4 60/96/4 +f 58/97/6 63/98/6 61/95/6 60/96/6 +f 58/99/1 57/92/1 64/91/1 63/100/1 +f 70/47/5 66/50/5 68/101/5 72/102/5 +f 68/101/4 67/103/4 71/104/4 72/102/4 +f 66/105/2 65/106/2 67/103/2 68/101/2 +f 65/49/3 69/48/3 71/107/3 67/108/3 +f 78/109/1 77/110/1 73/111/1 74/112/1 +f 78/109/5 74/112/5 76/113/5 80/114/5 +f 76/113/4 75/115/4 79/116/4 80/114/4 +f 74/117/2 73/118/2 75/115/2 76/113/2 +f 73/111/3 77/110/3 79/119/3 75/120/3 +f 88/3/3 84/2/3 82/121/3 86/122/3 +f 87/123/2 88/124/2 86/125/2 85/126/2 +f 96/45/3 92/44/3 90/127/3 94/128/3 +f 95/129/2 96/130/2 94/131/2 93/132/2 +f 93/132/4 94/131/4 90/133/4 89/134/4 +f 91/43/5 95/46/5 93/132/5 89/134/5 +f 6/135/1 5/22/1 1/21/1 2/136/1 +f 6/135/5 2/136/5 4/12/5 8/137/5 +f 4/12/4 3/11/4 7/138/4 8/137/4 +f 83/1/5 87/4/5 85/126/5 81/139/5 +f 85/126/4 86/125/4 82/140/4 81/139/4 +f 47/141/3 45/142/3 46/71/3 48/143/3 +f 58/99/3 60/144/3 59/145/3 57/146/3 +f 44/147/5 42/148/5 41/149/5 43/150/5 +f 64/151/5 62/152/5 61/95/5 63/153/5 diff --git a/mods/furniture/models/furniture_lantern.obj b/mods/furniture/models/furniture_lantern.obj new file mode 100644 index 0000000..c9e69c4 --- /dev/null +++ b/mods/furniture/models/furniture_lantern.obj @@ -0,0 +1,141 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Lantern_Cube.024 +v -0.250000 0.000000 0.250000 +v -0.250000 0.062500 0.250000 +v -0.250000 0.000000 -0.250000 +v -0.250000 0.062500 -0.250000 +v 0.250000 0.000000 0.250000 +v 0.250000 0.062500 0.250000 +v 0.250000 0.000000 -0.250000 +v 0.250000 0.062500 -0.250000 +v -0.250000 0.437500 0.250000 +v -0.250000 0.500000 0.250000 +v -0.250000 0.437500 -0.250000 +v -0.250000 0.500000 -0.250000 +v 0.250000 0.437500 0.250000 +v 0.250000 0.500000 0.250000 +v 0.250000 0.437500 -0.250000 +v 0.250000 0.500000 -0.250000 +v -0.187500 0.437500 -0.125000 +v -0.187500 0.437500 0.125000 +v 0.187500 0.062500 -0.125000 +v 0.187500 0.062500 0.125000 +v 0.187500 0.437500 0.125000 +v 0.187500 0.437500 -0.125000 +v 0.187500 0.437500 -0.187500 +v 0.187500 0.062500 -0.187500 +v 0.187500 0.437500 0.187500 +v 0.187500 0.062500 0.187500 +v -0.187500 0.437500 -0.187500 +v -0.187500 0.062500 -0.187500 +v -0.187500 0.437500 0.187500 +v -0.187500 0.062500 0.125000 +v -0.187500 0.062500 0.187500 +v -0.187500 0.062500 -0.125000 +v 0.125000 0.437500 0.187500 +v -0.125000 0.437500 0.187500 +v -0.125000 0.062500 0.187500 +v 0.125000 0.062500 0.187500 +v -0.125000 0.437500 -0.187500 +v 0.125000 0.437500 -0.187500 +v 0.125000 0.062500 -0.187500 +v -0.125000 0.062500 -0.187500 +v -0.125000 0.062500 0.125000 +v -0.125000 0.437500 0.125000 +v -0.125000 0.062500 -0.125000 +v -0.125000 0.437500 -0.125000 +v 0.125000 0.062500 0.125000 +v 0.125000 0.437500 0.125000 +v 0.125000 0.062500 -0.125000 +v 0.125000 0.437500 -0.125000 +vt 0.968750 0.437500 +vt 0.968750 0.468750 +vt 0.718750 0.468750 +vt 0.718750 0.437500 +vt 0.687500 0.468750 +vt 0.718750 0.718750 +vt 0.687500 0.718750 +vt 0.718750 0.750000 +vt 0.968750 0.718750 +vt 0.968750 0.750000 +vt 1.000000 0.718750 +vt 1.000000 0.468750 +vt 0.718750 1.000000 +vt 0.968750 1.000000 +vt 0.968750 0.031250 +vt 1.000000 0.031250 +vt 1.000000 0.281250 +vt 0.968750 0.281250 +vt 0.968750 0.312500 +vt 0.718750 0.312500 +vt 0.718750 0.281250 +vt 0.687500 0.281250 +vt 0.687500 0.031250 +vt 0.718750 0.031250 +vt 0.718750 0.000000 +vt 0.968750 0.000000 +vt 0.000000 0.937500 +vt 0.187500 0.937500 +vt 0.187500 0.968750 +vt 0.000000 0.968750 +vt 0.000000 0.859375 +vt 0.187500 0.859375 +vt 0.187500 0.890625 +vt 0.000000 0.890625 +vt 0.000000 0.781250 +vt 0.187500 0.781250 +vt 0.187500 0.812500 +vt 0.000000 0.812500 +vt 0.000000 0.703125 +vt 0.187500 0.703125 +vt 0.187500 0.734375 +vt 0.000000 0.734375 +vt 0.187500 1.000000 +vt 0.000000 1.000000 +vt 0.187500 0.921875 +vt 0.000000 0.921875 +vt 0.187500 0.765625 +vt 0.000000 0.765625 +vt 0.187500 0.843750 +vt 0.000000 0.843750 +vt 0.500000 -0.000000 +vt 0.500000 0.187500 +vt 0.375000 0.187500 +vt 0.375000 0.000000 +vt 0.250000 0.187500 +vt 0.250000 0.000000 +vt 0.125000 0.187500 +vt 0.125000 0.000000 +vt 0.000000 0.187500 +vt 0.000000 0.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/8/5 5/10/5 1/14/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 9/15/1 10/16/1 12/17/1 11/18/1 +f 11/18/2 12/19/2 16/20/2 15/21/2 +f 15/21/3 16/22/3 14/23/3 13/24/3 +f 13/24/4 14/25/4 10/26/4 9/15/4 +f 11/18/5 15/21/5 13/24/5 9/15/5 +f 35/27/4 34/28/4 29/29/4 31/30/4 +f 39/31/2 38/32/2 23/33/2 24/34/2 +f 20/35/3 21/36/3 25/37/3 26/38/3 +f 32/39/1 17/40/1 27/41/1 28/42/1 +f 31/30/1 29/29/1 18/43/1 30/44/1 +f 24/34/3 23/33/3 22/45/3 19/46/3 +f 28/42/2 27/41/2 37/47/2 40/48/2 +f 26/38/4 25/37/4 33/49/4 36/50/4 +f 41/51/1 42/52/1 44/53/1 43/54/1 +f 43/54/2 44/53/2 48/55/2 47/56/2 +f 47/56/3 48/55/3 46/57/3 45/58/3 +f 45/58/4 46/57/4 42/59/4 41/60/4 diff --git a/mods/furniture/models/furniture_lectern.obj b/mods/furniture/models/furniture_lectern.obj new file mode 100644 index 0000000..067c514 --- /dev/null +++ b/mods/furniture/models/furniture_lectern.obj @@ -0,0 +1,230 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Lectern_Cube.012 +v 0.000000 0.437473 0.234923 +v -0.062500 0.470509 0.222899 +v -0.125000 0.470509 0.222899 +v -0.187500 0.466838 0.224235 +v -0.250000 0.437473 0.234923 +v 0.250000 0.437473 0.234923 +v -0.250000 0.266463 -0.234923 +v 0.250000 0.266463 -0.234923 +v 0.062500 0.312500 -0.062500 +v -0.062500 0.312500 -0.062500 +v 0.062500 0.312500 0.062500 +v -0.062500 0.312500 0.062500 +v 0.062500 -0.375000 -0.062500 +v -0.062500 -0.375000 -0.062500 +v 0.062500 -0.375000 0.062500 +v -0.062500 -0.375000 0.062500 +v 0.062500 -0.500000 0.312500 +v 0.062500 -0.375000 0.312500 +v -0.062500 -0.500000 0.312500 +v -0.062500 -0.375000 0.312500 +v 0.062500 -0.500000 -0.312500 +v 0.062500 -0.375000 -0.312500 +v -0.062500 -0.500000 -0.312500 +v -0.062500 -0.375000 -0.312500 +v 0.312500 0.186356 -0.272278 +v 0.312500 0.245087 -0.293654 +v 0.312500 0.400118 0.315030 +v 0.312500 0.458849 0.293654 +v -0.312500 0.186356 -0.272278 +v -0.312500 0.245087 -0.293654 +v -0.312500 0.400118 0.315030 +v -0.312500 0.458849 0.293654 +v 0.312500 0.207732 -0.213547 +v 0.312500 0.266463 -0.234923 +v -0.312500 0.207732 -0.213547 +v -0.312500 0.266463 -0.234923 +v -0.312500 0.325194 -0.256299 +v -0.312500 0.303817 -0.315030 +v 0.312500 0.303817 -0.315030 +v 0.312500 0.325194 -0.256299 +v 0.062500 0.470509 0.222899 +v 0.125000 0.470509 0.222899 +v 0.187500 0.466838 0.224235 +v 0.187500 0.295828 -0.245611 +v 0.125000 0.299499 -0.246947 +v 0.062500 0.299499 -0.246947 +v -0.000000 0.266463 -0.234923 +v -0.062500 0.299499 -0.246947 +v -0.125000 0.299499 -0.246947 +v -0.187500 0.295828 -0.245611 +v -0.062500 0.437510 0.234910 +v -0.125000 0.437510 0.234910 +v -0.187500 0.437510 0.234910 +v 0.062500 0.437510 0.234910 +v 0.125000 0.437510 0.234910 +v 0.187500 0.437510 0.234910 +v -0.312500 -0.500000 0.062500 +v -0.312500 -0.375000 0.062500 +v -0.312500 -0.500000 -0.062500 +v -0.312500 -0.375000 -0.062500 +v 0.312500 -0.500000 0.062500 +v 0.312500 -0.375000 0.062500 +v 0.312500 -0.500000 -0.062500 +v 0.312500 -0.375000 -0.062500 +vt 0.093750 0.750000 +vt 0.125000 0.750000 +vt 0.125000 1.000000 +vt 0.093750 1.000000 +vt 0.062500 0.750000 +vt 0.062500 1.000000 +vt 0.031250 0.750000 +vt 0.031250 1.000000 +vt -0.000000 0.750000 +vt -0.000000 1.000000 +vt 0.312500 0.625000 +vt 0.375000 0.625000 +vt 0.375000 0.968750 +vt 0.312500 0.968750 +vt 0.218750 0.750000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.218750 1.000000 +vt 0.437500 0.625000 +vt 0.437500 0.968750 +vt 0.718750 0.562500 +vt 0.718750 0.625000 +vt 0.656250 0.625000 +vt 0.656250 0.562500 +vt 0.562500 0.968750 +vt 0.500000 0.968750 +vt 0.500000 0.625000 +vt 0.562500 0.625000 +vt 0.593750 0.625000 +vt 0.656250 0.937500 +vt 0.593750 0.937500 +vt 0.656250 1.000000 +vt 0.718750 0.937500 +vt 0.718750 1.000000 +vt 0.781250 0.937500 +vt 0.781250 0.625000 +vt 0.906250 0.031250 +vt 0.875000 0.031250 +vt 0.875000 0.312500 +vt 0.906250 0.312500 +vt 0.031250 0.312500 +vt 0.000000 0.312500 +vt 0.000000 0.000000 +vt 0.031250 0.000000 +vt 1.000000 0.031250 +vt 0.968750 0.031250 +vt 0.968750 0.000000 +vt 1.000000 0.000000 +vt 0.343750 0.000000 +vt 0.375000 0.000000 +vt 0.375000 0.312500 +vt 0.343750 0.312500 +vt 0.937500 0.031250 +vt 0.937500 0.000000 +vt 0.312500 0.312500 +vt 0.312500 0.000000 +vt 0.781250 0.000000 +vt 0.781250 0.312500 +vt 0.500000 0.312500 +vt 0.500000 0.000000 +vt 1.000000 0.312500 +vt 0.968750 0.312500 +vt 0.906250 0.000000 +vt 0.875000 0.000000 +vt 0.468750 0.000000 +vt 0.468750 0.312500 +vt 0.437500 0.312500 +vt 0.437500 0.000000 +vt 0.843750 0.000000 +vt 0.843750 0.031250 +vt 0.406250 0.000000 +vt 0.406250 0.312500 +vt 0.156250 0.750000 +vt 0.156250 1.000000 +vt 0.187500 0.750000 +vt 0.187500 1.000000 +vt 0.156250 0.734375 +vt 0.187500 0.734375 +vt 0.187500 0.750000 +vt 0.156250 0.750000 +vt 0.031250 0.734375 +vt 0.062500 0.734375 +vt 0.062500 0.750000 +vt 0.031250 0.750000 +vt 0.218750 0.734375 +vt 0.218750 0.750000 +vt 0.093750 0.734375 +vt 0.093750 0.750000 +vt 0.125000 0.750000 +vt 0.000000 0.750000 +vt 0.250000 0.750000 +vt 0.937500 0.562500 +vt 0.937500 0.625000 +vt 0.875000 0.625000 +vt 0.875000 0.562500 +vt 0.812500 0.625000 +vt 0.875000 0.937500 +vt 0.812500 0.937500 +vt 0.875000 1.000000 +vt 0.937500 0.937500 +vt 0.937500 1.000000 +vt 1.000000 0.937500 +vt 1.000000 0.625000 +vn -0.4903 0.8190 -0.2981 +vn 0.0000 0.9397 -0.3420 +vn 0.0624 0.9379 -0.3414 +vn 0.4472 0.8405 -0.3059 +vn 1.0000 -0.0000 -0.0000 +vn -0.4472 0.8405 -0.3059 +vn 0.0000 -0.0000 1.0000 +vn -0.0000 0.0000 -1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.3420 0.9397 +vn -0.0000 -0.3420 -0.9397 +vn 0.0000 -0.9397 0.3420 +vn 0.4903 0.8190 -0.2981 +vn -0.0624 0.9379 -0.3414 +s off +f 46/1/1 47/2/1 1/3/1 41/4/1 +f 45/5/2 46/1/2 41/4/2 42/6/2 +f 44/7/3 45/5/3 42/6/3 43/8/3 +f 8/9/4 44/7/4 43/8/4 6/10/4 +f 9/11/5 11/12/5 15/13/5 13/14/5 +f 50/15/6 7/16/6 5/17/6 4/18/6 +f 11/12/7 12/19/7 16/20/7 15/13/7 +f 17/21/7 18/22/7 20/23/7 19/24/7 +f 13/25/8 14/26/8 10/27/8 9/28/8 +f 16/20/9 12/19/9 10/27/9 14/26/9 +f 19/29/9 20/23/9 24/30/9 23/31/9 +f 23/32/8 24/30/8 22/33/8 21/34/8 +f 21/35/5 22/33/5 18/22/5 17/36/5 +f 24/30/10 20/23/10 18/22/10 22/33/10 +f 33/37/5 34/38/5 28/39/5 27/40/5 +f 27/41/11 28/42/11 32/43/11 31/44/11 +f 35/45/9 36/46/9 30/47/9 29/48/9 +f 29/49/12 30/50/12 26/51/12 25/52/12 +f 30/47/9 36/46/9 37/53/9 38/54/9 +f 33/55/13 27/41/13 31/44/13 35/56/13 +f 25/52/13 33/55/13 35/56/13 29/49/13 +f 32/57/2 28/58/2 34/59/2 36/60/2 +f 31/61/9 32/62/9 36/46/9 35/45/9 +f 25/63/5 26/64/5 34/38/5 33/37/5 +f 37/65/2 40/66/2 39/67/2 38/68/2 +f 36/60/11 34/59/11 40/66/11 37/65/11 +f 34/38/5 26/64/5 39/69/5 40/70/5 +f 26/51/12 30/50/12 38/71/12 39/72/12 +f 47/2/14 48/73/14 2/74/14 1/3/14 +f 48/73/2 49/75/2 3/76/2 2/74/2 +f 49/75/15 50/15/15 4/18/15 3/76/15 +f 2/77/11 3/78/11 52/79/11 51/80/11 +f 43/81/11 42/82/11 55/83/11 56/84/11 +f 3/78/11 4/85/11 53/86/11 52/79/11 +f 42/82/11 41/87/11 54/88/11 55/83/11 +f 41/87/11 1/89/11 54/88/11 +f 43/81/11 56/84/11 6/90/11 +f 2/77/11 51/80/11 1/89/11 +f 4/85/11 5/91/11 53/86/11 +f 57/92/9 58/93/9 60/94/9 59/95/9 +f 59/96/8 60/94/8 64/97/8 63/98/8 +f 63/99/5 64/97/5 62/100/5 61/101/5 +f 61/102/7 62/100/7 58/93/7 57/103/7 +f 64/97/10 60/94/10 58/93/10 62/100/10 diff --git a/mods/furniture/models/furniture_stool_short.obj b/mods/furniture/models/furniture_stool_short.obj new file mode 100644 index 0000000..c091597 --- /dev/null +++ b/mods/furniture/models/furniture_stool_short.obj @@ -0,0 +1,128 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Stool_short_Cube.002 +v -0.375000 -0.125000 0.375000 +v -0.375000 0.000000 0.375000 +v -0.375000 -0.125000 -0.375000 +v -0.375000 0.000000 -0.375000 +v 0.375000 -0.125000 0.375000 +v 0.375000 0.000000 0.375000 +v 0.375000 -0.125000 -0.375000 +v 0.375000 0.000000 -0.375000 +v -0.312500 -0.125000 0.312500 +v -0.312500 -0.125000 0.187500 +v -0.187500 -0.125000 0.312500 +v -0.187500 -0.125000 0.187500 +v -0.312500 -0.500000 0.187500 +v -0.312500 -0.500000 0.312500 +v -0.187500 -0.500000 0.187500 +v -0.187500 -0.500000 0.312500 +v -0.312500 -0.125000 -0.312500 +v -0.187500 -0.125000 -0.312500 +v -0.312500 -0.125000 -0.187500 +v -0.187500 -0.125000 -0.187500 +v -0.187500 -0.500000 -0.312500 +v -0.312500 -0.500000 -0.312500 +v -0.187500 -0.500000 -0.187500 +v -0.312500 -0.500000 -0.187500 +v 0.312500 -0.125000 -0.312500 +v 0.312500 -0.125000 -0.187500 +v 0.187500 -0.125000 -0.312500 +v 0.187500 -0.125000 -0.187500 +v 0.312500 -0.500000 -0.187500 +v 0.312500 -0.500000 -0.312500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.500000 -0.312500 +v 0.312500 -0.125000 0.312500 +v 0.187500 -0.125000 0.312500 +v 0.312500 -0.125000 0.187500 +v 0.187500 -0.125000 0.187500 +v 0.187500 -0.500000 0.312500 +v 0.312500 -0.500000 0.312500 +v 0.187500 -0.500000 0.187500 +v 0.312500 -0.500000 0.187500 +vt 0.500000 0.937500 +vt 0.437500 0.937500 +vt 0.437500 0.562500 +vt 0.500000 0.562500 +vt 0.437500 0.500000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.000000 0.562500 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.437500 1.000000 +vt 0.437500 0.562500 +vt 0.062500 0.562500 +vt 0.062500 0.937500 +vt 0.437500 0.937500 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.187500 +vt 0.000000 0.187500 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.250000 0.187500 +vt 0.250000 0.000000 +vt 0.500000 0.187500 +vt 0.437500 0.187500 +vt 0.437500 0.000000 +vt 0.500000 0.000000 +vt 0.375000 0.187500 +vt 0.312500 0.187500 +vt 0.312500 0.000000 +vt 0.375000 0.000000 +vt 0.562500 0.187500 +vt 0.562500 0.000000 +vt 0.187500 0.406250 +vt 0.125000 0.406250 +vt 0.125000 0.218750 +vt 0.187500 0.218750 +vt 0.062500 0.406250 +vt 0.000000 0.406250 +vt 0.000000 0.218750 +vt 0.062500 0.218750 +vt 0.250000 0.406250 +vt 0.250000 0.218750 +vt 0.500000 0.406250 +vt 0.437500 0.406250 +vt 0.437500 0.218750 +vt 0.500000 0.218750 +vt 0.375000 0.406250 +vt 0.312500 0.406250 +vt 0.312500 0.218750 +vt 0.375000 0.218750 +vt 0.562500 0.406250 +vt 0.562500 0.218750 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 11/17/4 9/18/4 14/19/4 16/20/4 +f 10/21/2 12/22/2 15/23/2 13/24/2 +f 12/25/3 11/17/3 16/20/3 15/26/3 +f 9/18/1 10/21/1 13/24/1 14/19/1 +f 19/27/1 17/28/1 22/29/1 24/30/1 +f 18/31/3 20/32/3 23/33/3 21/34/3 +f 20/35/4 19/27/4 24/30/4 23/36/4 +f 17/28/2 18/31/2 21/34/2 22/29/2 +f 27/37/2 25/38/2 30/39/2 32/40/2 +f 26/41/4 28/42/4 31/43/4 29/44/4 +f 28/45/1 27/37/1 32/40/1 31/46/1 +f 25/38/3 26/41/3 29/44/3 30/39/3 +f 35/47/3 33/48/3 38/49/3 40/50/3 +f 34/51/1 36/52/1 39/53/1 37/54/1 +f 36/55/2 35/47/2 40/50/2 39/56/2 +f 33/48/4 34/51/4 37/54/4 38/49/4 diff --git a/mods/furniture/models/furniture_stool_short_cushion.obj b/mods/furniture/models/furniture_stool_short_cushion.obj new file mode 100644 index 0000000..eef0b65 --- /dev/null +++ b/mods/furniture/models/furniture_stool_short_cushion.obj @@ -0,0 +1,155 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Stool_short_Cube.002 +v -0.375000 -0.125000 0.375000 +v -0.375000 0.000000 0.375000 +v -0.375000 -0.125000 -0.375000 +v -0.375000 0.000000 -0.375000 +v 0.375000 -0.125000 0.375000 +v 0.375000 0.000000 0.375000 +v 0.375000 -0.125000 -0.375000 +v 0.375000 0.000000 -0.375000 +v -0.312500 -0.125000 0.312500 +v -0.312500 -0.125000 0.187500 +v -0.187500 -0.125000 0.312500 +v -0.187500 -0.125000 0.187500 +v -0.312500 -0.500000 0.187500 +v -0.312500 -0.500000 0.312500 +v -0.187500 -0.500000 0.187500 +v -0.187500 -0.500000 0.312500 +v -0.312500 -0.125000 -0.312500 +v -0.187500 -0.125000 -0.312500 +v -0.312500 -0.125000 -0.187500 +v -0.187500 -0.125000 -0.187500 +v -0.187500 -0.500000 -0.312500 +v -0.312500 -0.500000 -0.312500 +v -0.187500 -0.500000 -0.187500 +v -0.312500 -0.500000 -0.187500 +v 0.312500 -0.125000 -0.312500 +v 0.312500 -0.125000 -0.187500 +v 0.187500 -0.125000 -0.312500 +v 0.187500 -0.125000 -0.187500 +v 0.312500 -0.500000 -0.187500 +v 0.312500 -0.500000 -0.312500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.500000 -0.312500 +v 0.312500 -0.125000 0.312500 +v 0.187500 -0.125000 0.312500 +v 0.312500 -0.125000 0.187500 +v 0.187500 -0.125000 0.187500 +v 0.187500 -0.500000 0.312500 +v 0.312500 -0.500000 0.312500 +v 0.187500 -0.500000 0.187500 +v 0.312500 -0.500000 0.187500 +v -0.312500 0.000000 0.312500 +v -0.312500 0.031250 0.312500 +v -0.312500 0.000000 -0.312500 +v -0.312500 0.031250 -0.312500 +v 0.312500 0.000000 0.312500 +v 0.312500 0.031250 0.312500 +v 0.312500 0.000000 -0.312500 +v 0.312500 0.031250 -0.312500 +vt 0.500000 0.937500 +vt 0.437500 0.937500 +vt 0.437500 0.562500 +vt 0.500000 0.562500 +vt 0.437500 0.500000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.000000 0.562500 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.437500 1.000000 +vt 0.437500 0.562500 +vt 0.062500 0.562500 +vt 0.062500 0.937500 +vt 0.437500 0.937500 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.187500 +vt 0.000000 0.187500 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.250000 0.187500 +vt 0.250000 0.000000 +vt 0.500000 0.187500 +vt 0.437500 0.187500 +vt 0.437500 0.000000 +vt 0.500000 0.000000 +vt 0.375000 0.187500 +vt 0.312500 0.187500 +vt 0.312500 0.000000 +vt 0.375000 0.000000 +vt 0.562500 0.187500 +vt 0.562500 0.000000 +vt 0.187500 0.406250 +vt 0.125000 0.406250 +vt 0.125000 0.218750 +vt 0.187500 0.218750 +vt 0.062500 0.406250 +vt 0.000000 0.406250 +vt 0.000000 0.218750 +vt 0.062500 0.218750 +vt 0.250000 0.406250 +vt 0.250000 0.218750 +vt 0.500000 0.406250 +vt 0.437500 0.406250 +vt 0.437500 0.218750 +vt 0.500000 0.218750 +vt 0.375000 0.406250 +vt 0.312500 0.406250 +vt 0.312500 0.218750 +vt 0.375000 0.218750 +vt 0.562500 0.406250 +vt 0.562500 0.218750 +vt 1.000000 0.954545 +vt 0.954545 0.954545 +vt 0.954545 0.045455 +vt 1.000000 0.045455 +vt 0.954545 0.000000 +vt 0.045455 0.045455 +vt 0.045455 0.000000 +vt 0.000000 0.045455 +vt 0.045455 0.954545 +vt 0.000000 0.954545 +vt 0.045455 1.000000 +vt 0.954545 1.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +g Stool_short_Cube.002_Stool_short +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 11/17/4 9/18/4 14/19/4 16/20/4 +f 10/21/2 12/22/2 15/23/2 13/24/2 +f 12/25/3 11/17/3 16/20/3 15/26/3 +f 9/18/1 10/21/1 13/24/1 14/19/1 +f 19/27/1 17/28/1 22/29/1 24/30/1 +f 18/31/3 20/32/3 23/33/3 21/34/3 +f 20/35/4 19/27/4 24/30/4 23/36/4 +f 17/28/2 18/31/2 21/34/2 22/29/2 +f 27/37/2 25/38/2 30/39/2 32/40/2 +f 26/41/4 28/42/4 31/43/4 29/44/4 +f 28/45/1 27/37/1 32/40/1 31/46/1 +f 25/38/3 26/41/3 29/44/3 30/39/3 +f 35/47/3 33/48/3 38/49/3 40/50/3 +f 34/51/1 36/52/1 39/53/1 37/54/1 +f 36/55/2 35/47/2 40/50/2 39/56/2 +f 33/48/4 34/51/4 37/54/4 38/49/4 +g Stool_short_Cube.002_Cushion +f 41/57/1 42/58/1 44/59/1 43/60/1 +f 43/61/2 44/59/2 48/62/2 47/63/2 +f 47/64/3 48/62/3 46/65/3 45/66/3 +f 45/67/4 46/65/4 42/58/4 41/68/4 +f 48/62/6 44/59/6 42/58/6 46/65/6 diff --git a/mods/furniture/models/furniture_stool_tall.obj b/mods/furniture/models/furniture_stool_tall.obj new file mode 100644 index 0000000..0803572 --- /dev/null +++ b/mods/furniture/models/furniture_stool_tall.obj @@ -0,0 +1,128 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Stool_tall_Cube.003 +v -0.375000 0.375000 0.375000 +v -0.375000 0.500000 0.375000 +v -0.375000 0.375000 -0.375000 +v -0.375000 0.500000 -0.375000 +v 0.375000 0.375000 0.375000 +v 0.375000 0.500000 0.375000 +v 0.375000 0.375000 -0.375000 +v 0.375000 0.500000 -0.375000 +v -0.312500 0.375000 0.312500 +v -0.312500 0.375000 0.187500 +v -0.187500 0.375000 0.312500 +v -0.187500 0.375000 0.187500 +v -0.312500 -0.500000 0.187500 +v -0.312500 -0.500000 0.312500 +v -0.187500 -0.500000 0.187500 +v -0.187500 -0.500000 0.312500 +v -0.312500 0.375000 -0.312500 +v -0.187500 0.375000 -0.312500 +v -0.312500 0.375000 -0.187500 +v -0.187500 0.375000 -0.187500 +v -0.187500 -0.500000 -0.312500 +v -0.312500 -0.500000 -0.312500 +v -0.187500 -0.500000 -0.187500 +v -0.312500 -0.500000 -0.187500 +v 0.312500 0.375000 -0.312500 +v 0.312500 0.375000 -0.187500 +v 0.187500 0.375000 -0.312500 +v 0.187500 0.375000 -0.187500 +v 0.312500 -0.500000 -0.187500 +v 0.312500 -0.500000 -0.312500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.500000 -0.312500 +v 0.312500 0.375000 0.312500 +v 0.187500 0.375000 0.312500 +v 0.312500 0.375000 0.187500 +v 0.187500 0.375000 0.187500 +v 0.187500 -0.500000 0.312500 +v 0.312500 -0.500000 0.312500 +v 0.187500 -0.500000 0.187500 +v 0.312500 -0.500000 0.187500 +vt 0.500000 0.937500 +vt 0.437500 0.937500 +vt 0.437500 0.562500 +vt 0.500000 0.562500 +vt 0.437500 0.500000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.000000 0.562500 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.437500 1.000000 +vt 0.437500 0.562500 +vt 0.062500 0.562500 +vt 0.062500 0.937500 +vt 0.437500 0.937500 +vt 0.187500 0.437500 +vt 0.125000 0.437500 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.437500 +vt 0.000000 0.437500 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.250000 0.437500 +vt 0.250000 0.000000 +vt 0.937500 0.437500 +vt 0.875000 0.437500 +vt 0.875000 0.000000 +vt 0.937500 0.000000 +vt 0.812500 0.437500 +vt 0.750000 0.437500 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 1.000000 0.437500 +vt 1.000000 0.000000 +vt 0.937500 1.000000 +vt 0.875000 1.000000 +vt 0.875000 0.562500 +vt 0.937500 0.562500 +vt 0.812500 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.562500 +vt 0.812500 0.562500 +vt 1.000000 1.000000 +vt 1.000000 0.562500 +vt 0.562500 0.437500 +vt 0.500000 0.437500 +vt 0.500000 0.000000 +vt 0.562500 0.000000 +vt 0.437500 0.437500 +vt 0.375000 0.437500 +vt 0.375000 0.000000 +vt 0.437500 0.000000 +vt 0.625000 0.437500 +vt 0.625000 0.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 11/17/4 9/18/4 14/19/4 16/20/4 +f 10/21/2 12/22/2 15/23/2 13/24/2 +f 12/25/3 11/17/3 16/20/3 15/26/3 +f 9/18/1 10/21/1 13/24/1 14/19/1 +f 19/27/1 17/28/1 22/29/1 24/30/1 +f 18/31/3 20/32/3 23/33/3 21/34/3 +f 20/35/4 19/27/4 24/30/4 23/36/4 +f 17/28/2 18/31/2 21/34/2 22/29/2 +f 27/37/2 25/38/2 30/39/2 32/40/2 +f 26/41/4 28/42/4 31/43/4 29/44/4 +f 28/45/1 27/37/1 32/40/1 31/46/1 +f 25/38/3 26/41/3 29/44/3 30/39/3 +f 35/47/3 33/48/3 38/49/3 40/50/3 +f 34/51/1 36/52/1 39/53/1 37/54/1 +f 36/55/2 35/47/2 40/50/2 39/56/2 +f 33/48/4 34/51/4 37/54/4 38/49/4 diff --git a/mods/furniture/models/furniture_stool_tall_cushion.obj b/mods/furniture/models/furniture_stool_tall_cushion.obj new file mode 100644 index 0000000..491bd87 --- /dev/null +++ b/mods/furniture/models/furniture_stool_tall_cushion.obj @@ -0,0 +1,155 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Seating_Cushion_Cube.005 +v -0.312500 0.500000 0.312500 +v -0.312500 0.531250 0.312500 +v -0.312500 0.500000 -0.312500 +v -0.312500 0.531250 -0.312500 +v 0.312500 0.500000 0.312500 +v 0.312500 0.531250 0.312500 +v 0.312500 0.500000 -0.312500 +v 0.312500 0.531250 -0.312500 +v -0.375000 0.375000 0.375000 +v -0.375000 0.500000 0.375000 +v -0.375000 0.375000 -0.375000 +v -0.375000 0.500000 -0.375000 +v 0.375000 0.375000 0.375000 +v 0.375000 0.500000 0.375000 +v 0.375000 0.375000 -0.375000 +v 0.375000 0.500000 -0.375000 +v -0.312500 0.375000 0.312500 +v -0.312500 0.375000 0.187500 +v -0.187500 0.375000 0.312500 +v -0.187500 0.375000 0.187500 +v -0.312500 -0.500000 0.187500 +v -0.312500 -0.500000 0.312500 +v -0.187500 -0.500000 0.187500 +v -0.187500 -0.500000 0.312500 +v -0.312500 0.375000 -0.312500 +v -0.187500 0.375000 -0.312500 +v -0.312500 0.375000 -0.187500 +v -0.187500 0.375000 -0.187500 +v -0.187500 -0.500000 -0.312500 +v -0.312500 -0.500000 -0.312500 +v -0.187500 -0.500000 -0.187500 +v -0.312500 -0.500000 -0.187500 +v 0.312500 0.375000 -0.312500 +v 0.312500 0.375000 -0.187500 +v 0.187500 0.375000 -0.312500 +v 0.187500 0.375000 -0.187500 +v 0.312500 -0.500000 -0.187500 +v 0.312500 -0.500000 -0.312500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.500000 -0.312500 +v 0.312500 0.375000 0.312500 +v 0.187500 0.375000 0.312500 +v 0.312500 0.375000 0.187500 +v 0.187500 0.375000 0.187500 +v 0.187500 -0.500000 0.312500 +v 0.312500 -0.500000 0.312500 +v 0.187500 -0.500000 0.187500 +v 0.312500 -0.500000 0.187500 +vt 0.500000 0.937500 +vt 0.437500 0.937500 +vt 0.437500 0.562500 +vt 0.500000 0.562500 +vt 0.437500 0.500000 +vt 0.062500 0.562500 +vt 0.062500 0.500000 +vt 0.000000 0.562500 +vt 0.062500 0.937500 +vt 0.000000 0.937500 +vt 0.062500 1.000000 +vt 0.437500 1.000000 +vt 0.437500 0.562500 +vt 0.062500 0.562500 +vt 0.062500 0.937500 +vt 0.437500 0.937500 +vt 0.187500 0.437500 +vt 0.125000 0.437500 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.437500 +vt 0.000000 0.437500 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.250000 0.437500 +vt 0.250000 0.000000 +vt 0.937500 0.437500 +vt 0.875000 0.437500 +vt 0.875000 0.000000 +vt 0.937500 0.000000 +vt 0.812500 0.437500 +vt 0.750000 0.437500 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 1.000000 0.437500 +vt 1.000000 0.000000 +vt 0.937500 1.000000 +vt 0.875000 1.000000 +vt 0.875000 0.562500 +vt 0.937500 0.562500 +vt 0.812500 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.562500 +vt 0.812500 0.562500 +vt 1.000000 1.000000 +vt 1.000000 0.562500 +vt 0.562500 0.437500 +vt 0.500000 0.437500 +vt 0.500000 0.000000 +vt 0.562500 0.000000 +vt 0.437500 0.437500 +vt 0.375000 0.437500 +vt 0.375000 0.000000 +vt 0.437500 0.000000 +vt 0.625000 0.437500 +vt 0.625000 0.000000 +vt 1.000000 0.954545 +vt 0.954545 0.954545 +vt 0.954545 0.045455 +vt 1.000000 0.045455 +vt 0.954545 0.000000 +vt 0.045455 0.045455 +vt 0.045455 0.000000 +vt 0.000000 0.045455 +vt 0.045455 0.954545 +vt 0.000000 0.954545 +vt 0.045455 1.000000 +vt 0.954545 1.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +g Seating_Cushion_Cube.005_Stool_tall +s off +f 9/1/1 10/2/1 12/3/1 11/4/1 +f 11/5/2 12/3/2 16/6/2 15/7/2 +f 15/8/3 16/6/3 14/9/3 13/10/3 +f 13/11/4 14/9/4 10/2/4 9/12/4 +f 11/13/5 15/14/5 13/15/5 9/16/5 +f 16/6/6 12/3/6 10/2/6 14/9/6 +f 19/17/4 17/18/4 22/19/4 24/20/4 +f 18/21/2 20/22/2 23/23/2 21/24/2 +f 20/25/3 19/17/3 24/20/3 23/26/3 +f 17/18/1 18/21/1 21/24/1 22/19/1 +f 27/27/1 25/28/1 30/29/1 32/30/1 +f 26/31/3 28/32/3 31/33/3 29/34/3 +f 28/35/4 27/27/4 32/30/4 31/36/4 +f 25/28/2 26/31/2 29/34/2 30/29/2 +f 35/37/2 33/38/2 38/39/2 40/40/2 +f 34/41/4 36/42/4 39/43/4 37/44/4 +f 36/45/1 35/37/1 40/40/1 39/46/1 +f 33/38/3 34/41/3 37/44/3 38/39/3 +f 43/47/3 41/48/3 46/49/3 48/50/3 +f 42/51/1 44/52/1 47/53/1 45/54/1 +f 44/55/2 43/47/2 48/50/2 47/56/2 +f 41/48/4 42/51/4 45/54/4 46/49/4 +g Seating_Cushion_Cube.005_Cushion +f 1/57/1 2/58/1 4/59/1 3/60/1 +f 3/61/2 4/59/2 8/62/2 7/63/2 +f 7/64/3 8/62/3 6/65/3 5/66/3 +f 5/67/4 6/65/4 2/58/4 1/68/4 +f 8/62/6 4/59/6 2/58/6 6/65/6 diff --git a/mods/furniture/models/furniture_table_basic.obj b/mods/furniture/models/furniture_table_basic.obj new file mode 100644 index 0000000..1cf03fe --- /dev/null +++ b/mods/furniture/models/furniture_table_basic.obj @@ -0,0 +1,238 @@ +# Blender v2.82 (sub 7) OBJ File: 'furniture.blend' +# www.blender.org +o Table_Cube.011 +v -1.500000 0.375000 0.500000 +v -1.500000 0.500000 0.500000 +v -1.500000 0.375000 -0.500000 +v -1.500000 0.500000 -0.500000 +v 0.500000 0.375000 0.500000 +v 0.500000 0.500000 0.500000 +v 0.500000 0.375000 -0.500000 +v 0.500000 0.500000 -0.500000 +v -1.375000 0.375000 0.062500 +v -1.375000 0.375000 -0.062500 +v -1.375000 0.250000 0.062500 +v -1.375000 0.250000 -0.062500 +v 0.375000 0.375000 0.062500 +v 0.375000 0.375000 -0.062500 +v 0.375000 0.250000 0.062500 +v 0.375000 0.250000 -0.062500 +v -0.062500 -0.375000 -0.062500 +v 0.062500 -0.375000 -0.062500 +v -0.062500 -0.375000 0.062500 +v 0.062500 -0.375000 0.062500 +v -0.062500 0.250000 -0.062500 +v 0.062500 0.250000 -0.062500 +v -0.062500 0.250000 0.062500 +v 0.062500 0.250000 0.062500 +v -1.062500 0.375000 -0.375000 +v -0.937500 0.375000 -0.375000 +v -1.062500 0.250000 -0.375000 +v -0.937500 0.250000 -0.375000 +v -1.062500 0.375000 0.375000 +v -0.937500 0.375000 0.375000 +v -1.062500 0.250000 0.375000 +v -0.937500 0.250000 0.375000 +v -1.062500 -0.375000 -0.062500 +v -0.937500 -0.375000 -0.062500 +v -1.062500 -0.375000 0.062500 +v -0.937500 -0.375000 0.062500 +v -1.062500 0.250000 -0.062500 +v -0.937500 0.250000 -0.062500 +v -1.062500 0.250000 0.062500 +v -0.937500 0.250000 0.062500 +v -0.062500 0.375000 -0.375000 +v 0.062500 0.375000 -0.375000 +v -0.062500 0.250000 -0.375000 +v 0.062500 0.250000 -0.375000 +v -0.062500 0.375000 0.375000 +v 0.062500 0.375000 0.375000 +v -0.062500 0.250000 0.375000 +v 0.062500 0.250000 0.375000 +v -1.375000 -0.500000 -0.062500 +v -1.375000 -0.500000 0.062500 +v -1.375000 -0.375000 -0.062500 +v -1.375000 -0.375000 0.062500 +v 0.375000 -0.500000 -0.062500 +v 0.375000 -0.500000 0.062500 +v 0.375000 -0.375000 -0.062500 +v 0.375000 -0.375000 0.062500 +v -1.062500 -0.500000 0.375000 +v -0.937500 -0.500000 0.375000 +v -1.062500 -0.375000 0.375000 +v -0.937500 -0.375000 0.375000 +v -1.062500 -0.500000 -0.375000 +v -0.937500 -0.500000 -0.375000 +v -1.062500 -0.375000 -0.375000 +v -0.937500 -0.375000 -0.375000 +v -0.062500 -0.500000 0.375000 +v 0.062500 -0.500000 0.375000 +v -0.062500 -0.375000 0.375000 +v 0.062500 -0.375000 0.375000 +v -0.062500 -0.500000 -0.375000 +v 0.062500 -0.500000 -0.375000 +v -0.062500 -0.375000 -0.375000 +v 0.062500 -0.375000 -0.375000 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.500000 1.000000 +vt 0.500000 0.937500 +vt 0.500000 1.000000 +vt 0.562500 1.000000 +vt 0.562500 0.000000 +vt 0.500000 0.000000 +vt 0.500000 0.062500 +vt 0.500000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.062500 +vt 1.000000 0.000000 +vt 0.953125 0.000000 +vt 0.953125 1.000000 +vt 1.000000 1.000000 +vt 0.953125 1.000000 +vt 0.953125 0.000000 +vt 0.562500 0.000000 +vt 0.562500 1.000000 +vt 0.125000 0.000000 +vt 0.062500 0.000000 +vt 0.062500 0.062500 +vt 0.125000 0.062500 +vt 0.062500 0.937500 +vt 0.125000 0.937500 +vt 0.062500 1.000000 +vt 0.125000 1.000000 +vt 0.187500 0.937500 +vt 0.187500 0.062500 +vt 0.000000 0.062500 +vt 0.000000 0.937500 +vt 0.500000 0.687500 +vt 0.437500 0.687500 +vt 0.437500 1.000000 +vt 0.500000 1.000000 +vt 0.312500 1.000000 +vt 0.375000 1.000000 +vt 0.375000 0.687500 +vt 0.312500 0.687500 +vt 0.250000 0.687500 +vt 0.250000 1.000000 +vt 0.156250 0.687500 +vt 0.218750 0.687500 +vt 0.218750 0.625000 +vt 0.156250 0.625000 +vt 0.218750 0.250000 +vt 0.156250 0.250000 +vt 0.218750 0.187500 +vt 0.156250 0.187500 +vt 0.093750 0.250000 +vt 0.093750 0.625000 +vt 0.281250 0.625000 +vt 0.281250 0.250000 +vt 0.406250 0.453125 +vt 0.343750 0.453125 +vt 0.343750 0.765625 +vt 0.406250 0.765625 +vt 0.218750 0.765625 +vt 0.281250 0.765625 +vt 0.281250 0.453125 +vt 0.218750 0.453125 +vt 0.156250 0.453125 +vt 0.156250 0.765625 +vt 0.234375 0.515625 +vt 0.296875 0.515625 +vt 0.296875 0.453125 +vt 0.234375 0.453125 +vt 0.296875 0.078125 +vt 0.234375 0.078125 +vt 0.296875 0.015625 +vt 0.234375 0.015625 +vt 0.171875 0.078125 +vt 0.171875 0.453125 +vt 0.359375 0.453125 +vt 0.359375 0.078125 +vt 0.375000 0.000000 +vt 0.312500 0.000000 +vt 0.312500 0.062500 +vt 0.375000 0.062500 +vt 0.312500 0.937500 +vt 0.375000 0.937500 +vt 0.312500 1.000000 +vt 0.375000 1.000000 +vt 0.437500 0.937500 +vt 0.437500 0.062500 +vt 0.250000 0.062500 +vt 0.250000 0.937500 +vt 0.140625 0.968750 +vt 0.203125 0.968750 +vt 0.203125 0.906250 +vt 0.140625 0.906250 +vt 0.203125 0.531250 +vt 0.140625 0.531250 +vt 0.203125 0.468750 +vt 0.140625 0.468750 +vt 0.078125 0.531250 +vt 0.078125 0.906250 +vt 0.265625 0.906250 +vt 0.265625 0.531250 +vt 0.328125 0.687500 +vt 0.390625 0.687500 +vt 0.390625 0.625000 +vt 0.328125 0.625000 +vt 0.390625 0.250000 +vt 0.328125 0.250000 +vt 0.390625 0.187500 +vt 0.328125 0.187500 +vt 0.265625 0.250000 +vt 0.265625 0.625000 +vt 0.453125 0.625000 +vt 0.453125 0.250000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 7/9/3 8/10/3 6/11/3 5/12/3 +f 5/13/4 6/14/4 2/15/4 1/16/4 +f 3/17/5 7/18/5 5/19/5 1/20/5 +f 8/10/6 4/3/6 2/2/6 6/11/6 +f 9/21/1 10/22/1 12/23/1 11/24/1 +f 11/24/5 12/23/5 16/25/5 15/26/5 +f 15/26/3 16/25/3 14/27/3 13/28/3 +f 11/24/4 15/26/4 13/29/4 9/30/4 +f 16/25/2 12/23/2 10/31/2 14/32/2 +f 19/33/4 20/34/4 24/35/4 23/36/4 +f 21/37/2 22/38/2 18/39/2 17/40/2 +f 19/41/1 23/42/1 21/37/1 17/40/1 +f 24/35/3 20/34/3 18/39/3 22/38/3 +f 25/43/2 26/44/2 28/45/2 27/46/2 +f 27/46/5 28/45/5 32/47/5 31/48/5 +f 31/48/4 32/47/4 30/49/4 29/50/4 +f 27/46/1 31/48/1 29/51/1 25/52/1 +f 32/47/3 28/45/3 26/53/3 30/54/3 +f 35/55/4 36/56/4 40/57/4 39/58/4 +f 37/59/2 38/60/2 34/61/2 33/62/2 +f 35/63/1 39/64/1 37/59/1 33/62/1 +f 40/57/3 36/56/3 34/61/3 38/60/3 +f 41/65/2 42/66/2 44/67/2 43/68/2 +f 43/68/5 44/67/5 48/69/5 47/70/5 +f 47/70/4 48/69/4 46/71/4 45/72/4 +f 43/68/1 47/70/1 45/73/1 41/74/1 +f 48/69/3 44/67/3 42/75/3 46/76/3 +f 49/77/1 50/78/1 52/79/1 51/80/1 +f 51/80/6 52/79/6 56/81/6 55/82/6 +f 55/82/3 56/81/3 54/83/3 53/84/3 +f 51/80/2 55/82/2 53/85/2 49/86/2 +f 56/81/4 52/79/4 50/87/4 54/88/4 +f 57/89/4 58/90/4 60/91/4 59/92/4 +f 59/92/6 60/91/6 64/93/6 63/94/6 +f 63/94/2 64/93/2 62/95/2 61/96/2 +f 59/92/1 63/94/1 61/97/1 57/98/1 +f 64/93/3 60/91/3 58/99/3 62/100/3 +f 65/101/4 66/102/4 68/103/4 67/104/4 +f 67/104/6 68/103/6 72/105/6 71/106/6 +f 71/106/2 72/105/2 70/107/2 69/108/2 +f 67/104/1 71/106/1 69/109/1 65/110/1 +f 72/105/3 68/103/3 66/111/3 70/112/3 diff --git a/mods/furniture/seating.lua b/mods/furniture/seating.lua new file mode 100644 index 0000000..f0a6c34 --- /dev/null +++ b/mods/furniture/seating.lua @@ -0,0 +1,310 @@ +minetest.register_node('furniture:stool_short', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Short stool', + drawtype = 'mesh', + mesh = 'furniture_stool_short.obj', + tiles = {'furniture_stool_short.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, 0, .375}, + }, + collision_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, 0, .375}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 + furniture.sit(pos, node, clicker, pointed_thing, false) + return itemstack + end +}) + +minetest.register_node('furniture:stool_tall', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Tall stool', + drawtype = 'mesh', + mesh = 'furniture_stool_tall.obj', + tiles = {'furniture_stool_tall.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, .5, .375}, + }, + collision_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, .5, .375}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + .5 + furniture.sit(pos, node, clicker, pointed_thing, false) + return itemstack + end +}) + +minetest.register_node('furniture:chair', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Chair', + drawtype = 'mesh', + mesh = 'furniture_chair.obj', + tiles = {'furniture_chair.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, 0, .375}, + }, + collision_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, 0, .375}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 + furniture.sit(pos, node, clicker, pointed_thing, true) + return itemstack + end +}) + +minetest.register_node('furniture:bench', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Bench', + drawtype = 'mesh', + mesh = 'furniture_bench.obj', + tiles = {'furniture_bench.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, 1.375, 0, .375}, + }, + collision_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, 1.375, 0, .375}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 + furniture.sit(pos, node, clicker, pointed_thing, false) + return itemstack + end, + after_place_node = function(pos, placer, itemstack) + if not epic.space_to_side(pos) then + minetest.remove_node(pos) + return itemstack + end + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + epic.remove_side_node(pos, oldnode) + end, + on_rotate = function(pos, node) + return false + end, +}) + +minetest.register_node('furniture:bench_with_back', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Bench with Back', + drawtype = 'mesh', + mesh = 'furniture_bench_with_back.obj', + tiles = {'furniture_bench.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {{-.375, -.5, -.375, 1.375, 0, .45}, + {-.375, 0, .275, 1.375, .5, .375}} + }, + collision_box = { + type = 'fixed', + fixed = {{-.375, -.5, -.375, 1.375, 0, .45}, + {-.375, 0, .275, 1.375, .5, .375}} + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 + furniture.sit(pos, node, clicker, pointed_thing, true) + return itemstack + end, + after_place_node = function(pos, placer, itemstack) + if not epic.space_to_side(pos) then + minetest.remove_node(pos) + return itemstack + end + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + epic.remove_side_node(pos, oldnode) + end, + on_rotate = function(pos, node) + return false + end, +}) + +minetest.register_node('furniture:bench_picnic', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Picnic Table', + drawtype = 'mesh', + mesh = 'furniture_bench_picnic.obj', + tiles = {'furniture_bench_picnic.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = { + {-.375, -.5, -.375, 1.375, 0, 1.375}, + {-.375, 0, -.0625, 1.375, .5, 1.0625} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {-.375, -.5, -.375, 1.375, 0, 1.375}, + {-.375, 0, -.0625, 1.375, .5, 1.0625} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 + furniture.sit(pos, node, clicker, pointed_thing, true) + return itemstack + end, + after_place_node = function(pos, placer, itemstack) + if not epic.space_to_side(pos) then + minetest.remove_node(pos) + return itemstack + end + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + epic.remove_side_node(pos, oldnode) + end, + on_rotate = function(pos, node) + return false + end, +}) + +---Cushioned items. Yay. :P +local dye_table = dye.dyes + +for i in ipairs(dye_table) do + local name = dye_table[i][1] + local desc = dye_table[i][2] + local hex = dye_table[i][3] + + minetest.register_node('furniture:stool_short_'..name, { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Short Stool with '..desc..' Cushion', + drawtype = 'mesh', + mesh = 'furniture_stool_short_cushion.obj', + tiles = {'furniture_stool_short.png', 'furniture_cushion_pad.png'}, + overlay_tiles = {'', {name = 'furniture_cushion_pad.png', color = hex}}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, 0, .375}, + }, + collision_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, 0, .375}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 + furniture.sit(pos, node, clicker, pointed_thing, false) + return itemstack + end + }) + + minetest.register_node('furniture:stool_tall_'..name, { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Tall Stool with '..desc..' Cushion', + drawtype = 'mesh', + mesh = 'furniture_stool_tall_cushion.obj', + tiles = {'furniture_stool_tall.png', 'furniture_cushion_pad.png'}, + overlay_tiles = {'', {name = 'furniture_cushion_pad.png', color = hex}}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, .5, .375}, + }, + collision_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, .5, .375}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + .5 + furniture.sit(pos, node, clicker, pointed_thing, false) + return itemstack + end + }) + + minetest.register_node('furniture:chair_'..name, { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Chair with '..desc..' Cushion', + drawtype = 'mesh', + mesh = 'furniture_chair_cushion.obj', + tiles = {'furniture_chair.png', 'furniture_cushion_pad.png'}, + overlay_tiles = {'', {name = 'furniture_cushion_pad.png', color = hex}}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, 0, .375}, + }, + collision_box = { + type = 'fixed', + fixed = {-.375, -.5, -.375, .375, 0, .375}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 + furniture.sit(pos, node, clicker, pointed_thing, true) + return itemstack + end + }) + + minetest.register_node('furniture:cushion_half_'..name, { + _doc_items_crafting = 'This is crafted in the Sewing Station.', + description = desc..' Half Cushion', + drawtype = 'nodebox', + tiles = {'furniture_cushion.png^[multiply:'..hex}, + paramtype = 'light', + node_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, 0, .5}, + }, + groups = {oddly_breakable_by_hand = 2, snappy=3, bouncy=50}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 + furniture.sit(pos, node, clicker, pointed_thing, false) + return itemstack + end + }) + + minetest.register_node('furniture:cushion_full_'..name, { + _doc_items_crafting = 'This is crafted in the Sewing Station.', + description = desc..' Full Cushion', + tiles = {'furniture_cushion.png^[multiply:'..hex}, + groups = {oddly_breakable_by_hand = 2, snappy=3, bouncy=50}, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + .5 + furniture.sit(pos, node, clicker, pointed_thing, false) + return itemstack + end + }) +end diff --git a/mods/furniture/stain.lua b/mods/furniture/stain.lua new file mode 100644 index 0000000..95347d2 --- /dev/null +++ b/mods/furniture/stain.lua @@ -0,0 +1,109 @@ +local function set_wear(itemstack, level, max_level) + local temp + if level == 0 then + temp = 0 + else + temp = 65536 - math.floor(level / max_level * 65535) + if temp > 65535 then temp = 65535 end + if temp < 1 then temp = 1 end + end + itemstack:set_wear(temp) +end + +local function get_wear(itemstack) + if itemstack:get_metadata() == "" then + return 30 + else + return tonumber(itemstack:get_metadata()) + end +end + +local stain_table = { + {'Golden Oak', '1', 32, '#cc7431'}, + {'Country Pine', '2', 64, '#b76126'}, + {'Cinnamon', '3', 96, '#9c4a1b'}, + {'Cherry', '4', 128, '#873a14'}, + {'Mahogany', '5', 160, '#712b0d'}, + {'Walnut', '6', 192, '#5b1e07'}, + {'Black', '7', 224, '#461404'} +} + +for i in ipairs (stain_table) do + local desc = stain_table[i][1] + local name = stain_table[i][2] + local indx = stain_table[i][3] + local colo = stain_table[i][4] + + minetest.register_tool('furniture:stain_brush'..name, { + description = desc..' Stain brush', + inventory_image = 'furniture_brush.png^(furniture_brush_overlay.png^[colorize:'..colo..':255)', + stack_max = 1, + wear_represents = 'content_level', + groups = {stain_brush=1}, + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= 'node' then return end + local player_name = user:get_player_name() + local pos = minetest.get_pointed_thing_position(pointed_thing) + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(user, 'protection_bypass') then + return + end + local node = minetest.get_node(pos) + if minetest.get_item_group(node.name, 'stainable') > 0 then + --local mod = string.sub(node.name, 1, 9) + --if mod == 'furniture' then + local fdir = node.param2 % 32 + local stain = get_wear(itemstack) + if stain == 0 then + itemstack:set_name('furniture:brush') + return itemstack end + if node.param2 == (fdir + indx) then + local player = user:get_player_name() + minetest.chat_send_player(player, "Already stained this color.") + return + elseif node.param2 >= (fdir + indx) then + local player = user:get_player_name() + minetest.chat_send_player(player, "You can only stain things darker.") + return end + minetest.swap_node(pos, {name = node.name, param2 = fdir + indx}) + stain = stain - 1 + itemstack:set_metadata(tostring(stain)) + set_wear(itemstack, stain, 30) + return itemstack + else + local player = user:get_player_name() + minetest.chat_send_player(player, "You can't stain that item.") + end + end, + }) +end + +minetest.register_tool('furniture:sanding', { + description = 'Sanding pad', + inventory_image = 'furniture_sanding.png', + stack_max = 1, + wear_represents = 'content_level', + on_use = function(itemstack, user, pointed_thing) + if pointed_thing.type ~= 'node' then return end + local player_name = user:get_player_name() + local pos = minetest.get_pointed_thing_position(pointed_thing) + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(user, 'protection_bypass') then + return + end + local node = minetest.get_node(pos) + if minetest.get_item_group(node.name, 'stainable') > 0 then + --local mod = string.sub(node.name, 1, 9) + --if mod == 'furniture' then + local fdir = node.param2 % 32 + if node.param2 == fdir then + local player = user:get_player_name() + minetest.chat_send_player(player, "Already sanded.") + return end + minetest.swap_node(pos, {name = node.name, param2 = fdir}) + itemstack:add_wear(65535 / 48) + return itemstack + else + local player = user:get_player_name() + minetest.chat_send_player(player, "You can't sand that item.") + end + end, +}) diff --git a/mods/furniture/storage.lua b/mods/furniture/storage.lua new file mode 100644 index 0000000..448c22c --- /dev/null +++ b/mods/furniture/storage.lua @@ -0,0 +1,513 @@ +minetest.register_node('furniture:chest_small', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Small Chest', + drawtype = 'mesh', + mesh = 'furniture_chest_small.obj', + tiles = {'furniture_chest_small.png'}, + overlay_tiles = {{name='furniture_chest_small_overlay.png', color='white'}}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.4, -.5, -.3, .4, .2, .4}, + }, + collision_box = { + type = 'fixed', + fixed = {-.4, -.5, -.3, .4, .2, .4}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string('formspec', furniture.storage_24_form(pos, '')) + local inv = meta:get_inventory() + inv:set_size('main', 24) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty('main') + end, + on_receive_fields = function(pos, formname, fields, sender) + local player_name = sender:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(sender, 'protection_bypass') then + return + end + local meta = minetest.get_meta(pos) + if fields ['save'] then + meta:set_string('infotext', fields.description) + meta:set_string('formspec', furniture.storage_24_form(pos, fields.description)) + elseif fields ['sort'] then + furniture.sort_inventory(meta:get_inventory()) + end + end, + allow_metadata_inventory_put = furniture.inv_take_put, + allow_metadata_inventory_take = furniture.inv_take_put, + allow_metadata_inventory_move = furniture.inv_manipulate, + on_metadata_inventory_put = furniture.inv_put, + on_metadata_inventory_take = furniture.inv_take, +}) + +minetest.register_node('furniture:chest', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Chest', + drawtype = 'mesh', + mesh = 'furniture_chest.obj', + tiles = {'furniture_chest.png'}, + overlay_tiles = {{name='furniture_chest_overlay.png', color='white'}}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.45, -.5, -.4, .45, .4, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.45, -.5, -.4, .45, .4, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string('formspec', furniture.storage_32_form(pos, '')) + local inv = meta:get_inventory() + inv:set_size('main', 32) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty('main') + end, + on_receive_fields = function(pos, formname, fields, sender) + local player_name = sender:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(sender, 'protection_bypass') then + return + end + local meta = minetest.get_meta(pos) + if fields ['save'] then + meta:set_string('infotext', fields.description) + meta:set_string('formspec', furniture.storage_32_form(pos, fields.description)) + elseif fields ['sort'] then + furniture.sort_inventory(meta:get_inventory()) + end + end, + allow_metadata_inventory_put = furniture.inv_take_put, + allow_metadata_inventory_take = furniture.inv_take_put, + allow_metadata_inventory_move = furniture.inv_manipulate, + on_metadata_inventory_put = furniture.inv_put, + on_metadata_inventory_take = furniture.inv_take, +}) + +minetest.register_node('furniture:chest_large', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Large Chest', + drawtype = 'mesh', + mesh = 'furniture_chest_large.obj', + tiles = {'furniture_chest_large.png'}, + overlay_tiles = {{name='furniture_chest_large_overlay.png', color='white'}}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.4, 1.5, .3, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.4, 1.5, .3, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + after_place_node = function(pos, placer, itemstack) + if not epic.space_to_side(pos) then + minetest.remove_node(pos) + return itemstack + end + end, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string('formspec', furniture.storage_60_form(pos, '')) + local inv = meta:get_inventory() + inv:set_size('main', 60) + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + epic.remove_side_node(pos, oldnode) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty('main') + end, + on_receive_fields = function(pos, formname, fields, sender) + local player_name = sender:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(sender, 'protection_bypass') then + return + end + local meta = minetest.get_meta(pos) + if fields ['save'] then + meta:set_string('infotext', fields.description) + meta:set_string('formspec', furniture.storage_60_form(pos, fields.description)) + elseif fields ['sort'] then + furniture.sort_inventory(meta:get_inventory()) + end + end, + on_rotate = function(pos, node) + return false + end, + allow_metadata_inventory_put = furniture.inv_take_put, + allow_metadata_inventory_take = furniture.inv_take_put, + allow_metadata_inventory_move = furniture.inv_manipulate, + on_metadata_inventory_put = furniture.inv_put, + on_metadata_inventory_take = furniture.inv_take, +}) + + + +minetest.register_node('furniture:cabinet_wall', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Wall Mounted Cabinet', + drawtype = 'mesh', + mesh = 'furniture_cabinet_wall.obj', + tiles = {'furniture_cabinet_wall.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.3, .5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.3, .5, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string('formspec', furniture.storage_24_form(pos, '')) + local inv = meta:get_inventory() + inv:set_size('main', 24) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty('main') + end, + on_receive_fields = function(pos, formname, fields, sender) + local player_name = sender:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(sender, 'protection_bypass') then + return + end + local meta = minetest.get_meta(pos) + if fields ['save'] then + meta:set_string('infotext', fields.description) + meta:set_string('formspec', furniture.storage_24_form(pos, fields.description)) + elseif fields ['sort'] then + furniture.sort_inventory(meta:get_inventory()) + end + end, + allow_metadata_inventory_put = furniture.inv_take_put, + allow_metadata_inventory_take = furniture.inv_take_put, + allow_metadata_inventory_move = furniture.inv_manipulate, + on_metadata_inventory_put = furniture.inv_put, + on_metadata_inventory_take = furniture.inv_take, +}) + +minetest.register_node('furniture:cabinet_counter', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Cabinet with Countertop', + drawtype = 'mesh', + mesh = 'furniture_cabinet_counter.obj', + tiles = {'furniture_cabinet_counter.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string('formspec', furniture.storage_24_form(pos, '')) + local inv = meta:get_inventory() + inv:set_size('main', 24) + end, + can_dig = function(pos,player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + return inv:is_empty('main') + end, + on_receive_fields = function(pos, formname, fields, sender) + local player_name = sender:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(sender, 'protection_bypass') then + return + end + local meta = minetest.get_meta(pos) + if fields ['save'] then + meta:set_string('infotext', fields.description) + meta:set_string('formspec', furniture.storage_24_form(pos, fields.description)) + elseif fields ['sort'] then + furniture.sort_inventory(meta:get_inventory()) + end + end, + allow_metadata_inventory_put = furniture.inv_take_put, + allow_metadata_inventory_take = furniture.inv_take_put, + allow_metadata_inventory_move = furniture.inv_manipulate, + on_metadata_inventory_put = furniture.inv_put, + on_metadata_inventory_take = furniture.inv_take, +}) + +local bookshelf_formspec = + "size[8,7;]" .. + "list[context;books;0,0.3;8,2;]" .. + "list[current_player;main;0,2.85;8,1;]" .. + "list[current_player;main;0,4.08;8,3;8]" .. + "listring[context;books]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0,2.85) + +local function update_bookshelf(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local invlist = inv:get_list("books") + + local formspec = bookshelf_formspec + -- Inventory slots overlay + local bx, by = 0, 0.3 + local n_written, n_empty = 0, 0 + for i = 1, 16 do + if i == 9 then + bx = 0 + by = by + 1 + end + local stack = invlist[i] + if stack:is_empty() then + formspec = formspec .. + "image[" .. bx .. "," .. by .. ";1,1;default_bookshelf_slot.png]" + else + local metatable = stack:get_meta():to_table() or {} + if metatable.fields and metatable.fields.text then + n_written = n_written + stack:get_count() + else + n_empty = n_empty + stack:get_count() + end + end + bx = bx + 1 + end + meta:set_string("formspec", formspec) + if n_written + n_empty == 0 then + meta:set_string("infotext", "Empty Locked Bookshelf") + else + meta:set_string("infotext", "Locked Bookshelf ("..n_written.." written, "..n_empty.." empty books)") + end +end + +minetest.register_node("furniture:bookshelf_locked", { + description = 'Locked Bookshelf', + tiles = {"default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "default_bookshelf.png", "default_bookshelf.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("books", 8 * 2) + update_bookshelf(pos) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("books") + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local player_name = player:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(player, 'protection_bypass') then + return 0 + else + if minetest.get_item_group(stack:get_name(), "book") ~= 0 then + return stack:get_count() + else + return 0 + end + end + end, + allow_metadata_inventory_take = furniture.inv_take_put, + allow_metadata_inventory_move = furniture.inv_manipulate, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) + update_bookshelf(pos) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " puts stuff to bookshelf at " .. minetest.pos_to_string(pos)) + update_bookshelf(pos) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) + update_bookshelf(pos) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "books", drops) + drops[#drops+1] = "furniture:bookshelf_locked" + minetest.remove_node(pos) + return drops + end, +}) + + +local vessels_shelf_formspec = + "size[8,7;]" .. + "list[context;vessels;0,0.3;8,2;]" .. + "list[current_player;main;0,2.85;8,1;]" .. + "list[current_player;main;0,4.08;8,3;8]" .. + "listring[context;vessels]" .. + "listring[current_player;main]" .. + default.get_hotbar_bg(0, 2.85) + +local function update_vessels_shelf(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local invlist = inv:get_list("vessels") + + local formspec = vessels_shelf_formspec + -- Inventory slots overlay + local vx, vy = 0, 0.3 + local n_items = 0 + for i = 1, 16 do + if i == 9 then + vx = 0 + vy = vy + 1 + end + if not invlist or invlist[i]:is_empty() then + formspec = formspec .. + "image[" .. vx .. "," .. vy .. ";1,1;vessels_shelf_slot.png]" + else + local stack = invlist[i] + if not stack:is_empty() then + n_items = n_items + stack:get_count() + end + end + vx = vx + 1 + end + meta:set_string("formspec", formspec) + if n_items == 0 then + meta:set_string("infotext", "Empty Locked Vessels Shelf") + else + meta:set_string("infotext", "Locked Vessels Shelf ("..n_items.." items)") + end +end + +minetest.register_node("furniture:shelf_vessel_locked", { + description = "Locked Vessels Shelf", + tiles = {"default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "vessels_shelf.png", "vessels_shelf.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + update_vessels_shelf(pos) + local inv = meta:get_inventory() + inv:set_size("vessels", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("vessels") + end, + allow_metadata_inventory_take = furniture.inv_take_put, + allow_metadata_inventory_move = furniture.inv_manipulate, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local player_name = player:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(player, 'protection_bypass') then + return 0 + else + if minetest.get_item_group(stack:get_name(), "vessel") ~= 0 then + return stack:get_count() + else + return 0 + end + end + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in vessels shelf at ".. minetest.pos_to_string(pos)) + update_vessels_shelf(pos) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to vessels shelf at ".. minetest.pos_to_string(pos)) + update_vessels_shelf(pos) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from vessels shelf at ".. minetest.pos_to_string(pos)) + update_vessels_shelf(pos) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "vessels", drops) + drops[#drops + 1] = "vessels:shelf" + minetest.remove_node(pos) + return drops + end, +}) + +minetest.register_node("furniture:multishelf_locked", { + description = "Locked Multishelf", + tiles = { + "default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "default_wood.png^xdecor_multishelf.png"}, + paramtype2 = "facedir", + is_ground_content = false, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, + sounds = default.node_sound_wood_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + update_vessels_shelf(pos) + local inv = meta:get_inventory() + inv:set_size("vessels", 8 * 2) + end, + can_dig = function(pos,player) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("vessels") + end, + allow_metadata_inventory_take = furniture.inv_take_put, + allow_metadata_inventory_move = furniture.inv_manipulate, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local player_name = player:get_player_name() + if minetest.is_protected(pos, player_name) and not minetest.check_player_privs(player, 'protection_bypass') then + return 0 + else return stack:get_count() + end + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + minetest.log("action", player:get_player_name() .. + " moves stuff in multi shelf at ".. minetest.pos_to_string(pos)) + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " moves stuff to multi shelf at ".. minetest.pos_to_string(pos)) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + minetest.log("action", player:get_player_name() .. + " takes stuff from multi shelf at ".. minetest.pos_to_string(pos)) + end, + on_blast = function(pos) + local drops = {} + default.get_inventory_drops(pos, "vessels", drops) + drops[#drops + 1] = "vessels:shelf" + minetest.remove_node(pos) + return drops + end, +}) diff --git a/mods/furniture/tables.lua b/mods/furniture/tables.lua new file mode 100644 index 0000000..36886a9 --- /dev/null +++ b/mods/furniture/tables.lua @@ -0,0 +1,31 @@ +minetest.register_node('furniture:table_basic', { + _doc_items_crafting = 'This is crafted in the Woodworking Station.', + description = 'Basic Table', + drawtype = 'mesh', + mesh = 'furniture_table_basic.obj', + tiles = {'furniture_table_basic.png'}, + paramtype = 'light', + paramtype2 = 'colorfacedir', + palette = 'furniture_stain_palette.png', + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, 1.5, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, 1.5, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, stainable=1}, + after_place_node = function(pos, placer, itemstack) + if not epic.space_to_side(pos) then + minetest.remove_node(pos) + return itemstack + end + end, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + epic.remove_side_node(pos, oldnode) + end, + on_rotate = function(pos, node) + return false + end, +}) diff --git a/mods/furniture/textures/furniture_bed1.png b/mods/furniture/textures/furniture_bed1.png new file mode 100644 index 0000000..b7a287f Binary files /dev/null and b/mods/furniture/textures/furniture_bed1.png differ diff --git a/mods/furniture/textures/furniture_bed1_mask.png b/mods/furniture/textures/furniture_bed1_mask.png new file mode 100644 index 0000000..54fc79b Binary files /dev/null and b/mods/furniture/textures/furniture_bed1_mask.png differ diff --git a/mods/furniture/textures/furniture_bed1_sheets.png b/mods/furniture/textures/furniture_bed1_sheets.png new file mode 100644 index 0000000..14d1a0f Binary files /dev/null and b/mods/furniture/textures/furniture_bed1_sheets.png differ diff --git a/mods/furniture/textures/furniture_bed1_wood.png b/mods/furniture/textures/furniture_bed1_wood.png new file mode 100644 index 0000000..681660a Binary files /dev/null and b/mods/furniture/textures/furniture_bed1_wood.png differ diff --git a/mods/furniture/textures/furniture_bench.png b/mods/furniture/textures/furniture_bench.png new file mode 100644 index 0000000..b2f226a Binary files /dev/null and b/mods/furniture/textures/furniture_bench.png differ diff --git a/mods/furniture/textures/furniture_bench_picnic.png b/mods/furniture/textures/furniture_bench_picnic.png new file mode 100644 index 0000000..ffa6fb8 Binary files /dev/null and b/mods/furniture/textures/furniture_bench_picnic.png differ diff --git a/mods/furniture/textures/furniture_brush.png b/mods/furniture/textures/furniture_brush.png new file mode 100644 index 0000000..bdd03e5 Binary files /dev/null and b/mods/furniture/textures/furniture_brush.png differ diff --git a/mods/furniture/textures/furniture_brush_overlay.png b/mods/furniture/textures/furniture_brush_overlay.png new file mode 100644 index 0000000..5d73835 Binary files /dev/null and b/mods/furniture/textures/furniture_brush_overlay.png differ diff --git a/mods/furniture/textures/furniture_cabinet_counter.png b/mods/furniture/textures/furniture_cabinet_counter.png new file mode 100644 index 0000000..9c62120 Binary files /dev/null and b/mods/furniture/textures/furniture_cabinet_counter.png differ diff --git a/mods/furniture/textures/furniture_cabinet_wall.png b/mods/furniture/textures/furniture_cabinet_wall.png new file mode 100644 index 0000000..2f09422 Binary files /dev/null and b/mods/furniture/textures/furniture_cabinet_wall.png differ diff --git a/mods/furniture/textures/furniture_chair.png b/mods/furniture/textures/furniture_chair.png new file mode 100644 index 0000000..13d6ba6 Binary files /dev/null and b/mods/furniture/textures/furniture_chair.png differ diff --git a/mods/furniture/textures/furniture_chest.png b/mods/furniture/textures/furniture_chest.png new file mode 100644 index 0000000..f5d1feb Binary files /dev/null and b/mods/furniture/textures/furniture_chest.png differ diff --git a/mods/furniture/textures/furniture_chest_large.png b/mods/furniture/textures/furniture_chest_large.png new file mode 100644 index 0000000..cf715b4 Binary files /dev/null and b/mods/furniture/textures/furniture_chest_large.png differ diff --git a/mods/furniture/textures/furniture_chest_large_overlay.png b/mods/furniture/textures/furniture_chest_large_overlay.png new file mode 100644 index 0000000..dfa2755 Binary files /dev/null and b/mods/furniture/textures/furniture_chest_large_overlay.png differ diff --git a/mods/furniture/textures/furniture_chest_overlay.png b/mods/furniture/textures/furniture_chest_overlay.png new file mode 100644 index 0000000..00e9362 Binary files /dev/null and b/mods/furniture/textures/furniture_chest_overlay.png differ diff --git a/mods/furniture/textures/furniture_chest_small.png b/mods/furniture/textures/furniture_chest_small.png new file mode 100644 index 0000000..0938500 Binary files /dev/null and b/mods/furniture/textures/furniture_chest_small.png differ diff --git a/mods/furniture/textures/furniture_chest_small_overlay.png b/mods/furniture/textures/furniture_chest_small_overlay.png new file mode 100644 index 0000000..1021a0b Binary files /dev/null and b/mods/furniture/textures/furniture_chest_small_overlay.png differ diff --git a/mods/furniture/textures/furniture_curtain_short_0.png b/mods/furniture/textures/furniture_curtain_short_0.png new file mode 100644 index 0000000..09f7151 Binary files /dev/null and b/mods/furniture/textures/furniture_curtain_short_0.png differ diff --git a/mods/furniture/textures/furniture_curtain_short_1.png b/mods/furniture/textures/furniture_curtain_short_1.png new file mode 100644 index 0000000..1385d09 Binary files /dev/null and b/mods/furniture/textures/furniture_curtain_short_1.png differ diff --git a/mods/furniture/textures/furniture_curtain_tall_0.png b/mods/furniture/textures/furniture_curtain_tall_0.png new file mode 100644 index 0000000..1b11cca Binary files /dev/null and b/mods/furniture/textures/furniture_curtain_tall_0.png differ diff --git a/mods/furniture/textures/furniture_curtain_tall_1.png b/mods/furniture/textures/furniture_curtain_tall_1.png new file mode 100644 index 0000000..a092599 Binary files /dev/null and b/mods/furniture/textures/furniture_curtain_tall_1.png differ diff --git a/mods/furniture/textures/furniture_cushion.png b/mods/furniture/textures/furniture_cushion.png new file mode 100644 index 0000000..a4efacf Binary files /dev/null and b/mods/furniture/textures/furniture_cushion.png differ diff --git a/mods/furniture/textures/furniture_cushion_pad.png b/mods/furniture/textures/furniture_cushion_pad.png new file mode 100644 index 0000000..6bdf457 Binary files /dev/null and b/mods/furniture/textures/furniture_cushion_pad.png differ diff --git a/mods/furniture/textures/furniture_cushion_pad_inv.png b/mods/furniture/textures/furniture_cushion_pad_inv.png new file mode 100644 index 0000000..d299a3a Binary files /dev/null and b/mods/furniture/textures/furniture_cushion_pad_inv.png differ diff --git a/mods/furniture/textures/furniture_fabric.png b/mods/furniture/textures/furniture_fabric.png new file mode 100644 index 0000000..d33678c Binary files /dev/null and b/mods/furniture/textures/furniture_fabric.png differ diff --git a/mods/furniture/textures/furniture_fabric_bg.png b/mods/furniture/textures/furniture_fabric_bg.png new file mode 100644 index 0000000..ac9883f Binary files /dev/null and b/mods/furniture/textures/furniture_fabric_bg.png differ diff --git a/mods/furniture/textures/furniture_fabric_fg.png b/mods/furniture/textures/furniture_fabric_fg.png new file mode 100644 index 0000000..cbf38d0 Binary files /dev/null and b/mods/furniture/textures/furniture_fabric_fg.png differ diff --git a/mods/furniture/textures/furniture_fence.png b/mods/furniture/textures/furniture_fence.png new file mode 100644 index 0000000..6e381f2 Binary files /dev/null and b/mods/furniture/textures/furniture_fence.png differ diff --git a/mods/furniture/textures/furniture_hinge.png b/mods/furniture/textures/furniture_hinge.png new file mode 100644 index 0000000..d2a6941 Binary files /dev/null and b/mods/furniture/textures/furniture_hinge.png differ diff --git a/mods/furniture/textures/furniture_lantern.png b/mods/furniture/textures/furniture_lantern.png new file mode 100644 index 0000000..c65d04a Binary files /dev/null and b/mods/furniture/textures/furniture_lantern.png differ diff --git a/mods/furniture/textures/furniture_lantern_particle.png b/mods/furniture/textures/furniture_lantern_particle.png new file mode 100644 index 0000000..2f270c1 Binary files /dev/null and b/mods/furniture/textures/furniture_lantern_particle.png differ diff --git a/mods/furniture/textures/furniture_lectern.png b/mods/furniture/textures/furniture_lectern.png new file mode 100644 index 0000000..f793ada Binary files /dev/null and b/mods/furniture/textures/furniture_lectern.png differ diff --git a/mods/furniture/textures/furniture_lectern_encylopedia_overlay.png b/mods/furniture/textures/furniture_lectern_encylopedia_overlay.png new file mode 100644 index 0000000..5b787b0 Binary files /dev/null and b/mods/furniture/textures/furniture_lectern_encylopedia_overlay.png differ diff --git a/mods/furniture/textures/furniture_lectern_formspec.png b/mods/furniture/textures/furniture_lectern_formspec.png new file mode 100644 index 0000000..4e3e756 Binary files /dev/null and b/mods/furniture/textures/furniture_lectern_formspec.png differ diff --git a/mods/furniture/textures/furniture_lectern_overlay.png b/mods/furniture/textures/furniture_lectern_overlay.png new file mode 100644 index 0000000..170a05e Binary files /dev/null and b/mods/furniture/textures/furniture_lectern_overlay.png differ diff --git a/mods/furniture/textures/furniture_lock.png b/mods/furniture/textures/furniture_lock.png new file mode 100644 index 0000000..6e4c699 Binary files /dev/null and b/mods/furniture/textures/furniture_lock.png differ diff --git a/mods/furniture/textures/furniture_sanding.png b/mods/furniture/textures/furniture_sanding.png new file mode 100644 index 0000000..e24ffb9 Binary files /dev/null and b/mods/furniture/textures/furniture_sanding.png differ diff --git a/mods/furniture/textures/furniture_stain_palette.png b/mods/furniture/textures/furniture_stain_palette.png new file mode 100644 index 0000000..4ad5953 Binary files /dev/null and b/mods/furniture/textures/furniture_stain_palette.png differ diff --git a/mods/furniture/textures/furniture_stool_short.png b/mods/furniture/textures/furniture_stool_short.png new file mode 100644 index 0000000..2b67c9d Binary files /dev/null and b/mods/furniture/textures/furniture_stool_short.png differ diff --git a/mods/furniture/textures/furniture_stool_tall.png b/mods/furniture/textures/furniture_stool_tall.png new file mode 100644 index 0000000..713837b Binary files /dev/null and b/mods/furniture/textures/furniture_stool_tall.png differ diff --git a/mods/furniture/textures/furniture_table_basic.png b/mods/furniture/textures/furniture_table_basic.png new file mode 100644 index 0000000..c45099c Binary files /dev/null and b/mods/furniture/textures/furniture_table_basic.png differ diff --git a/mods/furniture/textures/furniture_thread.png b/mods/furniture/textures/furniture_thread.png new file mode 100644 index 0000000..cbd80d8 Binary files /dev/null and b/mods/furniture/textures/furniture_thread.png differ diff --git a/mods/furniture/textures/furniture_thread_mask.png b/mods/furniture/textures/furniture_thread_mask.png new file mode 100644 index 0000000..c33588e Binary files /dev/null and b/mods/furniture/textures/furniture_thread_mask.png differ diff --git a/mods/furniture/textures/furniture_wheel.png b/mods/furniture/textures/furniture_wheel.png new file mode 100644 index 0000000..c94f030 Binary files /dev/null and b/mods/furniture/textures/furniture_wheel.png differ diff --git a/mods/game_commands/README.txt b/mods/game_commands/README.txt new file mode 100644 index 0000000..a451608 --- /dev/null +++ b/mods/game_commands/README.txt @@ -0,0 +1,7 @@ +Minetest Game mod: game_commands +================================ +See license.txt for license information. + +Authors of source code +---------------------- +rubenwardy (MIT) diff --git a/mods/game_commands/init.lua b/mods/game_commands/init.lua new file mode 100644 index 0000000..e038be1 --- /dev/null +++ b/mods/game_commands/init.lua @@ -0,0 +1,31 @@ +-- game_commands/init.lua + +-- Load support for MT game translation. +local S = minetest.get_translator("game_commands") + + +minetest.register_chatcommand("killme", { + description = S("Kill yourself to respawn"), + func = function(name) + local player = minetest.get_player_by_name(name) + if player then + if minetest.settings:get_bool("enable_damage") then + player:set_hp(0) + return true + else + for _, callback in pairs(minetest.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, S("No static_spawnpoint defined") + end + else + -- Show error message if used when not logged in, eg: from IRC mod + return false, S("You need to be online to be killed!") + end + end +}) diff --git a/mods/game_commands/license.txt b/mods/game_commands/license.txt new file mode 100644 index 0000000..fa85564 --- /dev/null +++ b/mods/game_commands/license.txt @@ -0,0 +1,24 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2017-2018 rubenwardy + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT diff --git a/mods/game_commands/locale/game_commands.de.tr b/mods/game_commands/locale/game_commands.de.tr new file mode 100644 index 0000000..24b0e25 --- /dev/null +++ b/mods/game_commands/locale/game_commands.de.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=Selbstmord begehen, um zu Respawnen +No static_spawnpoint defined=Kein static_spawnpoint definiert +You need to be online to be killed!=Sie müssen online sein, um getötet zu werden! diff --git a/mods/game_commands/locale/game_commands.es.tr b/mods/game_commands/locale/game_commands.es.tr new file mode 100644 index 0000000..702a2ef --- /dev/null +++ b/mods/game_commands/locale/game_commands.es.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=Suicídate para reaparecer +No static_spawnpoint defined=No se ha definido un punto de aparición +You need to be online to be killed!=¡Necesitas estar en línea para que te maten! diff --git a/mods/game_commands/locale/game_commands.fr.tr b/mods/game_commands/locale/game_commands.fr.tr new file mode 100644 index 0000000..0e295d6 --- /dev/null +++ b/mods/game_commands/locale/game_commands.fr.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=Se suicider pour réapparaître +No static_spawnpoint defined=Pas de point d'apparition défini +You need to be online to be killed!=Vous devez être en ligne pour être tué ! diff --git a/mods/game_commands/locale/game_commands.it.tr b/mods/game_commands/locale/game_commands.it.tr new file mode 100644 index 0000000..b2431fa --- /dev/null +++ b/mods/game_commands/locale/game_commands.it.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=Ucciditi per ricomparire +No static_spawnpoint defined=Nessuno static_spawnpoint definito +You need to be online to be killed!=Devi essere in linea per essere ucciso! \ No newline at end of file diff --git a/mods/game_commands/locale/game_commands.ms.tr b/mods/game_commands/locale/game_commands.ms.tr new file mode 100644 index 0000000..ed4a0bd --- /dev/null +++ b/mods/game_commands/locale/game_commands.ms.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=Bunuh diri anda untuk lahir semula +No static_spawnpoint defined=Tiada titik permulaan statik (tetapan static_spawnpoint) ditakrifkan +You need to be online to be killed!=Anda mesti berada dalam talian untuk dibunuh! diff --git a/mods/game_commands/locale/game_commands.ru.tr b/mods/game_commands/locale/game_commands.ru.tr new file mode 100644 index 0000000..26d9e08 --- /dev/null +++ b/mods/game_commands/locale/game_commands.ru.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=Убейте ÑебÑ, чтобы возродитьÑÑ +No static_spawnpoint defined=static_spawnpoint не определён +You need to be online to be killed!=Ð’Ñ‹ должны быть онлайн, чтобы убить ÑебÑ! diff --git a/mods/game_commands/locale/game_commands.se.tr b/mods/game_commands/locale/game_commands.se.tr new file mode 100644 index 0000000..259e1db --- /dev/null +++ b/mods/game_commands/locale/game_commands.se.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=Döda dig själv för att respawna +No static_spawnpoint defined=Ingen static_spawnpoint definierat +You need to be online to be killed!=Du mÃ¥sta vara online för att bli dödad! \ No newline at end of file diff --git a/mods/game_commands/locale/game_commands.zh_CN.tr b/mods/game_commands/locale/game_commands.zh_CN.tr new file mode 100644 index 0000000..3c69dfb --- /dev/null +++ b/mods/game_commands/locale/game_commands.zh_CN.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=æ€æ­»è‡ªå·±å¹¶é‡ç”Ÿ +No static_spawnpoint defined=static_spawnpoint 未定义 +You need to be online to be killed!=您需è¦åœ¨çº¿æ‰èƒ½è¢«æ€æ­»ï¼ diff --git a/mods/game_commands/locale/game_commands.zh_TW.tr b/mods/game_commands/locale/game_commands.zh_TW.tr new file mode 100644 index 0000000..34e148d --- /dev/null +++ b/mods/game_commands/locale/game_commands.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn=殺死自己並é‡ç”Ÿ +No static_spawnpoint defined=static_spawnpoint 未定義 +You need to be online to be killed!=您需è¦åœ¨ç·šæ‰èƒ½è¢«æ®ºæ­»ï¼ diff --git a/mods/game_commands/locale/template.txt b/mods/game_commands/locale/template.txt new file mode 100644 index 0000000..903f160 --- /dev/null +++ b/mods/game_commands/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: game_commands +Kill yourself to respawn= +No static_spawnpoint defined= +You need to be online to be killed!= diff --git a/mods/game_commands/mod.conf b/mods/game_commands/mod.conf new file mode 100644 index 0000000..5571ff5 --- /dev/null +++ b/mods/game_commands/mod.conf @@ -0,0 +1,2 @@ +name = game_commands +description = Minetest Game mod: game_commands diff --git a/mods/give_initial_stuff/README.txt b/mods/give_initial_stuff/README.txt new file mode 100644 index 0000000..cbd240f --- /dev/null +++ b/mods/give_initial_stuff/README.txt @@ -0,0 +1,8 @@ +Minetest Game mod: give_initial_stuff +===================================== +See license.txt for license information. + +Authors of source code +---------------------- +Perttu Ahola (celeron55) (MIT) +Various Minetest developers and contributors (MIT) diff --git a/mods/give_initial_stuff/init.lua b/mods/give_initial_stuff/init.lua new file mode 100644 index 0000000..74421dc --- /dev/null +++ b/mods/give_initial_stuff/init.lua @@ -0,0 +1,46 @@ +-- gave_initial_stuff/init.lua + +local stuff_string = minetest.settings:get("initial_stuff") or + "default:pick_steel,default:axe_steel,default:shovel_steel," .. + "default:torch 99,default:cobble 99" + +give_initial_stuff = { + items = {} +} + +function give_initial_stuff.give(player) + minetest.log("action", + "Giving initial stuff to player " .. player:get_player_name()) + local inv = player:get_inventory() + for _, stack in ipairs(give_initial_stuff.items) do + inv:add_item("main", stack) + end +end + +function give_initial_stuff.add(stack) + give_initial_stuff.items[#give_initial_stuff.items + 1] = ItemStack(stack) +end + +function give_initial_stuff.clear() + give_initial_stuff.items = {} +end + +function give_initial_stuff.add_from_csv(str) + local items = str:split(",") + for _, itemname in ipairs(items) do + give_initial_stuff.add(itemname) + end +end + +function give_initial_stuff.set_list(list) + give_initial_stuff.items = list +end + +function give_initial_stuff.get_list() + return give_initial_stuff.items +end + +give_initial_stuff.add_from_csv(stuff_string) +if minetest.settings:get_bool("give_initial_stuff") then + minetest.register_on_newplayer(give_initial_stuff.give) +end diff --git a/mods/give_initial_stuff/license.txt b/mods/give_initial_stuff/license.txt new file mode 100644 index 0000000..8134c92 --- /dev/null +++ b/mods/give_initial_stuff/license.txt @@ -0,0 +1,25 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT diff --git a/mods/give_initial_stuff/mod.conf b/mods/give_initial_stuff/mod.conf new file mode 100644 index 0000000..51d31ae --- /dev/null +++ b/mods/give_initial_stuff/mod.conf @@ -0,0 +1,3 @@ +name = give_initial_stuff +description = Minetest Game mod: give_initial_stuff +depends = default diff --git a/mods/glow/init.lua b/mods/glow/init.lua new file mode 100644 index 0000000..7b1538f --- /dev/null +++ b/mods/glow/init.lua @@ -0,0 +1,192 @@ +-- boilerplate to support localized strings if intllib mod is installed + +local S +if minetest.global_exists('intllib') then + if intllib.make_gettext_pair then + -- New method using gettext. + S = intllib.make_gettext_pair() + else + -- Old method using text files. + S = intllib.Getter() + end +else + S = function(s) return s end +end + +-- WORMS -------------------------------------------------- + +minetest.register_node('glow:cave_worms', { + description = S('Glow Worms'), + drawtype = 'nodebox', + tiles = {'glow_worms.png'}, + inventory_image = 'glow_worms.png', + groups = {dig_immediate = 2, flammable = 1}, + sounds = default.node_sound_stone_defaults(), + drop = 'glow:cave_worms', + paramtype = 'light', + light_source = 4, + paramtype2 = 'facedir', + sunlight_propagates = true, + walkable = false, + node_box = { + type = 'fixed', + fixed = { -1/2, -1/2, -1/2, 1/2, -15/32, 1/2 }, + }, + selection_box = { + type = 'fixed', + fixed = { -1/2, -1/2, -1/2, 1/2, -7/16, 1/2 }, + }, + on_place = minetest.rotate_node, +}) + +local function near_surface(pos) + for dx = -1, 1, 1 do + for dy = -1, 1, 1 do + for dz = -1, 1, 1 do + local dpos = { x=pos.x+dx, y=pos.y+dy, z=pos.z+dz } + local light = minetest.get_node_light(dpos, 0.5) -- 0.5 means noon + if light and light > 5 then + return true + end + end + end + end + return false +end + +local function place_worms(pos) + local axes = { + { x=pos.x, y=pos.y-1, z=pos.z }, + { x=pos.x, y=pos.y, z=pos.z-1 }, + { x=pos.x, y=pos.y, z=pos.z+1 }, + { x=pos.x-1, y=pos.y, z=pos.z }, + { x=pos.x+1, y=pos.y, z=pos.z }, + { x=pos.x, y=pos.y+1, z=pos.z }, + } + for i, cpos in ipairs(axes) do + if minetest.get_node(cpos).name == 'default:stone' then + local facedir = (i-1) * 4 + math.random(0, 3) -- see 6d facedir info + minetest.set_node(pos, { name = 'glow:cave_worms', param2 = facedir }) + return + end + end +end + +local function make_worms(pos) + local spot = minetest.find_node_near(pos, 1, 'air') + if not spot or near_surface(spot) then + return + end + local minp = vector.subtract(pos, 6) + local maxp = vector.add(pos, 6) + if #(minetest.find_nodes_in_area(minp, maxp, 'default:lava_source')) == 0 + and #(minetest.find_nodes_in_area(minp, maxp, 'glow:cave_worms')) == 0 + and #(minetest.find_nodes_in_area(minp, maxp, 'group:water')) > 1 then + place_worms(spot) + end +end + +minetest.register_abm({ + nodenames = { 'default:stone' }, + neighbors = { 'air' }, + interval = 120, + chance = 200, + action = make_worms, +}) + +minetest.register_abm({ + nodenames = { 'glow:cave_worms' }, + interval = 60, + chance = 10, + action = function(pos) + if math.random() < 0.7 then + local minp = vector.subtract(pos, 2) + local maxp = vector.add(pos, 2) + local worms_count = #(minetest.find_nodes_in_area(minp, maxp, 'glow:cave_worms')) + if worms_count < 20 then + local spot = minetest.find_node_near(pos, 3, 'air') + if spot and not near_surface(spot) then + place_worms(spot) + return + end + end + end + minetest.remove_node(pos) + end, +}) + +-- SHROOMS ------------------------------------------------- + +minetest.register_node('glow:shrooms', { + description = S('Glow Shrooms'), + drawtype = 'plantlike', + tiles = {'glow_shrooms.png'}, + inventory_image = 'glow_shrooms.png', + groups = { snappy=3, flammable=2, flower=1, flora=1, attached_node=1 }, + sunlight_propagates = true, + walkable = false, + pointable = true, + diggable = true, + climbable = false, + buildable_to = true, + paramtype = 'light', + light_source = 3, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = 'fixed', + fixed = { -0.4, -0.5, -0.4, 0.4, 0.0, 0.4 }, + }, +}) + +local function add_shrooms(pos) + if minetest.find_node_near(pos, 4, 'glow:shrooms') then + return + end + for nx = -1, 1, 2 do + for nz = -1, 1, 2 do + for ny = 1, -1, -1 do + if math.random() < 0.2 then + local p = { x=pos.x+nx, y=pos.y-1+ny, z=pos.z+nz } + if minetest.get_item_group(minetest.get_node(p).name, 'soil') ~= 0 then + p.y = p.y+1 + if minetest.get_node(p).name == 'air' then + minetest.set_node(p, { name = 'glow:shrooms' }) + end + break + end + end + end + end + end +end + +minetest.register_abm({ + nodenames = {'default:tree'}, + neighbors = { + 'air', + 'group:soil', + }, + interval = 163, + chance = 60, + action = function(pos) + local minp = vector.subtract(pos, 2) + local maxp = vector.add(pos, 2) + local shroom_count = #(minetest.find_nodes_in_area(minp, maxp, 'glow:shrooms')) + if shroom_count == 0 then + add_shrooms(pos) + end + end, +}) + +minetest.register_abm({ + nodenames = {'glow:shrooms'}, + neighbors = { + 'air', + 'group:soil', + }, + interval = 91, + chance = 100, + action = function(pos) + minetest.remove_node(pos) + end, +}) diff --git a/mods/glow/license.txt b/mods/glow/license.txt new file mode 100644 index 0000000..8851d92 --- /dev/null +++ b/mods/glow/license.txt @@ -0,0 +1 @@ +Code license : GPLv2/later by bdjnk diff --git a/mods/glow/locale/de.txt b/mods/glow/locale/de.txt new file mode 100644 index 0000000..d93e481 --- /dev/null +++ b/mods/glow/locale/de.txt @@ -0,0 +1,4 @@ +# Translation by Xanthin + +Glow Worms in Stone = Gluehwuermchen im Stein +Glow Shrooms = Leuchtpilze diff --git a/mods/glow/locale/template.txt b/mods/glow/locale/template.txt new file mode 100644 index 0000000..c5c5495 --- /dev/null +++ b/mods/glow/locale/template.txt @@ -0,0 +1,5 @@ +# Template + +Glow Worms in Stone = +Glow Shrooms = +Fireflies = diff --git a/mods/glow/mod.conf b/mods/glow/mod.conf new file mode 100644 index 0000000..7701a89 --- /dev/null +++ b/mods/glow/mod.conf @@ -0,0 +1,3 @@ +name = glow +depends = default +description = Adds various glowing elements to enhance the ambiance of caves and the night landscape. diff --git a/mods/glow/textures/glow_shrooms.png b/mods/glow/textures/glow_shrooms.png new file mode 100644 index 0000000..3accd90 Binary files /dev/null and b/mods/glow/textures/glow_shrooms.png differ diff --git a/mods/glow/textures/glow_worms.png b/mods/glow/textures/glow_worms.png new file mode 100644 index 0000000..2f5bf71 Binary files /dev/null and b/mods/glow/textures/glow_worms.png differ diff --git a/mods/hall/areas.lua b/mods/hall/areas.lua new file mode 100644 index 0000000..f4d6966 --- /dev/null +++ b/mods/hall/areas.lua @@ -0,0 +1,141 @@ +local priv_areas_formspec_base = + 'size[12,7]'.. + 'no_prepend[]'.. + 'bgcolor[#080808BB;true]'.. + 'background[0,0;12,7;hall_chalkboard_bg.png]'.. + 'hypertext[0,.2;12,1;;
]' + +local esc = minetest.formspec_escape + +local lesson = "The Areas privilege will let you create, rename, transfer, and delete areas that you have created. ".. + "To create an area you will need a land deed, one of which will be given to you upon the completion of this course. ".. + "Set the corners of the area you want to protect with /area_pos1 and /area_pos2 and protect the area with /protect \n".. + "You can add other players to your area using /add_owner \n".. + "You can list all your areas with /list_areas and can remove an area with /remove_area \n".. + "If you want to rename an area use /rename_area \n".. + "The ID of an area can be found by looking in the lower left corner of your screen while you are in the area. It will be a numerical value.".. + "You can only protect five areas max size of 128*128*128, and must keep twenty-five nodes space between another players area and your own. ".. + "Land deeds are not returned when deleting an area, due to potential exploits. If you want your deed back have an admin delete your area.".. + "Be careful when creating an area to make sure there are not other players protection blocks within the area you are trying to protect." + +local priv_areas_formspec_lesson = + priv_areas_formspec_base.. + "textarea[.75,1.5;11.25,4;;;"..esc(lesson).."]" .. + 'button[4.5,5;3,1;go;Take Quiz]' + +local priv_areas_formspec_1 = + priv_areas_formspec_base.. + "textarea[1,1.5;11,3;;;What do you need to create an area?]" .. + 'button[1,4;3,1;wrong;A) Land Deed]'.. + 'button[4.5,4;3,1;wrong;B) A Diamond Block]'.. + 'button[8,4;3,1;wrong;C) A Secret Potion]'.. + 'button[1,5.5;3,1;wrong;D) Twenty-five Zombie Teeth]'.. + 'button[4.5,5.5;3,1;wrong;E) The Areas Priv]'.. + 'button[8,5.5;3,1;right;F) Both A and E]' + +local priv_areas_formspec_2 = + priv_areas_formspec_base.. + "textarea[1,1.5;11,3;;;How many areas is a player allowed to have?]" .. + 'button[1,4;3,1;wrong;A) One]'.. + 'button[4.5,4;3,1;wrong;B) Three]'.. + 'button[8,4;3,1;right;C) Five]'.. + 'button[1,5.5;3,1;wrong;D) Seven]'.. + 'button[4.5,5.5;3,1;wrong;E) Nine]'.. + 'button[8,5.5;3,1;wrong;F) Eleven]' + +local priv_areas_formspec_3 = + priv_areas_formspec_base.. + "textarea[1,1.5;11,3;;;What is the maximum size of an area?]" .. + 'button[1,4;3,1;wrong;A) 32*32*32]'.. + 'button[4.5,4;3,1;wrong;B) 40*40*40]'.. + 'button[8,4;3,1;wrong;C) 64*64*64]'.. + 'button[1,5.5;3,1;wrong;D) 256*256*256]'.. + 'button[4.5,5.5;3,1;right;E) 128*128*128]'.. + 'button[8,5.5;3,1;wrong;F) 100*100*100]' + +local priv_areas_formspec_4 = + priv_areas_formspec_base.. + "textarea[1,1.5;11,3;;;How much space do you need to leave between another players area and your own?]" .. + 'button[1,4;3,1;wrong;A) None]'.. + 'button[4.5,4;3,1;wrong;B) One Node]'.. + 'button[8,4;3,1;wrong;C) Ten Nodes]'.. + 'button[1,5.5;3,1;right;D) Twenty-five Nodes]'.. + 'button[4.5,5.5;3,1;wrong;E) Fifty Nodes]'.. + 'button[8,5.5;3,1;wrong;F) One Hundred Nodes]' + +local priv_areas_formspec_5 = + priv_areas_formspec_base.. + "textarea[1,1.5;11,3;;;You've passed the quiz! If you haven't taken the quiz before a land deed was added to your inventory, or dropped at your feet.]".. + 'button_exit[4.5,5;3,1;;Exit]' + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if formname == 'hall:priv_areas_lesson' then + if fields.go then + minetest.show_formspec(name, 'hall:priv_areas_1', priv_areas_formspec_1) + end + elseif formname == 'hall:priv_areas_1' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_areas_2', priv_areas_formspec_2) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_areas_lesson', priv_areas_formspec_lesson) + end + elseif formname == 'hall:priv_areas_2' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_areas_3', priv_areas_formspec_3) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_areas_lesson', priv_areas_formspec_lesson) + end + elseif formname == 'hall:priv_areas_3' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_areas_4', priv_areas_formspec_4) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_areas_lesson', priv_areas_formspec_lesson) + end + elseif formname == 'hall:priv_areas_4' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_areas_5', priv_areas_formspec_5) + local give = hall.storage:get_string(name..'_areas') + if give ~= 'earned' then + local player_inv = player:get_inventory() + if player_inv:room_for_item('main', 'epic:deed') then + player_inv:add_item('main', 'epic:deed') + else + local drop_pos = player:get_pos() + minetest.add_item(drop_pos, 'epic:deed') + end + end + local privs = minetest.get_player_privs(name) + privs.areas = true + minetest.set_player_privs(name, privs) + hall.storage:set_string(name..'_areas', 'earned') + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_areas_lesson', priv_areas_formspec_lesson) + end + end +end) + +minetest.register_node('hall:priv_areas', { + description = 'Areas Course', + drawtype = 'mesh', + mesh = 'hall_chalkboard.obj', + tiles = {'hall_chalkboard_areas.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, + on_rightclick = function(pos, node, clicker, itemstack) + local meta = minetest.get_meta(pos) + meta:set_string('infotext', 'Areas Privs Course') + local name = clicker:get_player_name() + minetest.show_formspec(name, 'hall:priv_areas_lesson', priv_areas_formspec_lesson) + end, +}) diff --git a/mods/hall/crafts.lua b/mods/hall/crafts.lua new file mode 100644 index 0000000..d0c4d69 --- /dev/null +++ b/mods/hall/crafts.lua @@ -0,0 +1,29 @@ +minetest.register_craft({ + output = 'hall:stanchion_post', + recipe = { + {'default:fence_wood'}, + } +}) + +minetest.register_craft({ + output = 'hall:stanchion_post_sign', + recipe = { + {'default:sign_wall_wood'}, + {'hall:stanchion_post'} + } +}) + +minetest.register_craft({ + output = 'hall:stanchion_rope 4', + recipe = { + {'wool:black'} + } +}) + +minetest.register_craft({ + output = 'hall:stanchion_rope_sign', + recipe = { + {'default:sign_wall_wood'}, + {'hall:stanchion_rope'} + } +}) diff --git a/mods/hall/fire.lua b/mods/hall/fire.lua new file mode 100644 index 0000000..35d99d9 --- /dev/null +++ b/mods/hall/fire.lua @@ -0,0 +1,127 @@ +local priv_fire_formspec_base = + 'size[12,7]'.. + 'no_prepend[]'.. + 'bgcolor[#080808BB;true]'.. + 'background[0,0;12,7;hall_chalkboard_bg.png]'.. + 'hypertext[0,.2;12,1;;
]' + +local esc = minetest.formspec_escape + +local lesson = "The Fire privilege will let you start things on fire, and use explosives. ".. + "Due to the potentially dangerous nature of these things it's important that you understand required safety precautions. ".. + "On this server grass can burn, so it is all the more important to construct fire lanes before starting fires. ".. + "A good firelane will be two nodes wide, built of a nonflammable material, and have some anti-fire powder placed in it as well. ".. + "If you don't have anti-fire powder be sure and watch the fire lane and stop any fire that may pass over. ".. + "Starting fires that get out of hand can be grounds for jailing, and if repeated potential banning. ".. + "You can start fires with Flint & Steel and Lava." + +local priv_fire_formspec_lesson = + priv_fire_formspec_base.. + "textarea[.75,1.5;11.25,6;;;"..esc(lesson).."]" .. + 'button[4.5,5;3,1;go;Take Quiz]' + +local priv_fire_formspec_1 = + priv_fire_formspec_base.. + "textarea[1,1.5;11,3;;;Is fire enabled on this server?]" .. + 'button[1,4;3,1;wrong;A) Do pigs fly?]'.. + 'button[4.5,4;3,1;wrong;B) Certainly Not]'.. + 'button[8,4;3,1;wrong;C) A Nope]'.. + 'button[1,5.5;3,1;right;D) Yes]'.. + 'button[4.5,5.5;3,1;wrong;E) No]'.. + 'button[8,5.5;3,1;right;F) Yep]' + +local priv_fire_formspec_2 = + priv_fire_formspec_base.. + "textarea[1,1.5;11,3;;;What makes a good fire lane?]" .. + 'button[1,4;3,1;wrong;A) Lava]'.. + 'button[4.5,4;3,1;right;B) Water]'.. + 'button[8,4;3,1;wrong;C) Dirt with Grass]'.. + 'button[1,5.5;3,1;right;D) Stone]'.. + 'button[4.5,5.5;3,1;right;E) Anti-fire Powder]'.. + 'button[8,5.5;3,1;right;F) Nonflamable Nodes]' + +local priv_fire_formspec_3 = + priv_fire_formspec_base.. + "textarea[1,1.5;11,3;;;How wide should a firelane be?]" .. + 'button[1,4;3,1;wrong;A) 1 Node or More]'.. + 'button[4.5,4;3,1;right;B) 2 Nodes or More]'.. + 'button[8,4;3,1;wrong;C) 3 Nodes or More]'.. + 'button[1,5.5;3,1;wrong;D) 4 Nodes or More]'.. + 'button[4.5,5.5;3,1;wrong;E) 5 Nodes or More]'.. + 'button[8,5.5;3,1;wrong;F) 6 Nodes or More]' + +local priv_fire_formspec_4 = + priv_fire_formspec_base.. + "textarea[1,1.5;11,3;;;Which of the follow can start fires.?]" .. + 'button[1,4;3,1;wrong;A) Flint & Steel]'.. + 'button[4.5,4;3,1;wrong;B) Lava]'.. + 'button[8,4;3,1;wrong;C) Torches]'.. + 'button[1,5.5;3,1;wrong;D) Brasiers]'.. + 'button[4.5,5.5;3,1;wrong;E) Hot Cobble]'.. + 'button[8,5.5;3,1;right;F) Both A and B]' + +local priv_fire_formspec_5 = + priv_fire_formspec_base.. + "textarea[1,1.5;11,3;;;You've passed the quiz! You now have the fire privilege. Remember only YOU can prevent forest fires.]".. + 'button_exit[4.5,5;3,1;;Exit]' + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if formname == 'hall:priv_fire_lesson' then + if fields.go then + minetest.show_formspec(name, 'hall:priv_fire_1', priv_fire_formspec_1) + end + elseif formname == 'hall:priv_fire_1' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_fire_2', priv_fire_formspec_2) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_fire_lesson', priv_fire_formspec_lesson) + end + elseif formname == 'hall:priv_fire_2' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_fire_3', priv_fire_formspec_3) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_fire_lesson', priv_fire_formspec_lesson) + end + elseif formname == 'hall:priv_fire_3' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_fire_4', priv_fire_formspec_4) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_fire_lesson', priv_fire_formspec_lesson) + end + elseif formname == 'hall:priv_fire_4' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_fire_5', priv_fire_formspec_5) + local privs = minetest.get_player_privs(name) + privs.fire = true + minetest.set_player_privs(name, privs) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_fire_lesson', priv_fire_formspec_lesson) + end + end +end) + +minetest.register_node('hall:priv_fire', { + description = 'Fire Course', + drawtype = 'mesh', + mesh = 'hall_chalkboard.obj', + tiles = {'hall_chalkboard_fire.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, + on_rightclick = function(pos, node, clicker, itemstack) + local meta = minetest.get_meta(pos) + local name = clicker:get_player_name() + meta:set_string('infotext', 'Fire Privs Course') + minetest.show_formspec(name, 'hall:priv_fire_lesson', priv_fire_formspec_lesson) + end, +}) diff --git a/mods/hall/formspec.lua b/mods/hall/formspec.lua new file mode 100644 index 0000000..7319c71 --- /dev/null +++ b/mods/hall/formspec.lua @@ -0,0 +1,29 @@ +local esc = minetest.formspec_escape +local title, text = '', '' + +sign_formspec = + 'size[11,8]'.. + 'no_prepend[]'.. + 'bgcolor[#080808BB;true]'.. + 'background[0,0;11,8;hall_plaque.png]' + +function hall.edit_sign(title, bottom, left, right) + local formspec = + sign_formspec.. + "field[0.5,1;7.5,0;title;"..esc("Title:")..";"..esc(title) .. "]" .. + "textarea[1,1.5;4.25,3;left;;"..esc(left).."]" .. + "textarea[6.25,1.5;4.25,3;right;;"..esc(right).."]" .. + "textarea[1,4;9.5,3;bottom;;"..esc(bottom).."]" .. + "button_exit[4,6.5;3,1;save;Save]" + return formspec +end + +function hall.view_sign(title, bottom, left, right) + local formspec = + sign_formspec.. + 'hypertext[0,0;11,1;;
]'.. + "textarea[1,1.5;4.25,3;;;"..esc(left).."]".. + "textarea[6.25,1.5;4.25,3;;;"..esc(right).."]".. + "textarea[1,4;9.5,3;;;"..esc(bottom).."]" + return formspec +end diff --git a/mods/hall/init.lua b/mods/hall/init.lua new file mode 100644 index 0000000..bd5c57c --- /dev/null +++ b/mods/hall/init.lua @@ -0,0 +1,13 @@ +hall = {} +hall.storage = minetest.get_mod_storage() + +dofile(minetest.get_modpath('hall')..'/crafts.lua') +dofile(minetest.get_modpath('hall')..'/formspec.lua') +dofile(minetest.get_modpath('hall')..'/mobs.lua') +dofile(minetest.get_modpath('hall')..'/nodes.lua') +--Privs School +dofile(minetest.get_modpath('hall')..'/areas.lua') +dofile(minetest.get_modpath('hall')..'/fire.lua') +dofile(minetest.get_modpath('hall')..'/lumberjack.lua') +dofile(minetest.get_modpath('hall')..'/markets.lua') +dofile(minetest.get_modpath('hall')..'/spill.lua') diff --git a/mods/hall/license.txt b/mods/hall/license.txt new file mode 100644 index 0000000..4c5a56e --- /dev/null +++ b/mods/hall/license.txt @@ -0,0 +1,7 @@ +Code is licensed MIT +Textures and models CC by SA 4.0 +Copyright 2020 Nathan Salapat + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/mods/hall/lumberjack.lua b/mods/hall/lumberjack.lua new file mode 100644 index 0000000..b23be06 --- /dev/null +++ b/mods/hall/lumberjack.lua @@ -0,0 +1,96 @@ +local priv_lumberjack_formspec_base = + 'size[12,7]'.. + 'no_prepend[]'.. + 'bgcolor[#080808BB;true]'.. + 'background[0,0;12,7;hall_chalkboard_bg.png]'.. + 'hypertext[0,.2;12,1;;
]' + +local esc = minetest.formspec_escape + +local lesson = "The lumberjack mod should automatically give you the lumberjack privilege after ".. + "you harvest enough trees and plant saplings, but it seems to not always work, so if you don't have ".. + "the privilege there is this course you can take to get it. :)\n".. + "The lumberjack privilege lets you chop and entire tree by just breaking one node at the bottom.\n".. + "There are no hard rules reguarding chopping down trees, but you should replant when possible so we ".. + "don't run out of wood.\n".. + "When cutting down a full tree your axe will take the combined damage of all the nodes, so a very large tree ".. + "may add a lot of wear. This is not a bug!" + +local priv_lumberjack_formspec_lesson = + priv_lumberjack_formspec_base.. + "textarea[.75,1.5;11.25,6;;;"..esc(lesson).."]" .. + 'button[4.5,5;3,1;go;Take Quiz]' + +local priv_lumberjack_formspec_1 = + priv_lumberjack_formspec_base.. + "textarea[1,1.5;11,3;;;What does the lumberjack priv let you do?]" .. + 'button[1,4;3,1;wrong;A) Grow an epic beard.]'.. + 'button[4.5,4;3,1;wrong;B) Do tricks with axes.]'.. + 'button[8,4;3,1;wrong;C) Ride log rafts.]'.. + 'button[1,5.5;3,1;wrong;D) Juggle chainsaws.]'.. + 'button[4.5,5.5;3,1;right;E) Chop down entire trees.]'.. + 'button[8,5.5;3,1;wrong;F) Tame blue oxen.]' + +local priv_lumberjack_formspec_2 = + priv_lumberjack_formspec_base.. + "textarea[1,1.5;11,3;;;Are you REQUIRED to replant every tree you cut down?]" .. + 'button[1,4;3,1;right;A) No]'.. + 'button[4.5,4;3,1;right;B) No]'.. + 'button[8,4;3,1;right;C) No]'.. + 'button[1,5.5;3,1;wrong;D) Yes]'.. + 'button[4.5,5.5;3,1;wrong;E) Yes]'.. + 'button[8,5.5;3,1;wrong;F) Yes]' + +local priv_lumberjack_formspec_3 = + priv_lumberjack_formspec_base.. + "textarea[1,1.5;11,3;;;You've passed the quiz! You now have the lumberjack privilege]".. + 'button_exit[4.5,5;3,1;;Exit]' + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if formname == 'hall:priv_lumberjack_lesson' then + if fields.go then + minetest.show_formspec(name, 'hall:priv_lumberjack_1', priv_lumberjack_formspec_1) + end + elseif formname == 'hall:priv_lumberjack_1' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_lumberjack_2', priv_lumberjack_formspec_2) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_lumberjack_lesson', priv_lumberjack_formspec_lesson) + end + elseif formname == 'hall:priv_lumberjack_2' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_lumberjack_3', priv_lumberjack_formspec_3) + local privs = minetest.get_player_privs(name) + privs.lumberjack = true + minetest.set_player_privs(name, privs) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_lumberjack_lesson', priv_lumberjack_formspec_lesson) + end + end +end) + +minetest.register_node('hall:priv_lumberjack', { + description = 'Lumberjack Course', + drawtype = 'mesh', + mesh = 'hall_chalkboard.obj', + tiles = {'hall_chalkboard_lumberjack.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, + on_rightclick = function(pos, node, clicker, itemstack) + local meta = minetest.get_meta(pos) + meta:set_string('infotext', 'Lumberjack Privs Course') + local name = clicker:get_player_name() + minetest.show_formspec(name, 'hall:priv_lumberjack_lesson', priv_lumberjack_formspec_lesson) + end, +}) diff --git a/mods/hall/markets.lua b/mods/hall/markets.lua new file mode 100644 index 0000000..46d89b8 --- /dev/null +++ b/mods/hall/markets.lua @@ -0,0 +1,149 @@ +local markets_formspec_base = + 'size[12,7]'.. + 'no_prepend[]'.. + 'bgcolor[#080808BB;true]'.. + 'background[0,0;12,7;hall_chalkboard_bg.png]'.. + 'hypertext[0,.2;12,1;;
]' + +local esc = minetest.formspec_escape + +local lesson = "The commodity markets create a network of 'shops' that you can sell and buy from. ".. + " Items can be placed for sale at any location, and be purchased from any other location. ".. + "This means you can place a Trading Post at your base to summon a caravan when you want to sell or buy without ".. + "needing to travel to a central location to access the market.\n".. + " Markets use coins, which can be gathered by killing mobs, or by converting gold ingots. ".. + "One gold ingot is equivalent to one thousand coins. You can add coins or gold to your account by clicking on the ".. + "'Your Inventory' tab in the market and placing the coins or gold in the input slot on the left. You can withdraw gold or coins ".. + "by typing in the value you want to withdraw and clicking 'Withdraw' on the right. A value of more than one thousand will ".. + "be automatically converted to gold, with any remainder being cashed out in coins.\n".. + " The markets create a free market, you are able to sell items for any price you want, and buyers can decide if you are ".. + "offering a fair deal or not. A savvy player can watch the markets buying items low and selling them high.\n".. + " To sell items add them to the market inventory on the 'Your Inventory' tab, and then click on the 'Market Orders' tab. ".. + "Use the search box to easily find the items in your inventory. To put the item up for sale click on the listing, enter the ".. + "quantity you want to sell and how many coins you want, and then click the sell button.\n".. + " If you want to buy an item that isn't listed for sale you can create a Buy order. Click on the listing for the item you want to buy, ".. + "enter the quantity you'd like to purchase, and how much you're willing to pay, and click on the Buy button. To buy an item that is listed ".. + "you need only click on the item, the quantity you want to purchase and a price equal or greater than the listed price.\n".. + " You can cancel your orders by double clicking on them in the list. If it was a sell order the items will be added back to your available ".. + "inventory in the 'Your Inventory' tab.\n".. + " You are limited to one thousand items in the market inventory at any one time." + + +local markets_formspec_lesson = + markets_formspec_base.. + "textarea[.75,1.5;11.25,4;;;"..esc(lesson).."]" .. + 'button[4.5,5;3,1;go;Test your knowledge]' + +local markets_formspec_1 = + markets_formspec_base.. + "textarea[1,1.5;11,3;;;A gold ingot can be converted into how many coins?]" .. + 'button[1,4;3,1;wrong;A) 1]'.. + 'button[4.5,4;3,1;wrong;B) 10]'.. + 'button[8,4;3,1;wrong;C) 100]'.. + 'button[1,5.5;3,1;right;D) 1,000]'.. + 'button[4.5,5.5;3,1;wrong;E) 10,000]'.. + 'button[8,5.5;3,1;wrong;F) 100,000]' + +local markets_formspec_2 = + markets_formspec_base.. + "textarea[1,1.5;11,3;;;What item will summon a caravan?]" .. + 'button[1,4;3,1;wrong;A) A Trader Mob]'.. + 'button[4.5,4;3,1;wrong;B) A Secret Keyword]'.. + 'button[8,4;3,1;wrong;C) A Caravan Scroll]'.. + 'button[1,5.5;3,1;wrong;D) A Pile of Zombie Teeth]'.. + 'button[4.5,5.5;3,1;wrong;E) A Diamond Block]'.. + 'button[8,5.5;3,1;right;F) A Trading Post]' + +local markets_formspec_3 = + markets_formspec_base.. + "textarea[1,1.5;11,3;;;Can you pull coins/gold out of the market?]" .. + 'button[1,4;3,1;right;A) Yes]'.. + 'button[4.5,4;3,1;right;B) Yes]'.. + "button[8,4;3,1;right;C) Yes]".. + "button[1,5.5;3,1;wrong;D) No]".. + 'button[4.5,5.5;3,1;wrong;E) No]'.. + "button[8,5.5;3,1;wrong;F) No]" + +local markets_formspec_4 = + markets_formspec_base.. + "textarea[1,1.5;11,3;;;How many items can you have in the market at once?]" .. + 'button[1,4;3,1;wrong;A) 1]'.. + 'button[4.5,4;3,1;wrong;B) 10]'.. + 'button[8,4;3,1;wrong;C) 100]'.. + 'button[1,5.5;3,1;right;D) 1,000]'.. + 'button[4.5,5.5;3,1;wrong;E) 10,000]'.. + 'button[8,5.5;3,1;wrong;F) 100,000]' + +local markets_formspec_5 = + markets_formspec_base.. + "textarea[1,1.5;11,3;;;You've passed the quiz! Here's a free trading post.]".. + 'button_exit[4.5,5;3,1;;Exit]' + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if formname == 'hall:markets_lesson' then + if fields.go then + minetest.show_formspec(name, 'hall:markets_1', markets_formspec_1) + end + elseif formname == 'hall:markets_1' then + if fields.right then + minetest.show_formspec(name, 'hall:markets_2', markets_formspec_2) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:markets_lesson', markets_formspec_lesson) + end + elseif formname == 'hall:markets_2' then + if fields.right then + minetest.show_formspec(name, 'hall:markets_3', markets_formspec_3) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:markets_lesson', markets_formspec_lesson) + end + elseif formname == 'hall:markets_3' then + if fields.right then + minetest.show_formspec(name, 'hall:markets_4', markets_formspec_4) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:markets_lesson', markets_formspec_lesson) + end + elseif formname == 'hall:markets_4' then + if fields.right then + minetest.show_formspec(name, 'hall:markets_5', markets_formspec_5) + local give = hall.storage:get_string(name..'_market') + if give ~= 'earned' then + local player_inv = player:get_inventory() + if player_inv:room_for_item('main', 'commoditymarket:caravan_post') then + player_inv:add_item('main', 'commoditymarket:caravan_post') + else + local drop_pos = player:get_pos() + minetest.add_item(drop_pos, 'commoditymarket:caravan_post') + end + hall.storage:set_string(name..'_market', 'earned') + end + elseif fields.wrong then + minetest.show_formspec(name, 'hall:markets_lesson', markets_formspec_lesson) + end + end +end) + +minetest.register_node('hall:markets', { + description = 'Markets Course', + drawtype = 'mesh', + mesh = 'hall_chalkboard.obj', + tiles = {'hall_chalkboard_markets.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, + on_rightclick = function(pos, node, clicker, itemstack) + local meta = minetest.get_meta(pos) + local name = clicker:get_player_name() + meta:set_string('infotext', 'Market Course') + minetest.show_formspec(name, 'hall:markets_lesson', markets_formspec_lesson) + end, +}) diff --git a/mods/hall/mobs.lua b/mods/hall/mobs.lua new file mode 100644 index 0000000..74d7b94 --- /dev/null +++ b/mods/hall/mobs.lua @@ -0,0 +1,131 @@ +minetest.register_node('hall:scorpion', { + description = 'Scorpion', + drawtype = 'mesh', + mesh = 'hall_scorpion.obj', + tiles = {'spawn_quartz1.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = { + {-.6, -.5, -.6, .6, .4, .6} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {-.6, -.5, -.6, .6, .4, .6} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, +}) + +minetest.register_node('hall:Monster', { + description = 'Monster', + drawtype = 'mesh', + mesh = 'hall_monster.obj', + tiles = {'spawn_quartz1.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = { + {-.6, -.5, -.6, .6, .4, .6} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {-.6, -.5, -.6, .6, .4, .6} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, +}) + +minetest.register_node('hall:fairy', { + description = 'Fairy', + drawtype = 'mesh', + mesh = 'hall_fairy.obj', + tiles = {'spawn_quartz1.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = { + {-.2, -.5, -.2, .2, .2, .2} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {-.2, -.5, -.2, .2, .2, .2} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, +}) + +minetest.register_node('hall:goblin', { + description = 'Goblin', + drawtype = 'mesh', + mesh = 'hall_goblin.obj', + tiles = {'spawn_quartz1.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = { + {-.3, -.5, -.3, .3, .4, .3} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {-.3, -.5, -.3, .3, .4, .3} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, +}) + +minetest.register_node('hall:larva', { + description = 'Nether Lava', + drawtype = 'mesh', + mesh = 'hall_larva.obj', + tiles = {'spawn_quartz1.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = { + {-.3, 0, -.3, .3, .4, .3} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {-.3, 0, -.3, .3, .4, .3} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, +}) + +minetest.register_node('hall:gnome', { + description = 'Gnome', + drawtype = 'mesh', + mesh = 'hall_gnome.obj', + tiles = {'spawn_quartz1.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = { + {-.3, 0, -.3, .3, .4, .3} + } + }, + collision_box = { + type = 'fixed', + fixed = { + {-.3, 0, -.3, .3, .4, .3} + } + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, +}) diff --git a/mods/hall/mod.conf b/mods/hall/mod.conf new file mode 100644 index 0000000..ffe356d --- /dev/null +++ b/mods/hall/mod.conf @@ -0,0 +1,2 @@ +name = hall +depends = default diff --git a/mods/hall/models/hall_chalkboard.obj b/mods/hall/models/hall_chalkboard.obj new file mode 100644 index 0000000..183fd71 --- /dev/null +++ b/mods/hall/models/hall_chalkboard.obj @@ -0,0 +1,40 @@ +# Blender v2.82 (sub 7) OBJ File: 'chalkboard.blend' +# www.blender.org +o Cube.001 +v 1.000000 -0.750000 0.437500 +v 1.000000 0.500000 0.437500 +v 1.000000 -0.750000 0.500000 +v 1.000000 0.500000 0.500000 +v -1.000000 -0.750000 0.437500 +v -1.000000 0.500000 0.437500 +v -1.000000 -0.750000 0.500000 +v -1.000000 0.500000 0.500000 +vt 0.000000 0.203125 +vt 0.031250 0.203125 +vt 0.031250 0.796875 +vt 0.000000 0.796875 +vt 0.968750 0.203125 +vt 1.000000 0.203125 +vt 1.000000 0.796875 +vt 0.968750 0.796875 +vt 1.000000 0.203125 +vt 0.000000 0.796875 +vt 0.000000 0.203125 +vt 1.000000 0.203125 +vt 1.000000 0.234375 +vt -0.000000 0.234375 +vt 0.000000 0.765625 +vt 1.000000 0.765625 +vt 1.000000 0.796875 +vt 0.000000 0.796875 +vn 1.0000 0.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 7/5/2 8/6/2 6/7/2 5/8/2 +f 5/9/3 6/7/3 2/10/3 1/1/3 +f 3/11/4 7/12/4 5/13/4 1/14/4 +f 8/15/5 4/16/5 2/17/5 6/18/5 diff --git a/mods/hall/models/hall_fairy.obj b/mods/hall/models/hall_fairy.obj new file mode 100644 index 0000000..f520a65 --- /dev/null +++ b/mods/hall/models/hall_fairy.obj @@ -0,0 +1,189 @@ +# Blender v2.80 (sub 75) OBJ File: 'Hall.blend' +# www.blender.org +v 0.100000 0.298437 -0.096683 +v 0.100000 0.298437 0.103317 +v 0.200000 -0.001563 0.143317 +v 0.200000 -0.001563 -0.146683 +v -0.100000 0.298437 -0.096683 +v -0.100000 0.698437 -0.096683 +v 0.100000 0.698437 -0.096683 +v -0.100000 0.298437 0.103317 +v -0.200000 -0.001563 0.143317 +v -0.200000 -0.001563 -0.146683 +v -0.100000 0.698437 0.103317 +v 0.100000 0.698437 0.103317 +v -0.170000 0.257759 -0.049363 +v -0.170000 0.257759 0.046069 +v -0.170000 0.507759 0.046069 +v -0.170000 0.507759 -0.049363 +v -0.100000 0.507759 -0.049363 +v -0.100000 0.257759 -0.049363 +v -0.100000 0.257759 0.046069 +v -0.100000 0.507759 0.046069 +v 0.170000 0.257759 0.046069 +v 0.170000 0.257759 -0.049363 +v 0.170000 0.507759 -0.049363 +v 0.170000 0.507759 0.046069 +v 0.100000 0.507759 0.046069 +v 0.100000 0.257759 0.046069 +v 0.100000 0.257759 -0.049363 +v 0.100000 0.507759 -0.049363 +v 0.099000 0.296937 -0.095708 +v 0.198000 -0.000063 -0.145208 +v 0.198000 -0.000063 0.141892 +v 0.099000 0.296937 0.102292 +v -0.198000 -0.000063 0.141892 +v -0.099000 0.296937 0.102292 +v -0.099000 0.296937 -0.095708 +v -0.198000 -0.000063 -0.145208 +vt 0.039062 0.250000 +vt 0.203125 0.250000 +vt 0.234375 0.000000 +vt 0.000000 0.000000 +vt 0.539062 0.671875 +vt 0.703125 0.671875 +vt 0.703125 1.000000 +vt 0.539062 1.000000 +vt 0.492188 0.250000 +vt 0.328125 0.250000 +vt 0.242188 0.000000 +vt 0.570312 0.000000 +vt 0.328125 0.250000 +vt 0.492188 0.250000 +vt 0.570312 0.000000 +vt 0.242188 0.000000 +vt 0.703125 0.500000 +vt 0.703125 0.664062 +vt 0.539062 0.664062 +vt 0.539062 0.500000 +vt 0.039062 0.250000 +vt 0.203125 0.250000 +vt 0.203125 0.578125 +vt 0.039062 0.578125 +vt 0.039062 0.578125 +vt 0.203125 0.578125 +vt 0.492188 0.578125 +vt 0.328125 0.578125 +vt 0.000000 0.000000 +vt 0.234375 0.000000 +vt 0.585938 0.203125 +vt 0.664062 0.203125 +vt 0.664062 0.406250 +vt 0.585938 0.406250 +vt 0.523438 0.406250 +vt 0.523438 0.203125 +vt 0.585938 0.148438 +vt 0.664062 0.148438 +vt 0.726562 0.203125 +vt 0.726562 0.406250 +vt 0.664062 0.460938 +vt 0.585938 0.460938 +vt 0.664062 0.203125 +vt 0.585938 0.203125 +vt 0.585938 0.406250 +vt 0.664062 0.406250 +vt 0.726562 0.406250 +vt 0.726562 0.203125 +vt 0.664062 0.148438 +vt 0.585938 0.148438 +vt 0.523438 0.203125 +vt 0.523438 0.406250 +vt 0.585938 0.460938 +vt 0.664062 0.460938 +vt 0.039062 0.250000 +vt 0.000000 0.000000 +vt 0.234375 0.000000 +vt 0.203125 0.250000 +vt 0.492188 0.250000 +vt 0.570312 0.000000 +vt 0.242188 0.000000 +vt 0.328125 0.250000 +vt 0.328125 0.250000 +vt 0.242188 0.000000 +vt 0.570312 0.000000 +vt 0.492188 0.250000 +vt 0.203125 0.250000 +vt 0.234375 0.000000 +vt 0.000000 0.000000 +vt 0.039062 0.250000 +vn 0.9487 0.3162 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.1322 0.9912 +vn 0.0000 0.1644 -0.9864 +vn 0.0000 1.0000 0.0000 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn -0.9487 0.3162 0.0000 +vn 0.0000 -1.0000 -0.0000 +vn -0.9487 -0.3162 0.0000 +vn 0.0000 -0.1322 -0.9912 +vn 0.0000 -0.1644 0.9864 +vn 0.9487 -0.3162 0.0000 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 1/5/2 5/6/2 6/7/2 7/8/2 +f 2/9/3 8/10/3 9/11/3 3/12/3 +f 5/13/4 1/14/4 4/15/4 10/16/4 +f 7/17/5 6/18/5 11/19/5 12/20/5 +f 5/21/6 8/22/6 11/23/6 6/24/6 +f 2/2/7 1/1/7 7/25/7 12/26/7 +f 8/10/8 2/9/8 12/27/8 11/28/8 +f 8/22/9 5/21/9 10/29/9 9/30/9 +f 13/31/6 14/32/6 15/33/6 16/34/6 +f 17/35/2 18/36/2 13/31/2 16/34/2 +f 18/37/10 19/38/10 14/32/10 13/31/10 +f 19/39/8 20/40/8 15/33/8 14/32/8 +f 20/41/5 17/42/5 16/34/5 15/33/5 +f 21/43/7 22/44/7 23/45/7 24/46/7 +f 25/47/8 26/48/8 21/43/8 24/46/8 +f 26/49/10 27/50/10 22/44/10 21/43/10 +f 27/51/2 28/52/2 23/45/2 22/44/2 +f 28/53/5 25/54/5 24/46/5 23/45/5 +f 29/55/11 30/56/11 31/57/11 32/58/11 +f 32/59/12 31/60/12 33/61/12 34/62/12 +f 35/63/13 36/64/13 30/65/13 29/66/13 +f 34/67/14 33/68/14 36/69/14 35/70/14 +v -0.437500 -0.500000 0.437500 +v -0.437500 0.000000 0.437500 +v -0.437500 -0.500000 -0.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 -0.500000 0.437500 +v 0.437500 0.000000 0.437500 +v 0.437500 -0.500000 -0.437500 +v 0.437500 0.000000 -0.437500 +vt 1.000000 0.500000 +vt 0.733333 0.500000 +vt 0.733333 0.000000 +vt 1.000000 0.000000 +vt 0.733333 0.500000 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.733333 1.000000 +vt 0.466667 1.000000 +vt 0.466667 0.500000 +vt 0.733333 0.500000 +vt 0.466667 0.000000 +vt 0.733333 0.000000 +vt 0.466667 0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.466666 0.500000 +vt 0.466667 1.000000 +vt 0.466666 0.000000 +vt 0.466667 0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 37/71/15 38/72/15 40/73/15 39/74/15 +f 39/75/16 40/76/16 44/77/16 43/78/16 +f 43/78/17 44/79/17 42/80/17 41/81/17 +f 41/82/18 42/83/18 38/72/18 37/84/18 +f 39/85/19 43/86/19 41/87/19 37/88/19 +f 44/89/20 40/90/20 38/91/20 42/92/20 diff --git a/mods/hall/models/hall_gnome.obj b/mods/hall/models/hall_gnome.obj new file mode 100644 index 0000000..04e3f71 --- /dev/null +++ b/mods/hall/models/hall_gnome.obj @@ -0,0 +1,189 @@ +# Blender v2.80 (sub 75) OBJ File: 'gnome.blend' +# www.blender.org +mtllib hall_gnome.mtl +o Cube.001_Cube.002 +v -0.000222 0.780882 0.022057 +v -0.022057 0.780882 0.000241 +v 0.021594 0.780901 0.000222 +v -0.000241 0.780901 -0.021594 +v 0.000076 0.249924 0.174603 +v -0.174603 0.249924 0.000076 +v -0.000076 0.250076 -0.174603 +v 0.174603 0.250076 -0.000076 +v -0.174563 0.157326 0.000036 +v -0.000036 0.157479 -0.174644 +v 0.174644 0.157479 -0.000116 +v 0.000116 0.157327 0.174563 +v -0.000034 0.503023 0.174714 +v -0.174714 0.503023 0.000186 +v -0.000186 0.503176 -0.174493 +v 0.174493 0.503176 0.000034 +v 0.065476 0.211045 0.058182 +v 0.000000 0.201360 -0.006574 +v 0.130952 0.201360 -0.006574 +v 0.065476 0.191676 -0.071330 +v 0.065476 0.014455 0.087583 +v -0.000000 0.004771 0.022826 +v 0.130952 0.004771 0.022826 +v 0.065476 -0.004913 -0.041930 +v -0.065476 0.016348 -0.090599 +v -0.000000 0.005290 -0.026064 +v -0.130952 0.005290 -0.026064 +v -0.065476 -0.005767 0.038472 +v -0.065476 0.212269 -0.057029 +v 0.000000 0.201211 0.007506 +v -0.130952 0.201211 0.007506 +v -0.065476 0.190153 0.072042 +vt 0.301650 1.000000 +vt 0.000000 0.890668 +vt 0.000000 0.859430 +vt 0.301650 0.750099 +vt 0.301650 1.000000 +vt 0.000000 0.890668 +vt 0.000000 0.859430 +vt 0.301650 0.750099 +vt 0.301650 1.000000 +vt 0.000000 0.890668 +vt 0.000000 0.859430 +vt 0.301650 0.750099 +vt 0.301650 1.000000 +vt 0.000000 0.890668 +vt 0.000000 0.859430 +vt 0.301650 0.750098 +vt 0.000000 1.000000 +vt 0.000000 0.968762 +vt 0.031238 0.968762 +vt 0.031238 1.000000 +vt 0.500000 0.000197 +vt 0.500000 0.093910 +vt 0.250098 0.093910 +vt 0.250098 0.000197 +vt 0.749901 0.000197 +vt 0.749901 0.093910 +vt 0.999803 0.000197 +vt 0.999803 0.093910 +vt 0.000197 0.093910 +vt 0.000197 0.000197 +vt 0.249901 0.421816 +vt 0.249901 0.671718 +vt 0.000000 0.671718 +vt 0.000000 0.421816 +vt 0.500000 0.350059 +vt 0.250098 0.350059 +vt 0.749901 0.350059 +vt 0.999803 0.350059 +vt 0.000197 0.350059 +vt 1.000000 0.559876 +vt 0.860130 0.559876 +vt 0.860130 0.699746 +vt 1.000000 0.699746 +vt 0.720260 1.000000 +vt 0.720260 0.699746 +vt 0.580391 0.699746 +vt 0.580391 1.000000 +vt 1.000000 1.000000 +vt 0.860130 1.000000 +vt 0.440521 0.699746 +vt 0.440521 1.000000 +vt 0.860130 1.000000 +vt 0.860130 0.699746 +vt 1.000000 0.699746 +vt 1.000000 1.000000 +vt 1.000000 0.559876 +vt 0.860130 0.559876 +vt 0.580390 1.000000 +vt 0.580391 0.699746 +vt 0.720260 0.699746 +vt 0.720260 1.000000 +vt 0.440521 1.000000 +vt 0.440521 0.699746 +vn -0.6589 0.3619 0.6595 +vn -0.6595 0.3624 -0.6586 +vn 0.6586 0.3630 -0.6592 +vn 0.6592 0.3624 0.6589 +vn -0.0004 1.0000 0.0004 +vn 0.7074 0.0000 0.7068 +vn 0.7068 0.0006 -0.7074 +vn -0.7074 -0.0000 -0.7068 +vn -0.7068 -0.0006 0.7074 +vn 0.0004 -1.0000 -0.0004 +vn 0.0000 -0.9890 0.1479 +vn 0.7071 -0.1046 -0.6993 +vn -0.7071 0.1046 0.6993 +vn 0.7071 0.1046 0.6993 +vn -0.7071 -0.1046 -0.6993 +vn 0.7071 -0.1194 0.6969 +vn 0.0000 -0.9856 -0.1689 +vn -0.7071 0.1194 -0.6969 +vn -0.7071 -0.1194 0.6969 +vn 0.7071 0.1194 -0.6969 +usemtl Material.001 +s off +f 13/1/1 1/2/1 2/3/1 14/4/1 +f 14/5/2 2/6/2 4/7/2 15/8/2 +f 15/9/3 4/10/3 3/11/3 16/12/3 +f 16/13/4 3/14/4 1/15/4 13/16/4 +f 4/17/5 2/18/5 1/19/5 3/20/5 +f 11/21/6 8/22/6 5/23/6 12/24/6 +f 10/25/7 7/26/7 8/22/7 11/21/7 +f 9/27/8 6/28/8 7/26/8 10/25/8 +f 12/24/9 5/23/9 6/29/9 9/30/9 +f 12/31/10 9/32/10 10/33/10 11/34/10 +f 8/22/6 16/35/6 13/36/6 5/23/6 +f 7/26/7 15/37/7 16/35/7 8/22/7 +f 6/28/8 14/38/8 15/37/8 7/26/8 +f 5/23/9 13/36/9 14/39/9 6/29/9 +f 24/40/11 23/41/11 21/42/11 22/43/11 +f 19/44/12 23/45/12 24/46/12 20/47/12 +f 18/48/13 22/43/13 21/42/13 17/49/13 +f 17/49/14 21/42/14 23/45/14 19/44/14 +f 20/47/15 24/46/15 22/50/15 18/51/15 +f 32/52/16 28/53/16 26/54/16 30/55/16 +f 25/56/17 26/54/17 28/53/17 27/57/17 +f 29/58/18 25/59/18 27/60/18 31/61/18 +f 31/61/19 27/60/19 28/53/19 32/52/19 +f 30/62/20 26/63/20 25/59/20 29/58/20 +o Cube +v -0.500000 -0.500000 0.500000 +v -0.500000 0.000000 0.500000 +v -0.500000 -0.500000 -0.500000 +v -0.500000 0.000000 -0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 0.000000 0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.000000 -0.500000 +vt 1.000000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.500000 +vt 1.000000 0.500000 +vt 0.750000 0.500000 +vt 0.500000 0.500000 +vt 0.500000 0.000000 +vt 0.750000 0.000000 +vt 1.000000 0.500000 +vt 0.750000 0.500000 +vt 0.750000 0.000000 +vt 1.000000 0.000000 +vt 0.500000 0.500000 +vt 0.750000 0.500000 +vt 0.500000 1.000000 +vt 0.500000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.500000 0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl None +s off +f 33/64/21 34/65/21 36/66/21 35/67/21 +f 35/68/22 36/69/22 40/70/22 39/71/22 +f 39/72/23 40/73/23 38/74/23 37/75/23 +f 37/76/24 38/77/24 34/65/24 33/78/24 +f 35/79/25 39/80/25 37/81/25 33/82/25 +f 40/70/26 36/69/26 34/83/26 38/84/26 diff --git a/mods/hall/models/hall_goblin.obj b/mods/hall/models/hall_goblin.obj new file mode 100644 index 0000000..927cf65 --- /dev/null +++ b/mods/hall/models/hall_goblin.obj @@ -0,0 +1,385 @@ +# Blender v2.80 (sub 75) OBJ File: 'Hall.blend' +# www.blender.org +v -0.437500 -0.500000 0.437500 +v -0.437500 0.000000 0.437500 +v -0.437500 -0.500000 -0.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 -0.500000 0.437500 +v 0.437500 0.000000 0.437500 +v 0.437500 -0.500000 -0.437500 +v 0.437500 0.000000 -0.437500 +vt 1.000000 0.500000 +vt 0.733333 0.500000 +vt 0.733333 0.000000 +vt 1.000000 0.000000 +vt 0.733333 0.500000 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.733333 1.000000 +vt 0.466667 1.000000 +vt 0.466667 0.500000 +vt 0.733333 0.500000 +vt 0.466667 0.000000 +vt 0.733333 0.000000 +vt 0.466667 0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.466666 0.500000 +vt 0.466667 1.000000 +vt 0.466666 0.000000 +vt 0.466667 0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 7/8/3 8/9/3 6/10/3 5/11/3 +f 5/12/4 6/13/4 2/2/4 1/14/4 +f 3/15/5 7/16/5 5/17/5 1/18/5 +f 8/19/6 4/20/6 2/21/6 6/22/6 +v 0.089456 0.653278 0.027069 +v -0.110544 0.653278 0.027069 +v -0.110544 0.335861 0.026917 +v 0.089456 0.335861 0.026917 +v -0.110544 0.653345 -0.112686 +v -0.110544 0.335928 -0.112839 +v 0.089456 0.653345 -0.112686 +v 0.089456 0.335928 -0.112839 +v -0.010544 0.335873 -0.076190 +v -0.010544 -0.001627 -0.076190 +v -0.010544 -0.001627 0.023810 +v -0.010544 0.335873 0.023810 +v -0.110593 0.652115 -0.030842 +v -0.210593 0.652115 -0.030820 +v -0.210568 0.477327 0.077347 +v -0.110568 0.477329 0.077325 +v -0.110611 0.599493 -0.115876 +v -0.110586 0.424706 -0.007709 +v -0.110544 -0.001627 0.023810 +v -0.110544 -0.001627 -0.076190 +v -0.110544 0.335873 -0.076190 +v -0.010524 0.858841 -0.236701 +v -0.151980 0.858839 -0.095314 +v -0.010592 0.858841 0.046142 +v 0.130863 0.858841 -0.095246 +v 0.089456 0.335873 -0.076190 +v 0.089456 -0.001627 -0.076190 +v -0.210555 0.392294 0.129970 +v -0.110555 0.392296 0.129948 +v 0.189524 0.599491 -0.115859 +v 0.089523 0.599493 -0.115880 +v 0.089506 0.652117 -0.030846 +v 0.189506 0.652115 -0.030825 +v 0.089456 -0.001627 0.023810 +v -0.010590 0.658842 0.046142 +v -0.151977 0.658840 -0.095314 +v -0.210611 0.599491 -0.115854 +v -0.210586 0.424704 -0.007687 +v 0.189480 0.477327 0.077342 +v 0.189498 0.424704 -0.007692 +v 0.089498 0.424706 -0.007714 +v 0.089480 0.477329 0.077320 +v -0.110573 0.339672 0.044914 +v 0.089456 0.653894 0.195569 +v -0.110544 0.653894 0.195569 +v -0.110544 0.482759 0.195663 +v 0.089456 0.482759 0.195663 +v 0.089456 0.653811 0.042217 +v 0.089456 0.482676 0.042312 +v -0.110544 0.482676 0.042312 +v -0.110544 0.653811 0.042217 +v -0.010522 0.658842 -0.236701 +v 0.130865 0.658842 -0.095246 +v 0.089485 0.339672 0.044910 +v 0.189486 0.339670 0.044932 +v 0.189468 0.392296 0.129965 +v 0.089468 0.392296 0.129944 +v -0.210573 0.339670 0.044936 +v 0.189521 0.234423 -0.125136 +v 0.189533 0.319458 -0.177760 +v -0.210621 0.319458 -0.177755 +v -0.210609 0.234423 -0.125132 +v 0.089533 0.319460 -0.177782 +v 0.089521 0.234425 -0.125158 +v -0.110621 0.319458 -0.177777 +v -0.110609 0.234425 -0.125153 +vt 0.625000 0.375000 +vt 0.500000 0.375000 +vt 0.500000 0.000000 +vt 0.625000 0.000000 +vt 0.437500 0.375000 +vt 0.437500 0.000000 +vt 0.312500 0.375000 +vt 0.312500 0.000000 +vt 0.562500 0.375000 +vt 0.562500 0.500000 +vt 0.437500 0.500000 +vt 0.437500 0.375000 +vt 0.437500 0.500000 +vt 0.312500 0.500000 +vt 0.187500 0.375000 +vt 0.187500 0.000000 +vt 0.125000 0.000000 +vt 0.125000 0.375000 +vt 0.812500 0.187500 +vt 0.875000 0.187500 +vt 0.875000 0.375000 +vt 0.812500 0.375000 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.000000 +vt 0.750000 0.000000 +vt 0.187500 0.375000 +vt 0.187500 0.500000 +vt 0.125000 0.500000 +vt 0.125000 0.375000 +vt 0.000000 0.375000 +vt 0.062500 0.375000 +vt 0.062500 0.000000 +vt 0.000000 0.000000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.125000 1.000000 +vt 0.125000 0.750000 +vt 0.250000 0.375000 +vt 0.187500 0.375000 +vt 0.187500 0.000000 +vt 0.250000 0.000000 +vt 0.125000 0.375000 +vt 0.125000 0.000000 +vt 0.062500 0.000000 +vt 0.062500 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.000000 +vt 0.812500 0.093750 +vt 0.875000 0.093750 +vt 0.875000 0.187500 +vt 0.812500 0.187500 +vt 0.687500 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.500000 +vt 0.687500 0.500000 +vt 0.187500 0.000000 +vt 0.187500 0.375000 +vt 0.000000 0.375000 +vt 0.000000 0.000000 +vt 0.062500 0.000000 +vt 0.062500 0.375000 +vt 0.250000 0.375000 +vt 0.250000 0.000000 +vt 0.375000 0.500000 +vt 0.375000 0.750000 +vt 0.250000 0.750000 +vt 0.250000 0.500000 +vt 0.125000 0.500000 +vt 0.062500 0.500000 +vt 0.687500 0.375000 +vt 0.750000 0.187500 +vt 0.687500 0.187500 +vt 0.687500 0.375000 +vt 0.625000 0.375000 +vt 0.625000 0.187500 +vt 0.687500 0.187500 +vt 0.687500 0.375000 +vt 0.687500 0.187500 +vt 0.625000 0.187500 +vt 0.625000 0.375000 +vt 0.687500 0.500000 +vt 0.750000 0.500000 +vt 0.687500 0.187500 +vt 0.750000 0.187500 +vt 0.125000 0.375000 +vt 0.125000 0.500000 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 0.812500 0.375000 +vt 0.812500 0.187500 +vt 0.812500 0.281250 +vt 0.750000 0.281250 +vt 0.750000 0.187500 +vt 0.875000 0.187500 +vt 0.875000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.187500 +vt 0.125000 0.500000 +vt 1.000000 0.375000 +vt 0.875000 0.375000 +vt 0.875000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.375000 +vt 1.000000 0.000000 +vt 0.875000 0.000000 +vt 0.875000 0.375000 +vt 1.000000 0.343750 +vt 0.875000 0.343750 +vt 0.984375 0.000000 +vt 0.984375 0.375000 +vt 0.890625 0.375000 +vt 0.890625 0.000000 +vt 0.875000 0.031250 +vt 1.000000 0.031250 +vt 0.125000 0.500000 +vt 0.125000 0.750000 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 0.375000 1.000000 +vt 0.375000 0.750000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.500000 0.500000 +vt 0.500000 0.750000 +vt 0.875000 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.281250 +vt 0.875000 0.281250 +vt 0.812500 0.187500 +vt 0.812500 0.281250 +vt 0.875000 0.281250 +vt 0.875000 0.187500 +vt 0.687500 0.218750 +vt 0.625000 0.218750 +vt 0.625000 0.000000 +vt 0.687500 0.000000 +vt 0.687500 0.281250 +vt 0.625000 0.281250 +vt 0.625000 0.187500 +vt 0.812500 0.093750 +vt 0.875000 0.093750 +vt 0.875000 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.281250 +vt 0.812500 0.187500 +vt 0.750000 0.187500 +vt 0.750000 0.281250 +vt 0.687500 0.281250 +vt 0.625000 0.187500 +vt 0.625000 0.281250 +vt 0.625000 0.218750 +vt 0.687500 0.218750 +vt 0.687500 0.000000 +vt 0.625000 0.000000 +vt 0.750000 0.500000 +vt 0.812500 0.500000 +vt 0.812500 0.375000 +vt 0.750000 0.375000 +vt 0.812500 0.500000 +vt 0.750000 0.500000 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.750000 0.218750 +vt 0.812500 0.218750 +vt 0.812500 0.000000 +vt 0.750000 0.000000 +vt 0.812500 0.218750 +vt 0.750000 0.218750 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 0.812500 0.218750 +vt 0.875000 0.218750 +vt 0.875000 0.000000 +vt 0.812500 0.000000 +vt 0.812500 0.218750 +vt 0.875000 0.218750 +vt 0.875000 0.000000 +vt 0.812500 0.000000 +vt 0.750000 0.218750 +vt 0.750000 0.000000 +vt 0.750000 0.218750 +vt 0.750000 0.000000 +vn 0.0000 -0.0005 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0005 -1.0000 +vn -0.0000 -1.0000 -0.0005 +vn 0.0000 1.0000 0.0005 +vn 0.0002 0.5262 0.8503 +vn 1.0000 0.0000 -0.0002 +vn 0.0000 -1.0000 0.0000 +vn -0.0000 1.0000 0.0000 +vn 0.0155 -0.0046 0.9999 +vn 0.0000 0.0000 -1.0000 +vn 0.0001 0.8503 -0.5262 +vn -0.0155 -0.0046 0.9999 +vn 1.0000 -0.0000 0.0000 +vn -0.7073 -0.0000 0.7069 +vn -0.0001 1.0000 0.0001 +vn -0.0002 -0.5262 -0.8503 +vn -1.0000 -0.0000 0.0002 +vn 1.0000 -0.0000 0.0002 +vn -0.0001 0.8503 -0.5262 +vn 0.0002 -0.5262 -0.8503 +vn -1.0000 0.0000 -0.0002 +vn -0.0002 0.5262 0.8503 +vn 0.0001 1.0000 0.0001 +vn 0.0000 0.0005 1.0000 +vn -0.0000 -0.0006 -1.0000 +vn -0.0000 1.0000 -0.0005 +vn 0.0000 -1.0000 0.0005 +vn 0.7073 0.0000 -0.7069 +vn -0.7069 -0.0000 -0.7073 +vn 0.7069 0.0000 0.7073 +vn -0.0001 -0.8503 0.5262 +vn 0.0001 -0.8503 0.5262 +s 1 +f 9/23/7 10/24/7 11/25/7 12/26/7 +f 10/24/8 13/27/8 14/28/8 11/25/8 +f 13/27/9 15/29/9 16/30/9 14/28/9 +f 16/31/10 12/32/10 11/33/10 14/34/10 +f 13/27/11 10/35/11 9/36/11 15/29/11 +f 17/37/8 18/38/8 19/39/8 20/40/8 +f 21/41/12 22/42/12 23/43/12 24/44/12 +f 25/45/13 21/46/13 24/47/13 26/48/13 +f 18/49/14 19/50/14 27/51/14 28/52/14 +f 11/53/8 29/54/8 28/55/8 27/56/8 +f 30/57/15 31/58/15 32/59/15 33/60/15 +f 20/61/16 11/62/16 27/63/16 19/64/16 +f 34/65/17 35/66/17 18/67/17 17/68/17 +f 29/69/17 17/68/17 18/67/17 28/70/17 +f 24/71/12 23/72/12 36/73/12 37/74/12 +f 38/75/18 39/76/18 40/77/18 41/78/18 +f 20/61/19 19/64/19 42/79/19 12/80/19 +f 12/81/20 42/82/20 35/83/20 34/84/20 +f 9/85/20 12/86/20 16/30/20 15/29/20 +f 43/87/21 32/88/21 31/89/21 44/90/21 +f 29/69/22 11/91/22 20/92/22 17/68/22 +f 45/93/23 25/45/23 26/94/23 46/95/23 +f 22/96/24 45/97/24 46/98/24 23/99/24 +f 41/100/25 47/101/25 48/102/25 38/103/25 +f 45/93/26 22/104/26 21/105/26 25/45/26 +f 38/75/27 48/106/27 49/107/27 39/76/27 +f 18/49/14 35/108/14 42/109/14 19/50/14 +f 39/76/28 49/110/28 50/111/28 40/112/28 +f 26/113/13 24/114/13 37/115/13 51/116/13 +f 40/117/29 50/118/29 47/119/29 41/120/29 +f 34/65/30 17/68/30 20/92/30 12/121/30 +f 52/122/31 53/123/31 54/124/31 55/125/31 +f 56/126/32 57/127/32 58/128/32 59/129/32 +f 53/123/33 52/122/33 56/130/33 59/131/33 +f 52/122/20 55/125/20 57/132/20 56/133/20 +f 54/124/8 53/123/8 59/134/8 58/135/8 +f 55/125/34 54/124/34 58/136/34 57/137/34 +f 60/138/35 30/139/35 33/140/35 61/141/35 +f 60/142/14 61/143/14 43/144/14 44/145/14 +f 44/90/36 31/89/36 30/139/36 60/138/36 +f 61/146/37 33/147/37 32/88/37 43/87/37 +f 62/148/38 63/149/38 64/150/38 65/151/38 +f 51/152/39 37/153/39 36/154/39 66/155/39 +f 48/156/25 63/157/25 67/158/25 68/159/25 +f 48/106/25 47/160/25 64/161/25 63/162/25 +f 47/163/29 50/164/29 65/165/29 64/166/29 +f 50/167/28 49/168/28 62/169/28 65/170/28 +f 23/171/24 46/95/24 66/172/24 36/173/24 +f 66/174/24 46/175/24 69/176/24 70/177/24 +f 71/178/27 68/179/27 67/180/27 72/181/27 +f 69/182/23 73/183/23 74/184/23 70/185/23 +f 62/186/28 49/187/28 71/188/28 72/189/28 +f 26/190/13 51/191/13 74/192/13 73/193/13 +f 63/194/38 62/195/38 72/196/38 67/197/38 +f 51/198/39 66/199/39 70/200/39 74/201/39 +f 49/202/18 48/156/18 68/159/18 71/203/18 +f 46/175/26 26/204/26 73/205/26 69/176/26 diff --git a/mods/hall/models/hall_larva.obj b/mods/hall/models/hall_larva.obj new file mode 100644 index 0000000..bdab04c --- /dev/null +++ b/mods/hall/models/hall_larva.obj @@ -0,0 +1,225 @@ +# Blender v2.80 (sub 75) OBJ File: 'Hall.blend' +# www.blender.org +v -0.437500 -0.500000 0.437500 +v -0.437500 0.000000 0.437500 +v -0.437500 -0.500000 -0.437500 +v -0.437500 0.000000 -0.437500 +v 0.437500 -0.500000 0.437500 +v 0.437500 0.000000 0.437500 +v 0.437500 -0.500000 -0.437500 +v 0.437500 0.000000 -0.437500 +vt 1.000000 0.500000 +vt 0.733333 0.500000 +vt 0.733333 0.000000 +vt 1.000000 0.000000 +vt 0.733333 0.500000 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.733333 1.000000 +vt 0.466667 1.000000 +vt 0.466667 0.500000 +vt 0.733333 0.500000 +vt 0.466667 0.000000 +vt 0.733333 0.000000 +vt 0.466667 0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.466666 0.500000 +vt 0.466667 1.000000 +vt 0.466666 0.000000 +vt 0.466667 0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.000000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 7/8/3 8/9/3 6/10/3 5/11/3 +f 5/12/4 6/13/4 2/2/4 1/14/4 +f 3/15/5 7/16/5 5/17/5 1/18/5 +f 8/19/6 4/20/6 2/21/6 6/22/6 +v 0.167323 0.333315 -0.152773 +v 0.167426 0.333315 0.048000 +v 0.167426 -0.001306 0.048000 +v 0.167323 -0.001306 -0.152773 +v -0.167299 -0.001306 -0.152601 +v -0.167299 0.333315 -0.152601 +v -0.167196 0.333315 0.048172 +v -0.167196 -0.001306 0.048172 +v -0.125483 0.007059 -0.319998 +v -0.125483 0.258025 -0.319998 +v 0.125483 0.258026 -0.319998 +v 0.125483 0.007059 -0.319998 +v 0.125483 0.258025 -0.152687 +v -0.125483 0.258025 -0.152687 +v -0.125483 0.007059 -0.152687 +v 0.125483 0.007059 -0.152687 +v 0.125612 0.249660 0.047957 +v 0.125784 0.249660 0.215268 +v 0.125784 0.007059 0.215268 +v 0.125612 0.007059 0.047957 +v -0.125354 0.007059 0.048215 +v -0.125354 0.249660 0.048215 +v -0.125182 0.249660 0.215526 +v -0.125182 0.007059 0.215526 +v 0.083972 0.166005 0.215268 +v 0.084230 0.166005 0.382578 +v 0.084230 0.023790 0.382578 +v 0.083972 0.023790 0.215268 +v -0.083339 0.023790 0.215526 +v -0.083339 0.166005 0.215526 +v -0.083081 0.166005 0.382836 +v -0.083081 0.023790 0.382836 +v 0.083726 0.191101 -0.487268 +v 0.083644 0.191101 -0.319957 +v 0.083644 0.023790 -0.319957 +v 0.083726 0.023790 -0.487268 +v -0.083585 0.023790 -0.487350 +v -0.083585 0.191101 -0.487350 +v -0.083667 0.191101 -0.320039 +v -0.083667 0.023790 -0.320039 +v 0.034047 0.124177 0.382638 +v 0.034305 0.124177 0.508121 +v 0.034305 0.057252 0.508121 +v 0.034047 0.057252 0.382638 +v -0.032877 0.057252 0.382776 +v -0.032877 0.124177 0.382776 +v -0.032619 0.124177 0.508259 +v -0.032619 0.057252 0.508259 +vt 0.213196 0.727179 +vt 0.149054 0.727179 +vt 0.149054 0.598895 +vt 0.213196 0.598895 +vt 0.341479 0.727179 +vt 0.341479 0.855462 +vt 0.213196 0.855462 +vt 0.149054 0.855462 +vt 0.213196 0.983746 +vt 0.149054 0.983746 +vt 0.020771 0.727179 +vt 0.020771 0.855462 +vt 0.352422 0.729185 +vt 0.352422 0.858337 +vt 0.223270 0.858337 +vt 0.223270 0.729185 +vt 0.137169 0.858337 +vt 0.223270 0.987489 +vt 0.137169 0.987489 +vt 0.008016 0.729185 +vt 0.137169 0.729185 +vt 0.008016 0.858337 +vt 0.438524 0.729185 +vt 0.438524 0.858337 +vt 0.224880 0.728005 +vt 0.138779 0.728005 +vt 0.138779 0.603158 +vt 0.224880 0.603158 +vt 0.349727 0.728005 +vt 0.349727 0.857157 +vt 0.224880 0.857157 +vt 0.138779 0.857157 +vt 0.224880 0.982004 +vt 0.138779 0.982004 +vt 0.013931 0.728005 +vt 0.013931 0.857157 +vt 0.226508 0.737576 +vt 0.113855 0.737576 +vt 0.113855 0.641822 +vt 0.226508 0.641822 +vt 0.322263 0.737576 +vt 0.322263 0.850229 +vt 0.226508 0.850229 +vt 0.113855 0.850229 +vt 0.226508 0.945984 +vt 0.113855 0.945984 +vt 0.018100 0.737576 +vt 0.018100 0.850229 +vt 0.712861 0.857181 +vt 0.843510 0.857181 +vt 0.843510 0.987830 +vt 0.712861 0.987830 +vt 0.582211 0.857181 +vt 0.582211 0.726531 +vt 0.712861 0.726531 +vt 0.843510 0.726531 +vt 0.712861 0.595882 +vt 0.843510 0.595882 +vt 0.974160 0.857181 +vt 0.974160 0.726531 +vt 0.347323 0.951293 +vt 0.411899 0.951293 +vt 0.411899 0.985734 +vt 0.347323 0.985734 +vt 0.312883 0.951293 +vt 0.312883 0.916852 +vt 0.347323 0.916852 +vt 0.411899 0.916852 +vt 0.347323 0.882412 +vt 0.411899 0.882412 +vt 0.446340 0.951293 +vt 0.446340 0.916852 +vt 0.248306 0.951293 +vt 0.248306 0.916852 +vn 1.0000 0.0000 -0.0005 +vn -0.0005 0.0000 -1.0000 +vn -1.0000 0.0000 0.0005 +vn 0.0005 -0.0000 1.0000 +vn 0.0000 1.0000 -0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 1.0000 0.0000 -0.0000 +vn 1.0000 0.0000 -0.0010 +vn -0.0010 0.0000 -1.0000 +vn -1.0000 0.0000 0.0010 +vn 0.0010 0.0000 1.0000 +vn 1.0000 0.0000 -0.0015 +vn -0.0015 0.0000 -1.0000 +vn -1.0000 0.0000 0.0015 +vn 0.0015 -0.0000 1.0000 +vn 1.0000 0.0000 0.0005 +vn 0.0005 0.0000 -1.0000 +vn -1.0000 0.0000 -0.0005 +vn -0.0005 -0.0000 1.0000 +vn 1.0000 0.0000 -0.0021 +vn -0.0021 0.0000 -1.0000 +vn -1.0000 0.0000 0.0021 +vn 0.0021 0.0000 1.0000 +vn 0.0000 -1.0000 -0.0000 +s 1 +f 9/23/7 10/24/7 11/25/7 12/26/7 +f 12/27/8 13/28/8 14/29/8 9/23/8 +f 15/30/9 14/29/9 13/31/9 16/32/9 +f 11/33/10 10/24/10 15/30/10 16/34/10 +f 14/29/11 15/30/11 10/24/11 9/23/11 +f 17/35/12 18/36/12 19/37/12 20/38/12 +f 21/39/11 19/37/11 18/40/11 22/41/11 +f 23/42/13 24/43/13 21/39/13 22/44/13 +f 17/35/14 23/45/14 22/46/14 18/36/14 +f 19/37/15 21/39/15 24/43/15 20/38/15 +f 25/47/16 26/48/16 27/49/16 28/50/16 +f 28/51/17 29/52/17 30/53/17 25/47/17 +f 31/54/18 30/53/18 29/55/18 32/56/18 +f 27/57/19 26/48/19 31/54/19 32/58/19 +f 30/53/11 31/54/11 26/48/11 25/47/11 +f 33/59/20 34/60/20 35/61/20 36/62/20 +f 36/63/21 37/64/21 38/65/21 33/59/21 +f 39/66/22 38/65/22 37/67/22 40/68/22 +f 35/69/23 34/60/23 39/66/23 40/70/23 +f 38/65/11 39/66/11 34/60/11 33/59/11 +f 41/71/24 42/72/24 43/73/24 44/74/24 +f 44/75/25 45/76/25 46/77/25 41/71/25 +f 47/78/26 46/77/26 45/79/26 48/80/26 +f 43/81/27 42/72/27 47/78/27 48/82/27 +f 46/77/11 47/78/11 42/72/11 41/71/11 +f 49/83/28 50/84/28 51/85/28 52/86/28 +f 52/87/29 53/88/29 54/89/29 49/83/29 +f 55/90/30 54/89/30 53/91/30 56/92/30 +f 51/93/31 50/84/31 55/90/31 56/94/31 +f 52/87/32 51/95/32 56/96/32 53/88/32 +f 54/89/11 55/90/11 50/84/11 49/83/11 diff --git a/mods/hall/models/hall_monster.obj b/mods/hall/models/hall_monster.obj new file mode 100644 index 0000000..105386b --- /dev/null +++ b/mods/hall/models/hall_monster.obj @@ -0,0 +1,614 @@ +# Blender v2.80 (sub 75) OBJ File: 'Anthropod-humanoid.blend' +# www.blender.org +o Scorpion_Mesh_Cube.001 +v 0.275000 -0.291880 -0.763117 +v 0.275000 0.008114 -0.761188 +v 0.400000 -0.399594 0.436215 +v 0.400000 0.000398 0.438787 +v -0.275000 -0.291880 -0.763117 +v -0.275000 0.008114 -0.761188 +v -0.400000 -0.399594 0.436215 +v -0.400000 0.000398 0.438787 +v -0.410246 -0.334203 -0.600564 +v -0.259011 -0.203330 -0.600113 +v -0.410115 -0.335043 -0.400566 +v -0.258881 -0.204170 -0.400115 +v -0.810436 0.112995 -0.608426 +v -0.644077 0.256955 -0.607929 +v -0.810293 0.112071 -0.388428 +v -0.643934 0.256031 -0.387931 +v -0.554352 0.067274 -0.588861 +v -0.730215 0.105638 -0.588431 +v -0.554018 0.066785 -0.408862 +v -0.729882 0.105149 -0.408432 +v -0.672483 -0.521042 -0.600238 +v -0.867887 -0.478415 -0.599761 +v -0.672113 -0.521585 -0.400240 +v -0.867517 -0.478958 -0.399762 +v -0.411443 -0.336684 -0.200571 +v -0.259102 -0.207100 -0.200125 +v -0.411314 -0.337523 -0.000572 +v -0.258973 -0.207939 -0.000127 +v -0.807820 0.113897 -0.208425 +v -0.640245 0.256439 -0.207935 +v -0.807678 0.112974 0.011573 +v -0.640103 0.255516 0.012063 +v -0.552046 0.066391 -0.188867 +v -0.727752 0.105470 -0.188434 +v -0.551711 0.065902 -0.008868 +v -0.727417 0.104981 -0.008435 +v -0.672571 -0.521439 -0.200240 +v -0.867800 -0.478018 -0.199759 +v -0.672200 -0.521983 -0.000241 +v -0.867429 -0.478561 0.000240 +v -0.412642 -0.339155 0.199423 +v -0.259203 -0.210873 0.199862 +v -0.412514 -0.339992 0.399421 +v -0.259075 -0.211710 0.399860 +v -0.805169 0.114785 0.191575 +v -0.636386 0.255895 0.192058 +v -0.805028 0.113864 0.411573 +v -0.636245 0.254974 0.412056 +v -0.549719 0.065489 0.211128 +v -0.725262 0.105291 0.211563 +v -0.549384 0.064999 0.391127 +v -0.724927 0.104801 0.391562 +v -0.672662 -0.521840 0.199759 +v -0.867711 -0.477616 0.200242 +v -0.672290 -0.522384 0.399758 +v -0.867338 -0.478160 0.400241 +v 0.410245 -0.334203 -0.600564 +v 0.259011 -0.203330 -0.600113 +v 0.410115 -0.335043 -0.400566 +v 0.258881 -0.204170 -0.400115 +v 0.810436 0.112995 -0.608426 +v 0.644077 0.256955 -0.607929 +v 0.810293 0.112071 -0.388428 +v 0.643934 0.256031 -0.387931 +v 0.554352 0.067274 -0.588861 +v 0.730215 0.105638 -0.588431 +v 0.554018 0.066785 -0.408862 +v 0.729882 0.105149 -0.408432 +v 0.672483 -0.521042 -0.600238 +v 0.867887 -0.478416 -0.599761 +v 0.672113 -0.521585 -0.400240 +v 0.867517 -0.478958 -0.399762 +v 0.411443 -0.336684 -0.200571 +v 0.259102 -0.207100 -0.200125 +v 0.411314 -0.337523 -0.000572 +v 0.258973 -0.207939 -0.000127 +v 0.807820 0.113897 -0.208425 +v 0.640245 0.256439 -0.207935 +v 0.807678 0.112974 0.011573 +v 0.640103 0.255516 0.012063 +v 0.552046 0.066391 -0.188867 +v 0.727752 0.105470 -0.188434 +v 0.551711 0.065902 -0.008868 +v 0.727417 0.104981 -0.008435 +v 0.672571 -0.521439 -0.200240 +v 0.867800 -0.478018 -0.199759 +v 0.672200 -0.521983 -0.000241 +v 0.867429 -0.478561 0.000240 +v 0.412642 -0.339155 0.199423 +v 0.259203 -0.210873 0.199862 +v 0.412514 -0.339992 0.399421 +v 0.259075 -0.211710 0.399860 +v 0.805169 0.114785 0.191575 +v 0.636386 0.255895 0.192058 +v 0.805028 0.113864 0.411573 +v 0.636245 0.254974 0.412056 +v 0.549719 0.065489 0.211128 +v 0.725262 0.105291 0.211563 +v 0.549384 0.064999 0.391127 +v 0.724927 0.104801 0.391562 +v 0.672662 -0.521840 0.199759 +v 0.867710 -0.477616 0.200242 +v 0.672289 -0.522384 0.399758 +v 0.867338 -0.478160 0.400241 +v 0.400000 -0.393421 -0.523765 +v 0.400000 0.006571 -0.521193 +v -0.400000 -0.393421 -0.523765 +v -0.400000 0.006571 -0.521193 +v 0.250000 -0.006114 -0.750462 +v 0.250000 0.493875 -0.753920 +v 0.250000 -0.004385 -0.500468 +v 0.250000 0.495604 -0.503926 +v -0.250000 -0.006114 -0.750462 +v -0.250000 0.493875 -0.753920 +v -0.250000 -0.004385 -0.500468 +v -0.250000 0.495604 -0.503926 +v -0.176653 0.494615 -0.627230 +v -0.002226 0.745962 -0.804431 +v -0.002251 0.495969 -0.806345 +v 0.004994 0.741820 -0.263442 +v 0.004970 0.491827 -0.265355 +v 0.176894 0.744609 -0.630035 +v 0.176869 0.494617 -0.631948 +v -0.000000 0.937500 -0.625000 +v -0.176628 0.744608 -0.625316 +v -0.107413 0.521426 -0.976083 +v -0.147340 0.596760 -0.884908 +v -0.518477 0.242138 -0.925329 +v -0.558403 0.317472 -0.834154 +v -0.167002 0.593558 -1.061777 +v -0.206929 0.668892 -0.970602 +v -0.578066 0.314269 -1.011023 +v -0.617992 0.389603 -0.919847 +v -0.257725 0.432202 -0.539474 +v -0.236611 0.309172 -0.539535 +v -0.621519 0.369937 -0.876116 +v -0.600406 0.246907 -0.876177 +v -0.173465 0.446708 -0.633214 +v -0.152351 0.323678 -0.633274 +v -0.537259 0.384443 -0.969855 +v -0.516146 0.261413 -0.969916 +v -0.125814 0.520384 -1.454432 +v -0.111393 0.638396 -1.416386 +v 0.211330 0.370598 -1.117610 +v 0.225751 0.488610 -1.079564 +v -0.218282 0.504169 -1.369086 +v -0.203861 0.622181 -1.331040 +v 0.118862 0.354384 -1.032264 +v 0.133283 0.472395 -0.994218 +v 0.198546 0.423710 -0.549014 +v 0.198439 0.299761 -0.563806 +v 0.110265 0.482049 -1.037229 +v 0.110158 0.358100 -1.052021 +v 0.323424 0.426260 -0.571290 +v 0.323317 0.302311 -0.586082 +v 0.235143 0.484600 -1.059505 +v 0.235036 0.360650 -1.074297 +vt 1.000000 0.446360 +vt 0.868718 0.446360 +vt 0.868718 0.131283 +vt 1.000000 0.131283 +vt 0.868718 0.000000 +vt 0.606153 0.131283 +vt 0.606153 0.000000 +vt 0.474870 0.446360 +vt 0.606153 0.446360 +vt 0.606153 0.535173 +vt 0.507691 0.535173 +vt 0.647178 0.623591 +vt 0.647179 0.525130 +vt 0.827692 0.525130 +vt 0.827692 0.623591 +vt 0.212306 0.446360 +vt 0.433845 0.531694 +vt 0.253331 0.531694 +vt 0.999660 0.750454 +vt 0.996793 0.809461 +vt 0.799915 0.803181 +vt 0.803100 0.737618 +vt 0.271842 0.917355 +vt 0.276473 0.982832 +vt 0.080244 1.000000 +vt 0.075151 0.927975 +vt 0.002120 0.709320 +vt 0.074295 0.711440 +vt 0.072174 0.783615 +vt 0.000000 0.781494 +vt 0.072460 0.855819 +vt 0.269137 0.786118 +vt 0.269396 0.851759 +vt 0.271064 0.720505 +vt 0.734351 0.799996 +vt 0.737537 0.734432 +vt 0.800104 0.934445 +vt 0.798916 0.868815 +vt 0.995894 0.868531 +vt 0.996963 0.927599 +vt 1.000000 0.986598 +vt 0.803478 1.000000 +vt 0.999660 0.750454 +vt 0.996793 0.809461 +vt 0.799915 0.803182 +vt 0.803100 0.737617 +vt 0.271843 0.917354 +vt 0.276473 0.982832 +vt 0.080245 1.000000 +vt 0.075151 0.927975 +vt 0.002121 0.709320 +vt 0.074295 0.711441 +vt 0.072174 0.783615 +vt 0.000000 0.781494 +vt 0.072460 0.855819 +vt 0.269137 0.786118 +vt 0.269396 0.851759 +vt 0.271064 0.720505 +vt 0.734351 0.799996 +vt 0.737537 0.734432 +vt 0.800104 0.934445 +vt 0.798916 0.868815 +vt 0.995894 0.868531 +vt 0.996963 0.927599 +vt 1.000000 0.986598 +vt 0.803478 1.000000 +vt 0.999660 0.750454 +vt 0.996793 0.809461 +vt 0.799915 0.803181 +vt 0.803100 0.737617 +vt 0.271842 0.917354 +vt 0.276473 0.982832 +vt 0.080245 1.000000 +vt 0.075151 0.927975 +vt 0.002120 0.709320 +vt 0.074295 0.711441 +vt 0.072174 0.783615 +vt 0.000000 0.781494 +vt 0.072460 0.855819 +vt 0.269137 0.786118 +vt 0.269396 0.851759 +vt 0.271064 0.720505 +vt 0.734351 0.799996 +vt 0.737537 0.734432 +vt 0.800104 0.934445 +vt 0.798916 0.868815 +vt 0.995894 0.868531 +vt 0.996963 0.927599 +vt 1.000000 0.986598 +vt 0.803478 1.000000 +vt 1.000000 0.750736 +vt 0.803459 0.737617 +vt 0.800179 0.803176 +vt 0.997048 0.809740 +vt 0.272356 0.916628 +vt 0.075706 0.927994 +vt 0.081073 1.000000 +vt 0.277236 0.982087 +vt 0.001847 0.709619 +vt 0.000000 0.781800 +vt 0.072182 0.783647 +vt 0.074028 0.711465 +vt 0.072741 0.855850 +vt 0.269661 0.851042 +vt 0.269152 0.785402 +vt 0.270831 0.719783 +vt 0.737900 0.734337 +vt 0.734620 0.799897 +vt 0.800179 0.934441 +vt 0.997048 0.927877 +vt 0.996064 0.868808 +vt 0.799086 0.868808 +vt 1.000000 0.986881 +vt 0.803459 1.000000 +vt 1.000000 0.750737 +vt 0.803459 0.737617 +vt 0.800179 0.803176 +vt 0.997048 0.809740 +vt 0.272356 0.916628 +vt 0.075706 0.927994 +vt 0.081073 1.000000 +vt 0.277236 0.982087 +vt 0.001847 0.709619 +vt 0.000000 0.781800 +vt 0.072182 0.783647 +vt 0.074028 0.711465 +vt 0.072741 0.855850 +vt 0.269661 0.851042 +vt 0.269152 0.785402 +vt 0.270831 0.719783 +vt 0.737900 0.734337 +vt 0.734620 0.799897 +vt 0.800179 0.934441 +vt 0.997048 0.927877 +vt 0.996064 0.868809 +vt 0.799086 0.868809 +vt 1.000000 0.986881 +vt 0.803459 1.000000 +vt 1.000000 0.750737 +vt 0.803459 0.737617 +vt 0.800179 0.803177 +vt 0.997048 0.809740 +vt 0.272356 0.916628 +vt 0.075706 0.927994 +vt 0.081073 1.000000 +vt 0.277236 0.982087 +vt 0.001847 0.709619 +vt 0.000000 0.781800 +vt 0.072182 0.783647 +vt 0.074028 0.711465 +vt 0.072741 0.855850 +vt 0.269661 0.851042 +vt 0.269152 0.785403 +vt 0.270831 0.719783 +vt 0.737900 0.734337 +vt 0.734620 0.799897 +vt 0.800179 0.934441 +vt 0.997048 0.927878 +vt 0.996064 0.868809 +vt 0.799086 0.868809 +vt 1.000000 0.986881 +vt 0.803459 1.000000 +vt 0.212306 0.131283 +vt 0.474870 0.131282 +vt 0.967179 0.535173 +vt 0.868717 0.535173 +vt 0.082052 0.536703 +vt 0.082052 0.700806 +vt 0.000000 0.700806 +vt 0.000000 0.536703 +vt 0.492309 0.536703 +vt 0.492309 0.700806 +vt 0.328206 0.700806 +vt 0.328206 0.536703 +vt 0.246154 0.700806 +vt 0.246154 0.536703 +vt 0.492309 0.782857 +vt 0.328206 0.782857 +vt 0.697549 0.785065 +vt 0.741050 0.910636 +vt 0.615489 0.867108 +vt 0.615498 0.785056 +vt 0.407867 0.910600 +vt 0.451395 0.785039 +vt 0.533446 0.785048 +vt 0.533438 0.867099 +vt 0.533455 0.702996 +vt 0.615507 0.703005 +vt 0.533469 0.570104 +vt 0.615521 0.570113 +vt 0.615475 1.000000 +vt 0.533423 0.999991 +vt 0.000000 0.040970 +vt 0.000000 0.000000 +vt 0.041641 0.000000 +vt 0.041641 0.040970 +vt 0.165221 0.298302 +vt 0.165221 0.257333 +vt 0.123580 0.257333 +vt 0.123580 0.298302 +vt 0.082611 0.040970 +vt 0.124252 0.040970 +vt 0.124252 0.204925 +vt 0.082611 0.204925 +vt 0.000000 0.462258 +vt 0.040970 0.462258 +vt 0.040970 0.298302 +vt 0.000000 0.298302 +vt 0.123580 0.462258 +vt 0.123580 0.503227 +vt 0.165221 0.503227 +vt 0.165221 0.462258 +vt 0.082611 0.298302 +vt 0.082611 0.462258 +vt 0.165221 0.204925 +vt 0.165221 0.040970 +vt 0.041641 0.204925 +vt 0.041641 0.245895 +vt 0.000000 0.245895 +vt 0.000000 0.204925 +vt 0.041641 0.040970 +vt 0.041641 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.040970 +vt 0.123580 0.298302 +vt 0.123580 0.257333 +vt 0.165221 0.257333 +vt 0.165221 0.298302 +vt 0.124252 0.040970 +vt 0.082611 0.040970 +vt 0.082611 0.204925 +vt 0.124252 0.204925 +vt 0.123580 0.462258 +vt 0.082611 0.462258 +vt 0.082611 0.298302 +vt 0.165221 0.462258 +vt 0.165221 0.503227 +vt 0.123580 0.503227 +vt 0.040970 0.298302 +vt 0.040970 0.462258 +vt 0.041641 0.204925 +vt 0.000000 0.204925 +vt 0.000000 0.245895 +vt 0.041641 0.245895 +vt 0.165221 0.040970 +vt 0.165221 0.204925 +vt 0.000000 0.298302 +vt 0.000000 0.462258 +vn 1.0000 0.0000 -0.0000 +vn 0.0000 -0.0064 1.0000 +vn -0.8869 0.0030 -0.4619 +vn 0.0000 0.0064 -1.0000 +vn -0.0000 -0.9206 -0.3905 +vn 0.0000 1.0000 0.0064 +vn 0.0054 0.0136 0.9999 +vn 0.0116 -0.0168 0.9998 +vn -0.6544 0.7562 0.0036 +vn 0.0103 -0.0084 -0.9999 +vn -0.7452 -0.6669 -0.0023 +vn 0.7670 0.6417 0.0022 +vn -0.2131 -0.9770 -0.0023 +vn 0.0017 0.0190 -0.9998 +vn 0.9804 -0.1968 -0.0024 +vn -0.9733 0.2294 0.0024 +vn 0.0055 0.0136 0.9999 +vn 0.0114 -0.0169 0.9998 +vn -0.6479 0.7617 0.0036 +vn 0.0102 -0.0085 -0.9999 +vn -0.7508 -0.6605 -0.0023 +vn 0.7724 0.6351 0.0022 +vn -0.2171 -0.9761 -0.0022 +vn 0.0018 0.0190 -0.9998 +vn 0.9796 -0.2008 -0.0024 +vn -0.9724 0.2333 0.0024 +vn 0.0055 0.0135 0.9999 +vn 0.0113 -0.0170 0.9998 +vn -0.6414 0.7672 0.0036 +vn 0.0100 -0.0086 -0.9999 +vn -0.7564 -0.6541 -0.0023 +vn 0.7778 0.6285 0.0021 +vn -0.2211 -0.9752 -0.0022 +vn 0.9788 -0.2048 -0.0024 +vn -0.9714 0.2373 0.0025 +vn -0.0054 0.0136 0.9999 +vn -0.0116 -0.0168 0.9998 +vn 0.6544 0.7562 0.0036 +vn -0.0103 -0.0084 -0.9999 +vn 0.7452 -0.6669 -0.0023 +vn -0.7670 0.6417 0.0022 +vn 0.2131 -0.9770 -0.0023 +vn -0.0017 0.0190 -0.9998 +vn -0.9804 -0.1968 -0.0024 +vn 0.9733 0.2294 0.0024 +vn -0.0055 0.0136 0.9999 +vn -0.0114 -0.0169 0.9998 +vn 0.6479 0.7617 0.0036 +vn -0.0102 -0.0085 -0.9999 +vn 0.7508 -0.6605 -0.0023 +vn -0.7724 0.6351 0.0022 +vn 0.2171 -0.9761 -0.0022 +vn -0.0018 0.0190 -0.9998 +vn -0.9796 -0.2008 -0.0024 +vn 0.9724 0.2333 0.0024 +vn -0.0055 0.0135 0.9999 +vn -0.0113 -0.0170 0.9998 +vn 0.6414 0.7672 0.0036 +vn -0.0100 -0.0086 -0.9999 +vn 0.7564 -0.6541 -0.0023 +vn -0.7778 0.6285 0.0021 +vn 0.2211 -0.9752 -0.0022 +vn -0.9788 -0.2048 -0.0024 +vn 0.9714 0.2373 0.0025 +vn -0.0000 -1.0000 -0.0064 +vn -1.0000 -0.0000 0.0000 +vn 0.8869 0.0030 -0.4619 +vn -0.0000 0.0069 1.0000 +vn -0.0000 -0.0069 -1.0000 +vn 0.0000 1.0000 -0.0069 +vn 0.0001 1.0000 0.0077 +vn -0.0001 -1.0000 -0.0077 +vn 0.6976 0.0054 -0.7165 +vn -0.7165 0.0054 -0.6976 +vn -0.8938 -0.0033 0.4485 +vn 0.9054 -0.0033 0.4245 +vn 0.7282 0.1246 0.6739 +vn -0.8229 -0.5591 0.1016 +vn -0.1691 0.9856 0.0005 +vn 0.4697 -0.5685 0.6754 +vn 0.8229 0.5591 -0.1016 +vn -0.3198 0.6035 0.7304 +vn 0.6641 0.1143 -0.7388 +vn -0.7282 -0.1246 -0.6739 +vn 0.1691 -0.9856 -0.0005 +vn -0.6641 -0.1143 0.7388 +vn 0.3198 -0.6035 -0.7304 +vn -0.4697 0.5685 -0.6754 +vn 0.1767 -0.1168 0.9773 +vn 0.6749 -0.2998 0.6743 +vn 0.0009 0.9930 0.1185 +vn 0.7288 0.1278 -0.6727 +vn -0.6749 0.2998 -0.6743 +vn 0.1155 0.9454 0.3048 +vn 0.9843 0.0201 -0.1756 +vn -0.1767 0.1168 -0.9773 +vn -0.0009 -0.9930 -0.1185 +vn -0.9843 -0.0201 0.1756 +vn -0.1155 -0.9454 -0.3048 +vn -0.7288 -0.1278 0.6727 +s off +f 105/1/1 106/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 107/8/3 108/9/3 6/10/3 5/11/3 +f 5/12/4 6/13/4 2/14/4 1/15/4 +f 105/16/5 107/8/5 5/17/5 1/18/5 +f 108/9/6 106/2/6 2/14/6 6/13/6 +f 19/19/7 20/20/7 24/21/7 23/22/7 +f 11/23/8 12/24/8 16/25/8 15/26/8 +f 15/27/9 16/28/9 14/29/9 13/30/9 +f 13/31/10 14/29/10 10/32/10 9/33/10 +f 11/23/11 15/26/11 13/31/11 9/33/11 +f 16/28/12 12/34/12 10/32/12 14/29/12 +f 23/22/13 24/21/13 22/35/13 21/36/13 +f 21/37/14 22/38/14 18/39/14 17/40/14 +f 19/41/15 23/42/15 21/37/15 17/40/15 +f 24/21/16 20/20/16 18/39/16 22/38/16 +f 35/43/17 36/44/17 40/45/17 39/46/17 +f 27/47/18 28/48/18 32/49/18 31/50/18 +f 31/51/19 32/52/19 30/53/19 29/54/19 +f 29/55/20 30/53/20 26/56/20 25/57/20 +f 27/47/21 31/50/21 29/55/21 25/57/21 +f 32/52/22 28/58/22 26/56/22 30/53/22 +f 39/46/23 40/45/23 38/59/23 37/60/23 +f 37/61/24 38/62/24 34/63/24 33/64/24 +f 35/65/25 39/66/25 37/61/25 33/64/25 +f 40/45/26 36/44/26 34/63/26 38/62/26 +f 51/67/27 52/68/27 56/69/27 55/70/27 +f 43/71/28 44/72/28 48/73/28 47/74/28 +f 47/75/29 48/76/29 46/77/29 45/78/29 +f 45/79/30 46/77/30 42/80/30 41/81/30 +f 43/71/31 47/74/31 45/79/31 41/81/31 +f 48/76/32 44/82/32 42/80/32 46/77/32 +f 55/70/33 56/69/33 54/83/33 53/84/33 +f 53/85/24 54/86/24 50/87/24 49/88/24 +f 51/89/34 55/90/34 53/85/34 49/88/34 +f 56/69/35 52/68/35 50/87/35 54/86/35 +f 67/91/36 71/92/36 72/93/36 68/94/36 +f 59/95/37 63/96/37 64/97/37 60/98/37 +f 63/99/38 61/100/38 62/101/38 64/102/38 +f 61/103/39 57/104/39 58/105/39 62/101/39 +f 59/95/40 57/104/40 61/103/40 63/96/40 +f 64/102/41 62/101/41 58/105/41 60/106/41 +f 71/92/42 69/107/42 70/108/42 72/93/42 +f 69/109/43 65/110/43 66/111/43 70/112/43 +f 67/113/44 65/110/44 69/109/44 71/114/44 +f 72/93/45 70/112/45 66/111/45 68/94/45 +f 83/115/46 87/116/46 88/117/46 84/118/46 +f 75/119/47 79/120/47 80/121/47 76/122/47 +f 79/123/48 77/124/48 78/125/48 80/126/48 +f 77/127/49 73/128/49 74/129/49 78/125/49 +f 75/119/50 73/128/50 77/127/50 79/120/50 +f 80/126/51 78/125/51 74/129/51 76/130/51 +f 87/116/52 85/131/52 86/132/52 88/117/52 +f 85/133/53 81/134/53 82/135/53 86/136/53 +f 83/137/54 81/134/54 85/133/54 87/138/54 +f 88/117/55 86/136/55 82/135/55 84/118/55 +f 99/139/56 103/140/56 104/141/56 100/142/56 +f 91/143/57 95/144/57 96/145/57 92/146/57 +f 95/147/58 93/148/58 94/149/58 96/150/58 +f 93/151/59 89/152/59 90/153/59 94/149/59 +f 91/143/60 89/152/60 93/151/60 95/144/60 +f 96/150/61 94/149/61 90/153/61 92/154/61 +f 103/140/62 101/155/62 102/156/62 104/141/62 +f 101/157/53 97/158/53 98/159/53 102/160/53 +f 99/161/63 97/158/63 101/157/63 103/162/63 +f 104/141/64 102/160/64 98/159/64 100/142/64 +f 8/6/6 4/3/6 106/2/6 108/9/6 +f 3/163/65 7/164/65 107/8/65 105/16/65 +f 7/164/66 8/6/66 108/9/66 107/8/66 +f 1/165/67 2/166/67 106/2/67 105/1/67 +f 109/167/1 110/168/1 112/169/1 111/170/1 +f 111/171/68 112/172/68 116/173/68 115/174/68 +f 115/174/66 116/173/66 114/175/66 113/176/66 +f 113/176/69 114/175/69 110/168/69 109/167/69 +f 116/173/70 112/172/70 110/177/70 114/178/70 +f 125/179/71 120/180/71 122/181/71 118/182/71 +f 121/183/72 117/184/72 119/185/72 123/186/72 +f 119/185/73 118/182/73 122/181/73 123/186/73 +f 117/187/74 125/188/74 118/182/74 119/185/74 +f 121/189/75 120/190/75 125/188/75 117/187/75 +f 123/186/76 122/181/76 120/191/76 121/192/76 +f 139/193/77 138/194/77 134/195/77 135/196/77 +f 128/197/78 129/198/78 133/199/78 132/200/78 +f 134/201/79 138/202/79 140/203/79 136/204/79 +f 126/205/80 127/206/80 129/207/80 128/208/80 +f 130/209/81 131/210/81 127/211/81 126/212/81 +f 133/213/82 129/207/82 127/206/82 131/214/82 +f 141/215/83 140/203/83 138/202/83 139/216/83 +f 137/217/84 136/218/84 140/219/84 141/220/84 +f 139/193/85 135/196/85 137/217/85 141/220/85 +f 135/196/86 134/201/86 136/204/86 137/217/86 +f 128/197/87 132/200/87 130/209/87 126/212/87 +f 132/200/88 133/213/88 131/214/88 130/209/88 +f 155/221/89 154/222/89 150/223/89 151/224/89 +f 144/225/90 145/226/90 149/227/90 148/228/90 +f 150/229/91 154/230/91 156/231/91 152/232/91 +f 142/233/92 143/234/92 145/235/92 144/225/92 +f 146/236/93 147/237/93 143/238/93 142/233/93 +f 149/239/94 145/235/94 143/234/94 147/240/94 +f 157/241/95 156/231/95 154/230/95 155/221/95 +f 153/242/96 152/243/96 156/244/96 157/241/96 +f 155/221/97 151/224/97 153/242/97 157/241/97 +f 151/245/98 150/229/98 152/232/98 153/246/98 +f 144/225/99 148/228/99 146/236/99 142/233/99 +f 148/247/100 149/239/100 147/240/100 146/248/100 diff --git a/mods/hall/models/hall_scorpion.obj b/mods/hall/models/hall_scorpion.obj new file mode 100644 index 0000000..994c840 --- /dev/null +++ b/mods/hall/models/hall_scorpion.obj @@ -0,0 +1,596 @@ +# Blender v2.80 (sub 75) OBJ File: 'Scorpion2.8.blend' +# www.blender.org +o Scorpion_Mesh_Cube.001 +v 0.400000 0.252853 -0.916863 +v 0.400000 0.605969 -0.728956 +v 0.400000 -0.404823 0.319043 +v 0.400000 -0.051707 0.506950 +v -0.400000 0.252853 -0.916863 +v -0.400000 0.605969 -0.728956 +v -0.400000 -0.404823 0.319043 +v -0.400000 -0.051707 0.506950 +v -0.245433 0.282334 -0.635990 +v -0.300465 0.417395 -0.499132 +v -0.324072 0.136622 -0.523813 +v -0.379104 0.271682 -0.386955 +v -0.765138 0.351702 -0.928041 +v -0.825674 0.500269 -0.777498 +v -0.851641 0.191419 -0.804647 +v -0.912177 0.339985 -0.654103 +v -0.616457 0.394056 -0.753269 +v -0.791022 0.437805 -0.749640 +v -0.658191 0.224054 -0.711344 +v -0.832756 0.267803 -0.707715 +v -0.649834 0.268344 -1.339173 +v -0.843795 0.316954 -1.335140 +v -0.696205 0.079454 -1.292589 +v -0.890166 0.128064 -1.288556 +v -0.326082 0.026263 -0.342848 +v -0.317609 0.221038 -0.298230 +v -0.286525 -0.019146 -0.152131 +v -0.278052 0.175629 -0.107512 +v -0.916081 0.016559 -0.233271 +v -0.906761 0.230812 -0.184191 +v -0.872568 -0.033392 -0.023482 +v -0.863248 0.180861 0.025598 +v -0.689642 0.093023 -0.234412 +v -0.866806 0.096873 -0.202818 +v -0.657897 0.101516 -0.057437 +v -0.835061 0.105366 -0.025843 +v -0.689212 -0.506857 -0.215872 +v -0.886060 -0.502579 -0.180767 +v -0.653940 -0.497420 -0.019233 +v -0.850788 -0.493142 0.015872 +v -0.384224 -0.200353 0.017861 +v -0.279744 -0.030892 0.037016 +v -0.352662 -0.241643 0.210990 +v -0.248182 -0.072182 0.230146 +v -0.893809 0.086841 0.152184 +v -0.778881 0.273248 0.173255 +v -0.859091 0.041422 0.364626 +v -0.744163 0.227829 0.385697 +v -0.645862 0.075831 0.129094 +v -0.819220 0.097874 0.172234 +v -0.600879 0.089568 0.302841 +v -0.774237 0.111611 0.345980 +v -0.698681 -0.519878 0.179507 +v -0.891301 -0.495385 0.227441 +v -0.648699 -0.504615 0.372559 +v -0.841320 -0.480122 0.420492 +v 0.354572 0.258747 -0.722548 +v 0.245029 0.359432 -0.588895 +v 0.391840 0.117695 -0.585743 +v 0.282298 0.218380 -0.452091 +v 0.847577 0.560269 -0.560589 +v 0.727080 0.671022 -0.413572 +v 0.888572 0.405112 -0.410104 +v 0.768075 0.515865 -0.263086 +v 0.590101 0.523249 -0.484756 +v 0.761086 0.579448 -0.487143 +v 0.642496 0.366902 -0.412574 +v 0.813482 0.423100 -0.414961 +v 0.645900 0.297939 -1.038220 +v 0.835883 0.360382 -1.040872 +v 0.704117 0.124220 -0.958017 +v 0.894100 0.186663 -0.960670 +v 0.326082 0.026263 -0.342848 +v 0.317610 0.221038 -0.298230 +v 0.286525 -0.019147 -0.152131 +v 0.278052 0.175629 -0.107513 +v 0.916081 0.016559 -0.233271 +v 0.906761 0.230812 -0.184191 +v 0.872568 -0.033392 -0.023482 +v 0.863248 0.180861 0.025598 +v 0.689642 0.093023 -0.234412 +v 0.866806 0.096873 -0.202818 +v 0.657897 0.101516 -0.057437 +v 0.835061 0.105366 -0.025843 +v 0.689212 -0.506857 -0.215872 +v 0.886060 -0.502579 -0.180767 +v 0.653940 -0.497420 -0.019233 +v 0.850788 -0.493143 0.015871 +v 0.384224 -0.200353 0.017861 +v 0.279744 -0.030892 0.037016 +v 0.352662 -0.241643 0.210990 +v 0.248182 -0.072182 0.230146 +v 0.893809 0.086841 0.152184 +v 0.778881 0.273248 0.173255 +v 0.859091 0.041421 0.364626 +v 0.744163 0.227829 0.385697 +v 0.645862 0.075831 0.129094 +v 0.819220 0.097874 0.172234 +v 0.600879 0.089568 0.302841 +v 0.774237 0.111611 0.345980 +v 0.698681 -0.519878 0.179507 +v 0.891301 -0.495385 0.227441 +v 0.648699 -0.504615 0.372559 +v 0.841320 -0.480122 0.420492 +v 0.300000 0.531108 -0.785309 +v 0.300000 0.231949 -0.807768 +v 0.300000 0.549823 -1.034607 +v 0.300000 0.250665 -1.057066 +v -0.300000 0.250665 -1.057066 +v -0.300000 0.549823 -1.034607 +v -0.300000 0.231949 -0.807768 +v -0.300000 0.531108 -0.785309 +v -0.150000 -0.347078 0.714552 +v -0.150000 -0.047377 0.727936 +v -0.150000 -0.364924 1.114153 +v -0.150000 -0.065223 1.127538 +v -0.200000 0.000288 0.780300 +v -0.200000 -0.399297 0.762084 +v -0.200000 0.018505 0.380715 +v -0.200000 -0.381080 0.362499 +v 0.200000 0.000288 0.780300 +v 0.200000 -0.399297 0.762084 +v 0.200000 0.018505 0.380715 +v 0.200000 -0.381080 0.362499 +v 0.150000 -0.047377 0.727936 +v -0.084375 -0.311257 1.416277 +v -0.084375 -0.142729 1.424941 +v 0.150000 -0.364924 1.114153 +v -0.084375 -0.331794 1.815750 +v -0.084375 -0.163266 1.824414 +v 0.084375 -0.142729 1.424941 +v 0.084375 -0.331794 1.815750 +v 0.084375 -0.163266 1.824414 +v 0.084375 -0.311257 1.416277 +v 0.112500 -0.325251 1.066347 +v 0.112500 -0.116606 1.475117 +v 0.112500 -0.341422 1.466020 +v 0.112500 -0.100435 1.075444 +v -0.112500 -0.116606 1.475117 +v 0.150000 -0.065223 1.127538 +v -0.112500 -0.341422 1.466020 +v -0.112500 -0.100435 1.075444 +v -0.112500 -0.325251 1.066347 +v 0.150000 -0.347078 0.714552 +v -0.063281 -0.308189 1.767521 +v -0.063281 -0.181736 1.772774 +v -0.063281 -0.324792 2.167177 +v -0.063281 -0.198338 2.172430 +v 0.063281 -0.181736 1.772774 +v 0.063281 -0.324792 2.167177 +v 0.063281 -0.198338 2.172430 +v 0.063281 -0.308189 1.767521 +v -0.017739 -0.292709 2.143991 +v -0.017739 -0.266496 2.167898 +v -0.017739 -0.368267 2.226835 +v -0.017739 -0.342055 2.250743 +v 0.017739 -0.266496 2.167898 +v 0.017739 -0.368267 2.226835 +v 0.017739 -0.342055 2.250743 +v 0.017739 -0.292709 2.143991 +vt 0.426335 0.546089 +vt 0.426335 0.420075 +vt 0.867383 0.420075 +vt 0.867383 0.546089 +vt 0.993397 0.420075 +vt 0.867383 0.168047 +vt 0.993397 0.168047 +vt 0.867383 0.042033 +vt 0.426335 0.168047 +vt 0.426335 0.042033 +vt 0.300321 0.168047 +vt 0.300321 0.420075 +vt 0.867539 0.546163 +vt 0.867539 0.798191 +vt 0.426491 0.798191 +vt 0.426491 0.546163 +vt 0.123480 0.077218 +vt 0.125760 0.124145 +vt 0.282333 0.119151 +vt 0.279799 0.067010 +vt 0.238643 0.826643 +vt 0.242326 0.878716 +vt 0.086270 0.892369 +vt 0.082219 0.835089 +vt 0.024140 0.661198 +vt 0.081538 0.662884 +vt 0.079852 0.720283 +vt 0.022454 0.718597 +vt 0.080079 0.777706 +vt 0.236491 0.722274 +vt 0.236698 0.774476 +vt 0.238024 0.670094 +vt 0.334474 0.116618 +vt 0.331940 0.064477 +vt 0.282182 0.223542 +vt 0.283127 0.171348 +vt 0.126475 0.171123 +vt 0.125625 0.218097 +vt 0.123210 0.265018 +vt 0.279499 0.275676 +vt 0.123480 0.077218 +vt 0.125760 0.124145 +vt 0.282333 0.119151 +vt 0.279799 0.067010 +vt 0.238643 0.826643 +vt 0.242326 0.878716 +vt 0.086270 0.892369 +vt 0.082219 0.835089 +vt 0.024140 0.661198 +vt 0.081538 0.662885 +vt 0.079852 0.720283 +vt 0.022454 0.718596 +vt 0.080079 0.777706 +vt 0.236491 0.722274 +vt 0.236698 0.774476 +vt 0.238024 0.670094 +vt 0.334474 0.116618 +vt 0.331941 0.064477 +vt 0.282182 0.223542 +vt 0.283127 0.171348 +vt 0.126475 0.171122 +vt 0.125625 0.218097 +vt 0.123210 0.265018 +vt 0.279499 0.275676 +vt 0.123480 0.077218 +vt 0.125760 0.124145 +vt 0.282333 0.119151 +vt 0.279799 0.067010 +vt 0.238643 0.826643 +vt 0.242326 0.878716 +vt 0.086270 0.892369 +vt 0.082219 0.835089 +vt 0.024140 0.661198 +vt 0.081538 0.662885 +vt 0.079852 0.720283 +vt 0.022454 0.718596 +vt 0.080079 0.777706 +vt 0.236491 0.722274 +vt 0.236698 0.774476 +vt 0.238024 0.670094 +vt 0.334474 0.116618 +vt 0.331941 0.064477 +vt 0.282182 0.223542 +vt 0.283127 0.171348 +vt 0.126475 0.171122 +vt 0.125625 0.218097 +vt 0.123210 0.265018 +vt 0.279499 0.275676 +vt 0.123210 0.077518 +vt 0.279514 0.067085 +vt 0.282122 0.119223 +vt 0.125557 0.124442 +vt 0.239181 0.825996 +vt 0.082790 0.835035 +vt 0.087059 0.892300 +vt 0.243062 0.878054 +vt 0.024052 0.661367 +vt 0.022583 0.718771 +vt 0.079987 0.720240 +vt 0.081456 0.662835 +vt 0.080432 0.777661 +vt 0.237038 0.773837 +vt 0.236633 0.721636 +vt 0.237968 0.669450 +vt 0.331651 0.064477 +vt 0.334260 0.116614 +vt 0.282122 0.223614 +vt 0.125557 0.218394 +vt 0.126340 0.171418 +vt 0.282992 0.171418 +vt 0.123210 0.265318 +vt 0.279514 0.275752 +vt 0.123210 0.077518 +vt 0.279514 0.067085 +vt 0.282122 0.119223 +vt 0.125557 0.124442 +vt 0.239181 0.825996 +vt 0.082790 0.835035 +vt 0.087059 0.892300 +vt 0.243062 0.878054 +vt 0.024052 0.661367 +vt 0.022583 0.718771 +vt 0.079987 0.720240 +vt 0.081456 0.662835 +vt 0.080432 0.777661 +vt 0.237038 0.773837 +vt 0.236633 0.721636 +vt 0.237968 0.669450 +vt 0.331651 0.064477 +vt 0.334260 0.116614 +vt 0.282122 0.223614 +vt 0.125557 0.218394 +vt 0.126340 0.171418 +vt 0.282992 0.171418 +vt 0.123210 0.265318 +vt 0.279514 0.275752 +vt 0.123210 0.077518 +vt 0.279514 0.067085 +vt 0.282122 0.119223 +vt 0.125557 0.124442 +vt 0.239181 0.825996 +vt 0.082790 0.835036 +vt 0.087059 0.892300 +vt 0.243062 0.878054 +vt 0.024052 0.661367 +vt 0.022583 0.718771 +vt 0.079987 0.720240 +vt 0.081456 0.662835 +vt 0.080432 0.777661 +vt 0.237038 0.773837 +vt 0.236633 0.721636 +vt 0.237968 0.669450 +vt 0.331651 0.064477 +vt 0.334260 0.116614 +vt 0.282122 0.223614 +vt 0.125557 0.218394 +vt 0.126340 0.171418 +vt 0.282992 0.171418 +vt 0.123210 0.265318 +vt 0.279514 0.275751 +vt 0.081630 0.547572 +vt 0.173137 0.547572 +vt 0.173137 0.623828 +vt 0.081630 0.623828 +vt 0.081630 0.288301 +vt 0.173137 0.288301 +vt 0.173137 0.364558 +vt 0.081630 0.364558 +vt 0.005374 0.547572 +vt 0.005374 0.364558 +vt 0.249393 0.364558 +vt 0.249393 0.547572 +vt 0.395791 0.831804 +vt 0.395791 0.962311 +vt 0.265284 0.962311 +vt 0.265284 0.831804 +vt 0.395791 0.570790 +vt 0.395791 0.701297 +vt 0.265284 0.701297 +vt 0.265284 0.570790 +vt 0.526298 0.831804 +vt 0.526298 0.962311 +vt 0.395791 0.831343 +vt 0.526298 0.831343 +vt 0.526298 0.961850 +vt 0.395791 0.961850 +vt 0.395791 0.439822 +vt 0.395791 0.570329 +vt 0.265284 0.570329 +vt 0.265284 0.439822 +vt 0.395791 0.700836 +vt 0.265284 0.700836 +vt 0.395791 0.440283 +vt 0.265284 0.440283 +vt 0.265284 0.961850 +vt 0.265284 0.831343 +vt 0.395791 0.831343 +vt 0.526298 0.831343 +vt 0.526298 0.961850 +vt 0.395791 0.961850 +vt 0.395791 0.439822 +vt 0.395791 0.570329 +vt 0.265284 0.570329 +vt 0.265284 0.439822 +vt 0.395791 0.700836 +vt 0.265284 0.700836 +vt 0.265284 0.961850 +vt 0.265284 0.831343 +vt 0.265284 0.831343 +vt 0.265284 0.700836 +vt 0.395791 0.700836 +vt 0.395791 0.831343 +vt 0.395791 0.961850 +vt 0.265284 0.961850 +vt 0.395791 0.570329 +vt 0.265284 0.570329 +vt 0.395791 0.439822 +vt 0.265284 0.439822 +vt 0.526298 0.831343 +vt 0.526298 0.961850 +vt 0.395791 0.831343 +vt 0.526298 0.831343 +vt 0.526298 0.961850 +vt 0.395791 0.961850 +vt 0.395791 0.439822 +vt 0.395791 0.570329 +vt 0.265284 0.570329 +vt 0.265284 0.439822 +vt 0.395791 0.700836 +vt 0.265284 0.700836 +vt 0.265284 0.961850 +vt 0.265284 0.831343 +vt 0.899273 0.898809 +vt 0.899273 0.807697 +vt 0.990384 0.807697 +vt 0.990384 0.898809 +vt 0.625939 0.898809 +vt 0.717050 0.898809 +vt 0.717050 0.989920 +vt 0.625939 0.989920 +vt 0.808161 0.898809 +vt 0.808161 0.989920 +vt 0.990384 0.989920 +vt 0.899273 0.989920 +vn 1.0000 0.0000 0.0000 +vn 0.0000 -0.4698 0.8828 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.4698 -0.8828 +vn 0.0000 -0.8828 -0.4698 +vn 0.0000 0.8828 0.4698 +vn -0.2306 -0.9406 0.2491 +vn -0.3785 -0.7304 0.5686 +vn -0.8773 0.1147 -0.4660 +vn 0.4078 0.7266 -0.5530 +vn 0.2897 -0.6771 -0.6764 +vn -0.2605 0.6733 0.6920 +vn -0.0757 -0.2212 -0.9723 +vn 0.2331 0.9480 -0.2167 +vn 0.9709 -0.2393 -0.0040 +vn -0.9684 0.2467 0.0364 +vn 0.1765 0.0638 0.9822 +vn 0.2141 -0.2270 0.9501 +vn -0.9793 -0.0037 0.2022 +vn -0.1814 0.2271 -0.9568 +vn -0.0260 -0.9737 -0.2264 +vn 0.0587 0.9738 0.2197 +vn -0.0127 -0.9987 0.0502 +vn -0.1761 -0.0305 -0.9839 +vn 0.9843 -0.0047 -0.1763 +vn -0.9839 0.0380 0.1747 +vn 0.2515 0.0928 0.9634 +vn 0.1718 -0.2146 0.9615 +vn -0.8380 0.4893 0.2416 +vn -0.1438 0.1983 -0.9695 +vn -0.5084 -0.8553 -0.0998 +vn 0.5363 0.8390 0.0917 +vn -0.0999 -0.9895 0.1041 +vn -0.2482 -0.0598 -0.9669 +vn 0.9646 -0.1060 -0.2414 +vn -0.9613 0.1389 0.2379 +vn 0.2891 -0.8621 0.4162 +vn 0.1727 -0.7135 0.6791 +vn 0.8157 0.4992 0.2925 +vn -0.1999 0.6968 -0.6888 +vn 0.5340 -0.5117 -0.6730 +vn -0.5612 0.4950 0.6633 +vn 0.1137 -0.3848 -0.9160 +vn -0.2929 0.8749 -0.3857 +vn -0.9517 -0.3058 0.0285 +vn 0.9479 0.3186 0.0020 +vn -0.1765 0.0638 0.9822 +vn -0.2141 -0.2270 0.9501 +vn 0.9793 -0.0037 0.2022 +vn 0.1814 0.2271 -0.9568 +vn 0.0260 -0.9737 -0.2264 +vn -0.0587 0.9738 0.2197 +vn 0.0127 -0.9987 0.0502 +vn 0.1761 -0.0305 -0.9839 +vn -0.9843 -0.0047 -0.1763 +vn 0.9839 0.0380 0.1747 +vn -0.2515 0.0928 0.9634 +vn -0.1718 -0.2146 0.9615 +vn 0.8380 0.4893 0.2416 +vn 0.1438 0.1983 -0.9695 +vn 0.5084 -0.8553 -0.0998 +vn -0.5363 0.8390 0.0917 +vn 0.0999 -0.9895 0.1041 +vn 0.2482 -0.0598 -0.9669 +vn -0.9646 -0.1060 -0.2414 +vn 0.9613 0.1389 0.2379 +vn 0.0000 0.0749 -0.9972 +vn 0.0000 -0.9972 -0.0749 +vn 0.0000 0.9972 0.0749 +vn 0.0000 -0.9990 -0.0455 +vn 0.0000 0.9990 0.0455 +vn 0.0000 -0.0455 0.9990 +vn 0.0000 -0.0446 0.9990 +vn 0.0000 0.9990 0.0446 +vn -0.0000 -0.9990 -0.0446 +vn 0.0000 -0.0513 0.9987 +vn 0.0000 0.9987 0.0513 +vn 0.0000 -0.9987 -0.0513 +vn 0.0000 -0.9992 -0.0404 +vn 0.0000 0.9992 0.0404 +vn 0.0000 -0.0404 0.9992 +vn 0.0000 -0.0415 0.9991 +vn 0.0000 0.9991 0.0415 +vn 0.0000 -0.9991 -0.0415 +vn 0.0000 -0.6739 0.7389 +vn 0.0000 0.7388 0.6739 +vn 0.0000 -0.7389 -0.6739 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/3/2 8/6/2 7/7/2 +f 7/8/3 8/6/3 6/9/3 5/10/3 +f 5/11/4 6/9/4 2/2/4 1/12/4 +f 3/13/5 7/14/5 5/15/5 1/16/5 +f 8/6/6 4/3/6 2/2/6 6/9/6 +f 19/17/7 20/18/7 24/19/7 23/20/7 +f 11/21/8 12/22/8 16/23/8 15/24/8 +f 15/25/9 16/26/9 14/27/9 13/28/9 +f 13/29/10 14/27/10 10/30/10 9/31/10 +f 11/21/11 15/24/11 13/29/11 9/31/11 +f 16/26/12 12/32/12 10/30/12 14/27/12 +f 23/20/13 24/19/13 22/33/13 21/34/13 +f 21/35/14 22/36/14 18/37/14 17/38/14 +f 19/39/15 23/40/15 21/35/15 17/38/15 +f 24/19/16 20/18/16 18/37/16 22/36/16 +f 35/41/17 36/42/17 40/43/17 39/44/17 +f 27/45/18 28/46/18 32/47/18 31/48/18 +f 31/49/19 32/50/19 30/51/19 29/52/19 +f 29/53/20 30/51/20 26/54/20 25/55/20 +f 27/45/21 31/48/21 29/53/21 25/55/21 +f 32/50/22 28/56/22 26/54/22 30/51/22 +f 39/44/23 40/43/23 38/57/23 37/58/23 +f 37/59/24 38/60/24 34/61/24 33/62/24 +f 35/63/25 39/64/25 37/59/25 33/62/25 +f 40/43/26 36/42/26 34/61/26 38/60/26 +f 51/65/27 52/66/27 56/67/27 55/68/27 +f 43/69/28 44/70/28 48/71/28 47/72/28 +f 47/73/29 48/74/29 46/75/29 45/76/29 +f 45/77/30 46/75/30 42/78/30 41/79/30 +f 43/69/31 47/72/31 45/77/31 41/79/31 +f 48/74/32 44/80/32 42/78/32 46/75/32 +f 55/68/33 56/67/33 54/81/33 53/82/33 +f 53/83/34 54/84/34 50/85/34 49/86/34 +f 51/87/35 55/88/35 53/83/35 49/86/35 +f 56/67/36 52/66/36 50/85/36 54/84/36 +f 67/89/37 71/90/37 72/91/37 68/92/37 +f 59/93/38 63/94/38 64/95/38 60/96/38 +f 63/97/39 61/98/39 62/99/39 64/100/39 +f 61/101/40 57/102/40 58/103/40 62/99/40 +f 59/93/41 57/102/41 61/101/41 63/94/41 +f 64/100/42 62/99/42 58/103/42 60/104/42 +f 71/90/43 69/105/43 70/106/43 72/91/43 +f 69/107/44 65/108/44 66/109/44 70/110/44 +f 67/111/45 65/108/45 69/107/45 71/112/45 +f 72/91/46 70/110/46 66/109/46 68/92/46 +f 83/113/47 87/114/47 88/115/47 84/116/47 +f 75/117/48 79/118/48 80/119/48 76/120/48 +f 79/121/49 77/122/49 78/123/49 80/124/49 +f 77/125/50 73/126/50 74/127/50 78/123/50 +f 75/117/51 73/126/51 77/125/51 79/118/51 +f 80/124/52 78/123/52 74/127/52 76/128/52 +f 87/114/53 85/129/53 86/130/53 88/115/53 +f 85/131/54 81/132/54 82/133/54 86/134/54 +f 83/135/55 81/132/55 85/131/55 87/136/55 +f 88/115/56 86/134/56 82/133/56 84/116/56 +f 99/137/57 103/138/57 104/139/57 100/140/57 +f 91/141/58 95/142/58 96/143/58 92/144/58 +f 95/145/59 93/146/59 94/147/59 96/148/59 +f 93/149/60 89/150/60 90/151/60 94/147/60 +f 91/141/61 89/150/61 93/149/61 95/142/61 +f 96/148/62 94/147/62 90/151/62 92/152/62 +f 103/138/63 101/153/63 102/154/63 104/139/63 +f 101/155/64 97/156/64 98/157/64 102/158/64 +f 99/159/65 97/156/65 101/155/65 103/160/65 +f 104/139/66 102/158/66 98/157/66 100/140/66 +f 108/161/1 107/162/1 105/163/1 106/164/1 +f 111/165/3 112/166/3 110/167/3 109/168/3 +f 109/168/67 110/167/67 107/162/67 108/161/67 +f 106/169/68 111/170/68 109/168/68 108/161/68 +f 112/171/69 105/172/69 107/162/69 110/167/69 +f 122/173/70 118/174/70 120/175/70 124/176/70 +f 117/177/71 121/178/71 123/179/71 119/180/71 +f 122/173/72 121/181/72 117/182/72 118/174/72 +f 128/183/73 140/184/73 116/185/73 115/186/73 +f 115/187/3 116/188/3 114/189/3 113/190/3 +f 116/188/74 140/191/74 125/192/74 114/189/74 +f 118/193/3 117/177/3 119/180/3 120/194/3 +f 128/183/75 115/186/75 113/195/75 144/196/75 +f 124/176/1 123/179/1 121/178/1 122/173/1 +f 144/196/1 125/192/1 140/191/1 128/183/1 +f 132/197/76 133/198/76 130/199/76 129/200/76 +f 129/201/3 130/202/3 127/203/3 126/204/3 +f 130/202/77 133/205/77 131/206/77 127/203/77 +f 132/197/78 129/200/78 126/207/78 134/208/78 +f 134/208/1 131/206/1 133/205/1 132/197/1 +f 135/209/1 138/210/1 136/211/1 137/212/1 +f 137/212/79 141/213/79 143/214/79 135/209/79 +f 139/215/80 136/211/80 138/210/80 142/216/80 +f 141/217/3 139/215/3 142/216/3 143/218/3 +f 137/212/81 136/219/81 139/220/81 141/213/81 +f 150/221/82 151/222/82 148/223/82 147/224/82 +f 147/225/3 148/226/3 146/227/3 145/228/3 +f 148/226/83 151/229/83 149/230/83 146/227/83 +f 150/221/84 147/224/84 145/231/84 152/232/84 +f 152/232/1 149/230/1 151/229/1 150/221/1 +f 158/233/85 159/234/85 156/235/85 155/236/85 +f 155/237/3 156/238/3 154/239/3 153/240/3 +f 156/238/86 159/241/86 157/242/86 154/239/86 +f 158/233/87 155/236/87 153/243/87 160/244/87 +f 160/244/1 157/242/1 159/241/1 158/233/1 diff --git a/mods/hall/models/hall_stanchion_post.obj b/mods/hall/models/hall_stanchion_post.obj new file mode 100644 index 0000000..067215c --- /dev/null +++ b/mods/hall/models/hall_stanchion_post.obj @@ -0,0 +1,71 @@ +# Blender v2.80 (sub 75) OBJ File: 'Hall.blend' +# www.blender.org +o Stanchion_post_Cube.002 +v -0.125000 -0.437500 0.125000 +v -0.125000 0.437500 0.125000 +v -0.125000 -0.437500 -0.125000 +v -0.125000 0.437500 -0.125000 +v 0.125000 -0.437500 0.125000 +v 0.125000 0.437500 0.125000 +v 0.125000 -0.437500 -0.125000 +v 0.125000 0.437500 -0.125000 +v -0.312500 -0.437500 0.312500 +v -0.312500 -0.437500 -0.312500 +v 0.312500 -0.437500 0.312500 +v 0.312500 -0.437500 -0.312500 +v -0.312500 -0.500000 0.312500 +v -0.312500 -0.500000 -0.312500 +v 0.312500 -0.500000 -0.312500 +v 0.312500 -0.500000 0.312500 +vt 0.625000 0.750000 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 0.625000 0.500000 +vt 0.625000 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.750000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.250000 +vt 0.625000 0.250000 +vt 0.812500 0.187500 +vt 0.187500 0.187500 +vt 0.187500 0.812500 +vt 0.812500 0.812500 +vt -0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt 0.187500 0.875000 +vt 0.812500 0.875000 +vt 0.187500 0.125000 +vt 0.187500 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.125000 0.812500 +vt 0.187500 0.812500 +vt 0.125000 0.187500 +vt 0.875000 0.187500 +vt 0.812500 0.812500 +vt 0.875000 0.812500 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 1.0000 0.0000 +g Stanchion_post_Cube.002_Material +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 7/9/3 8/10/3 6/11/3 5/12/3 +f 5/13/4 6/14/4 2/15/4 1/16/4 +f 12/17/5 10/18/5 9/19/5 11/20/5 +f 8/21/5 4/22/5 2/23/5 6/11/5 +f 9/19/4 13/24/4 16/25/4 11/20/4 +f 12/26/2 15/27/2 14/28/2 10/29/2 +f 11/30/3 16/31/3 15/27/3 12/32/3 +f 10/33/1 14/28/1 13/34/1 9/35/1 diff --git a/mods/hall/models/hall_stanchion_post_sign.obj b/mods/hall/models/hall_stanchion_post_sign.obj new file mode 100644 index 0000000..bcfc3ed --- /dev/null +++ b/mods/hall/models/hall_stanchion_post_sign.obj @@ -0,0 +1,105 @@ +# Blender v2.80 (sub 75) OBJ File: 'Hall.blend' +# www.blender.org +o Stanchion_post_sign_Cube.002 +v 0.125000 -0.437500 -0.125000 +v 0.125000 0.437500 -0.125000 +v 0.125000 -0.437500 0.125000 +v 0.125000 0.437500 0.125000 +v -0.125000 -0.437500 -0.125000 +v -0.125000 0.437500 -0.125000 +v -0.125000 -0.437500 0.125000 +v -0.125000 0.437500 0.125000 +v 0.312500 -0.437500 -0.312500 +v 0.312500 -0.437500 0.312500 +v -0.312500 -0.437500 -0.312500 +v -0.312500 -0.437500 0.312500 +v 0.312500 -0.500000 -0.312500 +v 0.312500 -0.500000 0.312500 +v -0.312500 -0.500000 0.312500 +v -0.312500 -0.500000 -0.312500 +v 0.312500 0.372656 -0.125000 +v 0.312500 0.372656 -0.187500 +v -0.312500 0.372656 -0.187500 +v -0.312500 0.372656 -0.125000 +v -0.312500 -0.002344 -0.125000 +v 0.312500 -0.002344 -0.125000 +v 0.312500 -0.002344 -0.187500 +v -0.312500 -0.002344 -0.187500 +vt 0.625000 0.750000 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 0.625000 0.500000 +vt 0.625000 0.250000 +vt 0.000000 0.250000 +vt 0.000000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.750000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.000000 0.500000 +vt 0.000000 0.250000 +vt 0.625000 0.250000 +vt 0.812500 0.187500 +vt 0.187500 0.187500 +vt 0.187500 0.812500 +vt 0.812500 0.812500 +vt -0.000000 0.500000 +vt 0.250000 0.500000 +vt 0.250000 0.750000 +vt 0.187500 0.875000 +vt 0.812500 0.875000 +vt 0.187500 0.125000 +vt 0.187500 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.125000 0.812500 +vt 0.187500 0.812500 +vt 0.125000 0.187500 +vt 0.875000 0.187500 +vt 0.812500 0.812500 +vt 0.875000 0.812500 +vt 0.812500 0.687500 +vt 0.812500 0.750000 +vt 0.187500 0.750000 +vt 0.187500 0.687500 +vt 0.812500 0.312500 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.812500 0.250000 +vt 0.875000 0.687500 +vt 0.812500 0.687500 +vt 0.812500 0.312500 +vt 0.875000 0.312500 +vt 0.125000 0.687500 +vt 0.187500 0.687500 +vt 0.187500 0.312500 +vt 0.125000 0.312500 +vt 0.187500 0.687500 +vt 0.187500 0.312500 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.0000 0.0000 +g Stanchion_post_sign_Cube.002_Material +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 7/9/3 8/10/3 6/11/3 5/12/3 +f 5/13/4 6/14/4 2/15/4 1/16/4 +f 12/17/5 10/18/5 9/19/5 11/20/5 +f 8/21/5 4/22/5 2/23/5 6/11/5 +f 9/19/4 13/24/4 16/25/4 11/20/4 +f 12/26/2 15/27/2 14/28/2 10/29/2 +f 11/30/3 16/31/3 15/27/3 12/32/3 +f 10/33/1 14/28/1 13/34/1 9/35/1 +g Stanchion_post_sign_Cube.002_Sign +f 17/36/5 18/37/5 19/38/5 20/39/5 +f 22/40/6 21/41/6 24/42/6 23/43/6 +f 20/44/3 19/45/3 24/46/3 21/47/3 +f 18/48/1 17/49/1 22/50/1 23/51/1 +f 19/45/4 18/52/4 23/53/4 24/46/4 +f 17/36/2 20/39/2 21/41/2 22/40/2 diff --git a/mods/hall/models/hall_stanchion_rope.obj b/mods/hall/models/hall_stanchion_rope.obj new file mode 100644 index 0000000..ad46600 --- /dev/null +++ b/mods/hall/models/hall_stanchion_rope.obj @@ -0,0 +1,73 @@ +# Blender v2.80 (sub 75) OBJ File: 'Hall.blend' +# www.blender.org +o Stanchion_rope_Cube.006 +v -0.875000 0.250000 0.062500 +v -0.875000 0.375000 0.062500 +v -0.875000 0.250000 -0.062500 +v -0.875000 0.375000 -0.062500 +v 0.875000 0.250000 0.062500 +v 0.875000 0.375000 0.062500 +v 0.875000 0.250000 -0.062500 +v 0.875000 0.375000 -0.062500 +v -0.500000 0.187500 -0.062500 +v -0.500000 0.312500 -0.062500 +v -0.500000 0.187500 0.062500 +v -0.500000 0.312500 0.062500 +v 0.500000 0.312500 -0.062500 +v 0.500000 0.187500 0.062500 +v 0.500000 0.187500 -0.062500 +v 0.500000 0.312500 0.062500 +vt 0.250000 0.214286 +vt 0.000000 0.214286 +vt 0.000000 0.000000 +vt 0.250000 0.000000 +vt 0.250001 0.785714 +vt 0.500001 0.785714 +vt 0.500001 1.000000 +vt 0.250001 1.000000 +vt 0.750000 0.785714 +vt 0.750000 1.000000 +vt 0.500001 1.000000 +vt 0.500001 0.785714 +vt 0.750000 0.214286 +vt 0.750000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.214286 +vt 0.750000 0.785714 +vt 1.000000 0.785714 +vt 0.750000 0.000000 +vt 0.750000 0.214286 +vt 0.500001 0.214286 +vt 0.500001 0.000000 +vt 0.250000 0.214286 +vt 0.500000 0.214286 +vt 0.250000 1.000000 +vt 0.000001 1.000000 +vt 0.000000 0.785714 +vt 0.250000 0.785714 +vt 0.250000 0.000000 +vt 0.500000 0.000000 +vt 0.750000 1.000000 +vt 1.000000 1.000000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.1644 -0.9864 0.0000 +vn 0.1644 0.9864 0.0000 +vn 0.0000 1.0000 0.0000 +vn -0.1644 -0.9864 0.0000 +vn -0.1644 0.9864 0.0000 +vn 0.0000 -1.0000 0.0000 +g Stanchion_rope_Cube.006_wool +s off +f 15/1/1 13/2/1 8/3/1 7/4/1 +f 11/5/2 12/6/2 2/7/2 1/8/2 +f 15/9/3 7/10/3 5/11/3 14/12/3 +f 10/13/4 4/14/4 2/15/4 12/16/4 +f 13/17/5 10/13/5 12/16/5 16/18/5 +f 3/19/6 9/20/6 11/21/6 1/22/6 +f 14/23/2 16/24/2 12/6/2 11/5/2 +f 3/25/1 4/26/1 10/27/1 9/28/1 +f 5/29/2 6/30/2 16/24/2 14/23/2 +f 8/31/7 13/17/7 16/18/7 6/32/7 +f 9/20/8 15/9/8 14/12/8 11/21/8 +f 9/28/1 10/27/1 13/2/1 15/1/1 diff --git a/mods/hall/models/hall_stanchion_rope_sign.obj b/mods/hall/models/hall_stanchion_rope_sign.obj new file mode 100644 index 0000000..9dff557 --- /dev/null +++ b/mods/hall/models/hall_stanchion_rope_sign.obj @@ -0,0 +1,108 @@ +# Blender v2.80 (sub 75) OBJ File: 'Hall.blend' +# www.blender.org +o Stanchion_rope_sign_Cube.003 +v -0.875000 0.250000 0.062500 +v -0.875000 0.375000 0.062500 +v -0.875000 0.250000 -0.062500 +v -0.875000 0.375000 -0.062500 +v 0.875000 0.250000 0.062500 +v 0.875000 0.375000 0.062500 +v 0.875000 0.250000 -0.062500 +v 0.875000 0.375000 -0.062500 +v -0.500000 0.187500 -0.062500 +v -0.500000 0.312500 -0.062500 +v -0.500000 0.187500 0.062500 +v -0.500000 0.312500 0.062500 +v 0.500000 0.312500 -0.062500 +v 0.500000 0.187500 0.062500 +v 0.500000 0.187500 -0.062500 +v 0.500000 0.312500 0.062500 +v -0.312500 0.185156 -0.031250 +v -0.312500 0.185156 0.031250 +v 0.312500 0.185156 0.031250 +v 0.312500 0.185156 -0.031250 +v 0.312500 -0.189844 -0.031250 +v -0.312500 -0.189844 -0.031250 +v -0.312500 -0.189844 0.031250 +v 0.312500 -0.189844 0.031250 +vt 0.250000 0.214286 +vt 0.000000 0.214286 +vt 0.000000 0.000000 +vt 0.250000 0.000000 +vt 0.250001 0.785714 +vt 0.500001 0.785714 +vt 0.500001 1.000000 +vt 0.250001 1.000000 +vt 0.750000 0.785714 +vt 0.750000 1.000000 +vt 0.500001 1.000000 +vt 0.500001 0.785714 +vt 0.750000 0.214286 +vt 0.750000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.214286 +vt 0.750000 0.785714 +vt 1.000000 0.785714 +vt 0.750000 0.000000 +vt 0.750000 0.214286 +vt 0.500001 0.214286 +vt 0.500001 0.000000 +vt 0.250000 0.214286 +vt 0.500000 0.214286 +vt 0.250000 1.000000 +vt 0.000001 1.000000 +vt 0.000000 0.785714 +vt 0.250000 0.785714 +vt 0.250000 0.000000 +vt 0.500000 0.000000 +vt 0.750000 1.000000 +vt 1.000000 1.000000 +vt 0.812500 0.687500 +vt 0.812500 0.750000 +vt 0.187500 0.750000 +vt 0.187500 0.687500 +vt 0.812500 0.312500 +vt 0.187500 0.312500 +vt 0.187500 0.250000 +vt 0.812500 0.250000 +vt 0.875000 0.687500 +vt 0.812500 0.687500 +vt 0.812500 0.312500 +vt 0.875000 0.312500 +vt 0.125000 0.687500 +vt 0.187500 0.687500 +vt 0.187500 0.312500 +vt 0.125000 0.312500 +vt 0.187500 0.687500 +vt 0.187500 0.312500 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 0.0000 1.0000 +vn 0.1644 -0.9864 0.0000 +vn 0.1644 0.9864 0.0000 +vn 0.0000 1.0000 0.0000 +vn -0.1644 -0.9864 0.0000 +vn -0.1644 0.9864 0.0000 +vn 0.0000 -1.0000 0.0000 +vn 1.0000 0.0000 0.0000 +vn -1.0000 0.0000 0.0000 +g Stanchion_rope_sign_Cube.003_wool +s off +f 15/1/1 13/2/1 8/3/1 7/4/1 +f 11/5/2 12/6/2 2/7/2 1/8/2 +f 15/9/3 7/10/3 5/11/3 14/12/3 +f 10/13/4 4/14/4 2/15/4 12/16/4 +f 13/17/5 10/13/5 12/16/5 16/18/5 +f 3/19/6 9/20/6 11/21/6 1/22/6 +f 14/23/2 16/24/2 12/6/2 11/5/2 +f 3/25/1 4/26/1 10/27/1 9/28/1 +f 5/29/2 6/30/2 16/24/2 14/23/2 +f 8/31/7 13/17/7 16/18/7 6/32/7 +f 9/20/8 15/9/8 14/12/8 11/21/8 +f 9/28/1 10/27/1 13/2/1 15/1/1 +g Stanchion_rope_sign_Cube.003_Sign +f 17/33/5 18/34/5 19/35/5 20/36/5 +f 22/37/8 21/38/8 24/39/8 23/40/8 +f 20/41/9 19/42/9 24/43/9 21/44/9 +f 18/45/10 17/46/10 22/47/10 23/48/10 +f 19/42/2 18/49/2 23/50/2 24/43/2 +f 17/33/1 20/36/1 21/38/1 22/37/1 diff --git a/mods/hall/nodes.lua b/mods/hall/nodes.lua new file mode 100644 index 0000000..c234942 --- /dev/null +++ b/mods/hall/nodes.lua @@ -0,0 +1,143 @@ +minetest.register_node('hall:stanchion_post', { + description = 'Stanchion post', + drawtype = 'mesh', + mesh = 'hall_stanchion_post.obj', + tiles = {'default_aspen_wood.png'}, + sounds = default.node_sound_wood_defaults(), + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-.2, -.5, -.2, .2, .5, .2}, + }, + collision_box = { + type = 'fixed', + fixed = {-.2, -.5, -.2, .2, .5, .2}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3}, +}) + +minetest.register_node('hall:stanchion_post_sign', { + description = 'Stanchion post', + drawtype = 'mesh', + mesh = 'hall_stanchion_post_sign.obj', + tiles = {'default_aspen_wood.png', 'hall_plaque_texture.png'}, + sounds = default.node_sound_wood_defaults(), + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-.2, -.5, -.2, .2, .5, .2}, + }, + collision_box = { + type = 'fixed', + fixed = {-.2, -.5, -.2, .2, .5, .2}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3}, + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string('owner', placer:get_player_name()) + meta:set_string('infotext', 'Empty Sign') + meta:set_string('title', '') + meta:set_string('bottom', '') + meta:set_string('left', '') + meta:set_string('right', '') + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local name = clicker:get_player_name() + local meta = minetest.get_meta(pos) + local owner = meta:get_string('owner') + local title = meta:get_string('title') + local bottom = meta:get_string('bottom') + local left = meta:get_string('left') + local right = meta:get_string('right') + if owner == name then + meta:set_string('formspec', hall.edit_sign(title, bottom, left, right)) + else + meta:set_string('formspec', hall.view_sign(title, bottom, left, right)) + end + end, + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if fields ['save'] then + local player_name = sender:get_player_name() + meta:set_string('infotext', fields.title) + meta:set_string('title', fields.title) + meta:set_string('bottom', fields.bottom) + meta:set_string('left', fields.left) + meta:set_string('right', fields.right) + minetest.log("action", (player_name or "").." wrote \""..fields.title.."\" to stanchion at "..minetest.pos_to_string(pos)) + end + end, +}) + +minetest.register_node('hall:stanchion_rope', { + description = 'Stanchion rope', + drawtype = 'mesh', + mesh = 'hall_stanchion_rope.obj', + tiles = {'wool.png^[multiply:#1a1a1a'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-.6, -.2, -.2, .6, .4, .2}, + }, + collision_box = { + type = 'fixed', + fixed = {-.6, -.2, -.2, .6, .4, .2}, + }, + groups = {oddly_breakable_by_hand = 2, snappy=3}, +}) + +minetest.register_node('hall:stanchion_rope_sign', { + description = 'Stanchion rope', + drawtype = 'mesh', + mesh = 'hall_stanchion_rope_sign.obj', + tiles = {'wool.png^[multiply:#1a1a1a','hall_plaque_texture.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-.6, -.2, -.2, .6, .4, .2}, + }, + collision_box = { + type = 'fixed', + fixed = {-.6, -.2, -.2, .6, .4, .2}, + }, + groups = {oddly_breakable_by_hand = 2, snappy=3}, + after_place_node = function(pos, placer) + local meta = minetest.get_meta(pos) + meta:set_string('owner', placer:get_player_name()) + meta:set_string('infotext', 'Empty Sign') + meta:set_string('title', '') + meta:set_string('bottom', '') + meta:set_string('left', '') + meta:set_string('right', '') + end, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local name = clicker:get_player_name() + local meta = minetest.get_meta(pos) + local owner = meta:get_string('owner') + local title = meta:get_string('title') + local bottom = meta:get_string('bottom') + local left = meta:get_string('left') + local right = meta:get_string('right') + if owner == name then + meta:set_string('formspec', hall.edit_sign(title, bottom, left, right)) + else + meta:set_string('formspec', hall.view_sign(title, bottom, left, right)) + end + end, + on_receive_fields = function(pos, formname, fields, sender) + local meta = minetest.get_meta(pos) + if fields ['save'] then + local player_name = sender:get_player_name() + meta:set_string('infotext', fields.title) + meta:set_string('title', fields.title) + meta:set_string('bottom', fields.bottom) + meta:set_string('left', fields.left) + meta:set_string('right', fields.right) + minetest.log("action", (player_name or "").." wrote \""..fields.title.."\" to stanchion at "..minetest.pos_to_string(pos)) + end + end, +}) diff --git a/mods/hall/spill.lua b/mods/hall/spill.lua new file mode 100644 index 0000000..7ea9ce2 --- /dev/null +++ b/mods/hall/spill.lua @@ -0,0 +1,129 @@ +local priv_spill_formspec_base = + 'size[12,7]'.. + 'no_prepend[]'.. + 'bgcolor[#080808BB;true]'.. + 'background[0,0;12,7;hall_chalkboard_bg.png]'.. + 'hypertext[0,.2;12,1;;
]' + +local esc = minetest.formspec_escape + +local lesson = "The spill privilege will let you empty liquids from buckets. ".. + "Due to the griefing potential of liquids there is this quiz. ".. + "There are a few things you should know about liquids and spilling them. Besides the obvious that spills can get messy, ".. + "lava will start flammable nodes on fire. If you're going to place lava make sure there isn't anything around that can burn. ".. + "Keep in mind that Grass is flammable on this server. Water is less dangerous, but due to it's infinite nature ".. + "it can easily make a huge mess that will take a while to clean up. \n".. + "Bulk dumping of water and lava underground, away from other players areas is fine. Be it for farming mobs, or making elevators.".. + "You must never empty liquids in such a way that they flow into another players protected area(s).".. + "You may face jail time, or banning for intentionally ignoring these rules." + +local priv_spill_formspec_lesson = + priv_spill_formspec_base.. + "textarea[.75,1.5;11.25,6;;;"..esc(lesson).."]" .. + 'button[4.5,5;3,1;go;Take Quiz]' + +local priv_spill_formspec_1 = + priv_spill_formspec_base.. + "textarea[1,1.5;11,3;;;What privilege do you need to empty buckets?]" .. + 'button[1,4;3,1;wrong;A) Bucket]'.. + 'button[4.5,4;3,1;wrong;B) Liquid]'.. + 'button[8,4;3,1;wrong;C) Splash]'.. + 'button[1,5.5;3,1;right;D) Spill]'.. + 'button[4.5,5.5;3,1;wrong;E) Water]'.. + 'button[8,5.5;3,1;wrong;F) Lava]' + +local priv_spill_formspec_2 = + priv_spill_formspec_base.. + "textarea[1,1.5;11,3;;;Are water elevators allowed?]" .. + 'button[1,4;3,1;wrong;A) No]'.. + 'button[4.5,4;3,1;wrong;B) No]'.. + 'button[8,4;3,1;wrong;C) No]'.. + 'button[1,5.5;3,1;right;D) Yes]'.. + 'button[4.5,5.5;3,1;right;E) Yes]'.. + 'button[8,5.5;3,1;right;F) Yes]' + +local priv_spill_formspec_3 = + priv_spill_formspec_base.. + "textarea[1,1.5;11,3;;;Do you need the spill privilege to pick up liquids with a bucket?]" .. + 'button[1,4;3,1;right;A) No]'.. + 'button[4.5,4;3,1;wrong;B) Yes]'.. + "button[8,4;3,1;right;C) The lesson didn't say]".. + "button[1,5.5;3,1;right;D) I don't know]".. + 'button[4.5,5.5;3,1;wrong;E) This quiz is junk!]'.. + "button[8,5.5;3,1;wrong;F) Don't pick me]" + +local priv_spill_formspec_4 = + priv_spill_formspec_base.. + "textarea[1,1.5;11,3;;;Are you allowed to grief with liquids?]" .. + 'button[1,4;3,1;wrong;A) Yes]'.. + 'button[4.5,4;3,1;wrong;B) Sure]'.. + 'button[8,4;3,1;wrong;C) Why not?]'.. + 'button[1,5.5;3,1;right;D) No]'.. + 'button[4.5,5.5;3,1;right;E) Nope]'.. + 'button[8,5.5;3,1;right;F) Absolutely not]' + +local priv_spill_formspec_5 = + priv_spill_formspec_base.. + "textarea[1,1.5;11,3;;;You've passed the quiz! You now have the spill privilege]".. + 'button_exit[4.5,5;3,1;;Exit]' + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = player:get_player_name() + if formname == 'hall:priv_spill_lesson' then + if fields.go then + minetest.show_formspec(name, 'hall:priv_spill_1', priv_spill_formspec_1) + end + elseif formname == 'hall:priv_spill_1' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_spill_2', priv_spill_formspec_2) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_spill_lesson', priv_spill_formspec_lesson) + end + elseif formname == 'hall:priv_spill_2' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_spill_3', priv_spill_formspec_3) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_spill_lesson', priv_spill_formspec_lesson) + end + elseif formname == 'hall:priv_spill_3' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_spill_4', priv_spill_formspec_4) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_spill_lesson', priv_spill_formspec_lesson) + end + elseif formname == 'hall:priv_spill_4' then + if fields.right then + minetest.show_formspec(name, 'hall:priv_spill_5', priv_spill_formspec_5) + local privs = minetest.get_player_privs(name) + privs.spill = true + minetest.set_player_privs(name, privs) + elseif fields.wrong then + minetest.show_formspec(name, 'hall:priv_spill_lesson', priv_spill_formspec_lesson) + end + end +end) + +minetest.register_node('hall:priv_spill', { + description = 'Spill Course', + drawtype = 'mesh', + mesh = 'hall_chalkboard.obj', + tiles = {'hall_chalkboard_spill.png'}, + paramtype2 = 'facedir', + paramtype = 'light', + selection_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + collision_box = { + type = 'fixed', + fixed = {-1, -.75, .4375, 1, .5, .5}, + }, + groups = {oddly_breakable_by_hand = 2, choppy=3, not_in_creative_inventory=1}, + on_rightclick = function(pos, node, clicker, itemstack) + local meta = minetest.get_meta(pos) + local name = clicker:get_player_name() + meta:set_string('infotext', 'Spill Privs Course') + minetest.show_formspec(name, 'hall:priv_spill_lesson', priv_spill_formspec_lesson) + end, +}) diff --git a/mods/hall/textures/hall_chalkboard.png b/mods/hall/textures/hall_chalkboard.png new file mode 100644 index 0000000..9050221 Binary files /dev/null and b/mods/hall/textures/hall_chalkboard.png differ diff --git a/mods/hall/textures/hall_chalkboard_areas.png b/mods/hall/textures/hall_chalkboard_areas.png new file mode 100644 index 0000000..51e8d84 Binary files /dev/null and b/mods/hall/textures/hall_chalkboard_areas.png differ diff --git a/mods/hall/textures/hall_chalkboard_bg.png b/mods/hall/textures/hall_chalkboard_bg.png new file mode 100644 index 0000000..c2d7116 Binary files /dev/null and b/mods/hall/textures/hall_chalkboard_bg.png differ diff --git a/mods/hall/textures/hall_chalkboard_fire.png b/mods/hall/textures/hall_chalkboard_fire.png new file mode 100644 index 0000000..f7c944e Binary files /dev/null and b/mods/hall/textures/hall_chalkboard_fire.png differ diff --git a/mods/hall/textures/hall_chalkboard_lumberjack.png b/mods/hall/textures/hall_chalkboard_lumberjack.png new file mode 100644 index 0000000..9fe0292 Binary files /dev/null and b/mods/hall/textures/hall_chalkboard_lumberjack.png differ diff --git a/mods/hall/textures/hall_chalkboard_markets.png b/mods/hall/textures/hall_chalkboard_markets.png new file mode 100644 index 0000000..b062b05 Binary files /dev/null and b/mods/hall/textures/hall_chalkboard_markets.png differ diff --git a/mods/hall/textures/hall_chalkboard_spill.png b/mods/hall/textures/hall_chalkboard_spill.png new file mode 100644 index 0000000..7729e9e Binary files /dev/null and b/mods/hall/textures/hall_chalkboard_spill.png differ diff --git a/mods/hall/textures/hall_plaque.png b/mods/hall/textures/hall_plaque.png new file mode 100644 index 0000000..94d6b0d Binary files /dev/null and b/mods/hall/textures/hall_plaque.png differ diff --git a/mods/hall/textures/hall_plaque_texture.png b/mods/hall/textures/hall_plaque_texture.png new file mode 100644 index 0000000..9a3887b Binary files /dev/null and b/mods/hall/textures/hall_plaque_texture.png differ diff --git a/mods/hall/textures/hall_privs_book.png b/mods/hall/textures/hall_privs_book.png new file mode 100644 index 0000000..fd595b7 Binary files /dev/null and b/mods/hall/textures/hall_privs_book.png differ diff --git a/mods/hangglider/GNU_GPL.txt b/mods/hangglider/GNU_GPL.txt new file mode 100755 index 0000000..1451535 --- /dev/null +++ b/mods/hangglider/GNU_GPL.txt @@ -0,0 +1,185 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS +0. Definitions. +“This License†refers to version 3 of the GNU General Public License. + +“Copyright†also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program†refers to any copyrightable work licensed under this License. Each licensee is addressed as “youâ€. “Licensees†and “recipients†may be individuals or organizations. + +To “modify†a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version†of the earlier work or a work “based on†the earlier work. + +A “covered work†means either the unmodified Program or a work based on the Program. + +To “propagate†a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey†a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices†to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code†for a work means the preferred form of the work for making modifications to it. “Object code†means any non-source form of a work. + +A “Standard Interface†means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries†of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Componentâ€, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source†for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified it, and giving a relevant date. +b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all noticesâ€. +c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. +d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate†if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + +a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. +b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. +c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. +d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. +e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product†is either (1) a “consumer productâ€, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used†refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information†for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions†are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or +b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or +c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or +d) Limiting the use for publicity purposes of names of licensors or authors of the material; or +e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or +f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. +All other non-permissive additional terms are considered “further restrictions†within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction†is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor†is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor versionâ€. + +A contributor's “essential patent claims†are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control†includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license†is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant†such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying†means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory†if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version†applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS†WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/mods/hangglider/GNU_LGPL.txt b/mods/hangglider/GNU_LGPL.txt new file mode 100644 index 0000000..f166cc5 --- /dev/null +++ b/mods/hangglider/GNU_LGPL.txt @@ -0,0 +1,502 @@ + 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! \ No newline at end of file diff --git a/mods/hangglider/depends.txt b/mods/hangglider/depends.txt new file mode 100755 index 0000000..6bae540 --- /dev/null +++ b/mods/hangglider/depends.txt @@ -0,0 +1,5 @@ +default +wool +minetest_systemd? +areas? +player_monoids? diff --git a/mods/hangglider/init.lua b/mods/hangglider/init.lua new file mode 100644 index 0000000..494ec45 --- /dev/null +++ b/mods/hangglider/init.lua @@ -0,0 +1,346 @@ +-- Hangglider mod for Minetest +-- Original code by Piezo_ (orderofthefourthwall@gmail.com) +-- 2018-11-14 + +-- Modifications by David G (kestral246@gmail.com) +-- 2018-11-24 +-- For Minetest 5.x, glider's set_attach needs to be offset by 1 node +-- Switch to alternate commented line below with correct offset. +-- Additional tuning of parameters. +-- Commented out debug hud display code, prefixed with "--debug:". + +-- 2018-11-22 +-- Give visual indication that hangglider is equiped. +-- Display simple overlay with blurred struts when equiped. +-- Issue: don't know how to disable overlay in third person view. +-- Also Unequip hangglider when landing on water. +-- Attempt to linearize parabolic flight path. +-- Start gravity stronger, but gradually reduce it as descent velocity increases. +-- Don't use airstopper when equipped from the ground (descent velocity is low). +-- Slightly increase flight speed to 1.25. +-- Unequip/equip cycling mid-flight should not fly farther than continuous flight. +-- When equipping mid-air (descent velocity higher), use airstopper but increase descent slope afterwards. +-- Create airbreak flag so all equips mid-flight use faster descent. +-- Reset airbreak flag only when land (canExist goes false). +-- Issue: it wouldn't reset if land in water, use fly, and launch from air, before I added test for water, +-- not sure if there are other such cases. +-- Temporarily add hud debug display to show descent velocity, gravity override, and airbreak flag. +-- Still in process of tuning all the parameters. + + +-- Modifications by Piezo_ +-- 2018-11-25 +-- hud overlay and debug can be enabled/disabled +-- Added blender-rendered overlay for struts using the actual model. +-- Reduced airbreak penalty severity +-- gave glider limited durability. +-- Improved gravity adjustment function. +-- Changed airbreaking process +-- Removed airbreak penalty, as any 'advantage' seems minimal after new adjustments +-- Removed airbreak until minetest devs are smart enough to implement better serverside players. +-- Simplified liquid check. + +-- Modifications by gpcf +-- 2018-12-09 +-- get shot down while flying over protected areas marked as no-fly-zones (flak, from German Flugabwehrkanone) +-- set these areas with the /area_flak command + +-- Modifications by SpaghettiToastBook +-- 2018-12-29 +-- Physics overrides use player_monoids mod if available + +local HUD_Overlay = true --show glider struts as overlay on HUD +local debug = false --show debug info in top-center of hud +local moveModelUp = false +if tonumber(string.sub(minetest.get_version().string, 1, 1)) and tonumber(string.sub(minetest.get_version().string, 1, 1)) > 4 then + moveModelUp = true +end +hangglider = {} --Make this global, so other mods can tell if hangglider exists. +hangglider.use = {} +if HUD_Overlay then +hangglider.id = {} -- hud id for displaying overlay with struts +end +hangglider.players = {} +if debug then hangglider.debug = {} end -- hud id for debug data +--hangglider.airbreak = {} -- true if falling fast when equip + +--[[minetest.register_entity("hangglider:airstopper", { --A one-instant entity that catches the player and stops them. + is_visible = false, + physical = false, + immortal = true, + attach = nil, + on_step = function(self, _) + local canExist = false + if self.attach then + local player = self.attach + if player:is_player() then + local pname = player:get_player_name() + canExist = true + if player:get_player_velocity().y < 0.5 and player:get_player_velocity().y > -0.5 then + --Let go when the player actually stops, as that's the whole point. + if hangglider.use[pname] then + if moveModelUp then + minetest.add_entity(player:get_pos(), "hangglider:glider"):set_attach(player, "", {x=0,y=10,z=0}, {x=0,y=0,z=0}) + else + minetest.add_entity(player:get_pos(), "hangglider:glider"):set_attach(player, "", {x=0,y=0,z=0}, {x=0,y=0,z=0}) + end + end + canExist = false + end + end + if not canExist then + player:set_detach() + end + end + if not canExist then + self.object:remove() + end + end +}) + +if core.global_exists("areas") then + hangglider.flak = false + -- chat command definition essentially copied from areas mod. + minetest.register_chatcommand("area_flak",{ + params = "", + description = "Toggle airspace restrictions for area ", + func = function(name, param) + local id = tonumber(param) + if not id then + return false, "Invalid usage, see /help area_flak." + end + + if not areas:isAreaOwner(id, name) then + return false, "Area "..id.." does not exist" + .." or is not owned by you." + end + local open = not areas.areas[id].flak + -- Save false as nil to avoid inflating the DB. + areas.areas[id].flak = open or nil + areas:save() + return true, ("Area's airspace %s."):format(open and "closed" or "opened") + end + }) +end + +if core.global_exists("minetestd") and minetestd.services.physicsctl.enabled then +minetestd.physicsctl.register_physics_effect("hangglider", + function(player) -- check + return hangglider.use[player:get_player_name()] + end, + function(phys, player) -- blend + local vel_y = player:get_player_velocity().y + if debug then player:hud_change(hangglider.debug[pname].id, "text", vel_y..', '..player:get_physics_override().gravity..', '..tostring(hangglider.airbreak[pname])) end + phys.gravity = phys.gravity*((vel_y + 3)/20) + if vel_y < 0 and vel_y > -3 then + phys.speed = (math.abs(vel_y/2) + 0.75) + elseif vel_y <= -3 then --Cap our gliding movement speed. + phys.speed = 2.25 + end + phys.jump = 0 + end, + 7 -- effect order +) +end + +hangglider.shot_sound = function (pos) + minetest.sound_play("hangglider_flak_shot", { + pos = pos, + max_hear_distance = 30, + gain = 10.0, + }) +end +]] +local physics_attrs = {"jump", "speed", "gravity"} +local function apply_physics_override(player, overrides) + if player_monoids then + for _, attr in pairs(physics_attrs) do + if overrides[attr] then + player_monoids[attr]:add_change(player, overrides[attr], "hangglider:glider") + end + end + else + player:set_physics_override(overrides) + end +end + +local function remove_physics_override(player, overrides) + for _, attr in pairs(physics_attrs) do + if overrides[attr] then + if core.global_exists("player_monoids") then + player_monoids[attr]:del_change(player, "hangglider:glider") + else + player:set_physics_override({[attr] = 1}) + end + end + end +end + +local step_v +minetest.register_entity("hangglider:glider", { + visual = "mesh", + visual_size = {x = 12, y = 12}, + collisionbox = {0,0,0,0,0,0}, + mesh = "glider.obj", + immortal = true, + static_save = false, + textures = {"wool.png","default_wood.png"}, + on_step = function(self, dtime) + local canExist = false + if self.object:get_attach() then + local player = self.object:get_attach("parent") + if player then + local pos = player:getpos() + local pname = player:get_player_name() + if hangglider.use[pname] then + local mrn_name = minetest.registered_nodes[minetest.get_node(vector.new(pos.x, pos.y-0.5, pos.z)).name] + if mrn_name then + if not (mrn_name.walkable or mrn_name.liquidtype ~= "none") then + canExist = true + + if not minetestd then + step_v = player:get_player_velocity().y + if step_v < 0 and step_v > -3 then + apply_physics_override(player, {speed=math.abs(step_v/2) + 0.75}) + elseif step_v <= -3 then --Cap our gliding movement speed. + apply_physics_override(player, {speed=2.25}) + else + remove_physics_override(player, {speed=1}) + end + if debug then player:hud_change(hangglider.debug[pname].id, "text", step_v..', '..player:get_physics_override().gravity..', '..tostring(hangglider.airbreak[pname])) end + apply_physics_override(player, {gravity=((step_v + 3)/20)}) + end + --[[local vel = player:get_player_velocity() + if debug then player:hud_change(hangglider.debug[pname].id, "text", vel.y..', '..grav..', '..tostring(hangglider.airbreak[pname])) end + + player:set_physics_override({gravity = (vel.y + 2.0)/20}) + ]]end + end + end + if not canExist then + + if not minetestd then + local player_physics = hangglider.players[pname] + local player_gravity = player_physics.gravity + local player_jump = player_physics.jump + local player_speed = player_physics.speed + if player_gravity < .9 then + player:set_physics_override({gravity=1}) + end + if player_jump < .8 then + player:set_physics_override({jump=1}) + end + if player_speed < .9 or player_speed > 2 then + player:set_physics_override({speed=1}) + end + if player_jump > .7 and player_gravity > .8 then + player:set_physics_override(hangglider.players[pname]) + end + end + hangglider.use[pname] = false + if HUD_Overlay then + player:hud_change(hangglider.id[pname], "text", "blank.png") + end + --hangglider.airbreak[pname] = false + end + end + end + if not canExist then + self.object:set_detach() + self.object:remove() + end + end +}) + +minetest.register_on_dieplayer(function(player) + remove_physics_override(player, { + gravity = 1, + jump = 1, + }) + hangglider.use[player:get_player_name()] = false +end) + + +minetest.register_on_joinplayer(function(player) + local pname = player:get_player_name() + remove_physics_override(player, { + gravity = 1, + jump = 1, + }) + hangglider.use[pname] = false + if HUD_Overlay then + hangglider.id[pname] = player:hud_add({ + hud_elem_type = "image", + text = "blank.png", + position = {x=0, y=0}, + scale = {x=-100, y=-100}, + alignment = {x=1, y=1}, + offset = {x=0, y=0} + }) end + if debug then + hangglider.debug[pname] = {id = player:hud_add({hud_elem_type = "text", + position = {x=0.5, y=0.1}, + text = "-", + number = 0xFF0000}), -- red text + -- ht = {50,50,50}, + } + end + --hangglider.airbreak[pname] = false +end) + +minetest.register_on_leaveplayer(function(player) + local pname = player:get_player_name() + hangglider.use[pname] = nil + if HUD_Overlay then hangglider.id[pname] = nil end + if debug then hangglider.debug[pname] = nil end + --hangglider.airbreak[pname] = nil +end) + +minetest.register_tool("hangglider:hangglider", { + description = "Glider", + inventory_image = "glider_item.png", + stack_max=1, + on_use = function(itemstack, player, pointed_thing) + if not player then + return + end + local pos = player:get_pos() + local pname = player:get_player_name() + hangglider.players[pname] = player:get_physics_override() + if not hangglider.use[pname] then --Equip + minetest.sound_play("bedsheet", {pos=pos, max_hear_distance = 8, gain = 1.0}) + if HUD_Overlay then player:hud_change(hangglider.id[pname], "text", "glider_struts.png") end + local airbreak = false + local vel = player:get_player_velocity().y + --[[if vel < -1.5 then -- engage mid-air, falling fast, so stop but ramp velocity more quickly + --hangglider.airbreak[pname] = true + airbreak = true + local stopper = minetest.add_entity(pos, "hangglider:airstopper") + minetest.after(0, function(stopper, player) --"Extreme Measures" + stopper:set_pos(player:get_pos()) + stopper:get_luaentity().attach = player + player:set_attach( stopper, "", {x=0,y=0,z=0}, {x=0,y=0,z=0}) + end, stopper, player) + end]] + if not airbreak then + if moveModelUp then + minetest.add_entity(pos, "hangglider:glider"):set_attach(player, "", {x=0,y=10,z=0}, {x=0,y=0,z=0}) + else + minetest.add_entity(pos, "hangglider:glider"):set_attach(player, "", {x=0,y=0,z=0}, {x=0,y=0,z=0}) + end + end + hangglider.use[pname] = true + apply_physics_override(player, {jump = 0}) + -- if minetest 0.4.x use this: + + -- if minetest 5.x use this: + -- minetest.add_entity(player:get_pos(), "hangglider:glider"):set_attach(player, "", {x=0,y=10,z=0}, {x=0,y=0,z=0}) + itemstack:set_wear(itemstack:get_wear() + 255) + return itemstack + elseif hangglider.use[pname] then --Unequip + if HUD_Overlay then player:hud_change(hangglider.id[pname], "text", "default_wood.png^[colorize:#0000:255") end + hangglider.use[pname] = false + end + end, + sound = {breaks = "default_tool_breaks"}, +}) diff --git a/mods/hangglider/license.txt b/mods/hangglider/license.txt new file mode 100755 index 0000000..407255a --- /dev/null +++ b/mods/hangglider/license.txt @@ -0,0 +1,53 @@ +License for the Hangglider mod +------------------------------ +Copyright (C) 2018 Piezo_ +Copyright (C) 2018 kestral246 +Copyright (C) 2016 cd2 (cdqwertz) + +This mod is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This mod is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this mod. If not, see . + + +--- +License for the original paraglider mod by cdqwertz +(available as part of "rpgtest", found at https://forum.minetest.net/viewtopic.php?t=13761) +------------------------------------------------------------------------------------------ + +This program 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 program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +http://www.gnu.org/licenses/lgpl-2.1.html + + +--- +License for Media +----------------- + +Textures: + glider_inventory.png: CC-BY-SA 3.0 UNPORTED. Created by cd2 (cdqwertz) + glider_struts.png: CC-BY-SA 3.0, Piezo_. + Default wood and wool textures from minetest-game. + +Models and sounds: + CC BY-SA (4.0) by Piezo_. + hangglider_flak_shot: tnt_explode sound from minetest_game (CC BY-SA 3.0) diff --git a/mods/hangglider/mod.conf b/mods/hangglider/mod.conf new file mode 100644 index 0000000..a6d5a68 --- /dev/null +++ b/mods/hangglider/mod.conf @@ -0,0 +1 @@ +name = hangglider diff --git a/mods/hangglider/models/glider.obj b/mods/hangglider/models/glider.obj new file mode 100755 index 0000000..5234e00 --- /dev/null +++ b/mods/hangglider/models/glider.obj @@ -0,0 +1,153 @@ +# Blender v2.79 (sub 0) OBJ File: 'glider.blend' +# www.blender.org +o wood_Plane.001 +v 0.572761 0.605751 0.566543 +v 0.572761 0.605751 -0.566543 +v 0.572761 0.745661 0.566543 +v 1.132401 0.395886 -0.566543 +v 0.572761 0.745661 -0.566543 +v 1.132401 0.395886 0.566543 +v 0.000000 0.605751 0.566543 +v -0.572761 0.605751 0.566543 +v 0.000000 0.605751 -0.566543 +v -0.572761 0.605751 -0.566543 +v -0.572761 0.745661 0.566543 +v -1.132401 0.395886 -0.566543 +v -0.572761 0.745661 -0.566543 +v -1.132401 0.395886 0.566543 +v 0.000000 0.745661 -0.566543 +v 0.000000 0.745661 0.566543 +vt 0.482051 -0.081189 +vt 0.482051 1.089032 +vt 0.961113 1.089032 +vt 0.961113 -0.081189 +vt 1.461031 1.089032 +vt 1.461031 -0.081189 +vt 1.565178 -0.071488 +vt 1.013186 -0.071488 +vt 1.013186 1.098732 +vt 1.565178 1.098732 +vt 0.534125 -0.071488 +vt 0.534125 1.098732 +vt -0.343283 0.514972 +vt 0.063942 0.769487 +vt 0.063942 0.667681 +vt -0.343283 0.514179 +vt 0.063941 0.361470 +vt 0.063941 0.259664 +vt 0.480711 0.361470 +vt 0.480711 0.259664 +vt 0.480713 0.667681 +vt 0.480713 0.769487 +vt 0.002990 -0.081188 +vt 0.002990 1.089032 +vt -0.496929 -0.081188 +vt -0.496929 1.089032 +vt -0.496929 -0.071488 +vt -0.496929 1.098732 +vt 0.055063 1.098732 +vt 0.055063 -0.071488 +vt 1.304706 0.514972 +vt 0.897483 0.667681 +vt 0.897483 0.769487 +vt 1.304706 0.514179 +vt 0.897482 0.259664 +vt 0.897482 0.361470 +vn 0.0000 -1.0000 0.0000 +vn -0.3511 -0.9363 0.0000 +vn 0.5300 0.8480 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 0.0000 -1.0000 +vn 0.3511 -0.9363 0.0000 +vn -0.5300 0.8480 0.0000 +g wood_Plane.001_0001 +s off +f 7/1/1 9/2/1 2/3/1 1/4/1 +f 2/3/2 4/5/2 6/6/2 1/4/2 +f 4/7/3 5/8/3 3/9/3 6/10/3 +f 3/9/4 5/8/4 15/11/4 16/12/4 +f 6/13/5 3/14/5 1/15/5 +f 4/16/6 2/17/6 5/18/6 +f 9/19/6 15/20/6 5/18/6 2/17/6 +f 7/21/5 1/15/5 3/14/5 16/22/5 +f 7/1/1 8/23/1 10/24/1 9/2/1 +f 10/24/7 8/23/7 14/25/7 12/26/7 +f 12/27/8 14/28/8 11/29/8 13/30/8 +f 11/29/4 16/12/4 15/11/4 13/30/4 +f 14/31/5 8/32/5 11/33/5 +f 12/34/6 13/35/6 10/36/6 +f 9/19/6 10/36/6 13/35/6 15/20/6 +f 7/21/5 16/22/5 11/33/5 8/32/5 +o stick_Plane +v 0.345489 -0.242835 0.171751 +v 0.276391 -0.171751 0.171751 +v 0.345489 -0.242835 0.242835 +v 0.276391 -0.171751 0.242835 +v 0.725527 0.552782 0.242836 +v 0.829174 0.552782 0.242836 +v 0.725527 0.552782 0.171751 +v 0.829174 0.552782 0.171751 +v 0.000000 -0.171751 0.242835 +v 0.000000 -0.242835 0.242835 +v 0.000000 -0.171751 0.171751 +v 0.000000 -0.242835 0.171751 +v -0.345489 -0.242835 0.171751 +v -0.276391 -0.171751 0.171751 +v -0.345489 -0.242835 0.242835 +v -0.276391 -0.171751 0.242835 +v -0.725527 0.552782 0.242836 +v -0.829174 0.552782 0.242836 +v -0.725527 0.552782 0.171751 +v -0.829174 0.552782 0.171751 +vt 0.500002 0.375000 +vt 0.500000 0.250000 +vt 0.750000 0.250000 +vt 0.875000 0.375000 +vt 0.500000 0.500000 +vt 0.875000 0.500000 +vt 0.500000 0.125000 +vt 0.500000 0.000000 +vt 0.875000 0.000000 +vt 0.750000 0.125000 +vt 1.600000 0.000000 +vt 1.500000 0.125000 +vt 1.500000 0.250000 +vt 1.600000 0.375000 +vt 1.600000 0.500000 +vt 0.125000 0.375000 +vt 0.250000 0.250000 +vt 0.125000 0.500000 +vt 0.250000 0.125000 +vt 0.125000 0.000000 +vt -0.500000 0.125000 +vt -0.600000 0.000000 +vt -0.500000 0.250000 +vt -0.600000 0.375000 +vt -0.600000 0.500000 +vn 0.0000 0.0000 -1.0000 +vn 0.0000 -1.0000 -0.0000 +vn 0.0000 -0.0000 1.0000 +vn 0.0000 1.0000 0.0000 +vn -0.8499 0.5269 0.0000 +vn 0.8545 -0.5195 -0.0000 +vn 0.8499 0.5269 0.0000 +vn -0.8545 -0.5195 -0.0000 +g stick_Plane_0002 +s off +f 28/37/9 27/38/9 18/39/9 17/40/9 +f 26/41/10 28/37/10 17/40/10 19/42/10 +f 25/43/11 26/44/11 19/45/11 20/46/11 +f 27/38/12 25/43/12 20/46/12 18/39/12 +f 20/46/11 19/45/11 22/47/11 21/48/11 +f 18/39/13 20/46/13 21/48/13 23/49/13 +f 17/40/9 18/39/9 23/49/9 24/50/9 +f 19/42/14 17/40/14 24/50/14 22/51/14 +f 28/37/9 29/52/9 30/53/9 27/38/9 +f 26/41/10 31/54/10 29/52/10 28/37/10 +f 25/43/11 32/55/11 31/56/11 26/44/11 +f 27/38/12 30/53/12 32/55/12 25/43/12 +f 32/55/11 33/57/11 34/58/11 31/56/11 +f 30/53/15 35/59/15 33/57/15 32/55/15 +f 29/52/9 36/60/9 35/59/9 30/53/9 +f 31/54/16 34/61/16 36/60/16 29/52/16 diff --git a/mods/hangglider/sounds/bedsheet.ogg b/mods/hangglider/sounds/bedsheet.ogg new file mode 100755 index 0000000..b664830 Binary files /dev/null and b/mods/hangglider/sounds/bedsheet.ogg differ diff --git a/mods/hangglider/sounds/hangglider_flak_shot.ogg b/mods/hangglider/sounds/hangglider_flak_shot.ogg new file mode 100644 index 0000000..a414ea0 Binary files /dev/null and b/mods/hangglider/sounds/hangglider_flak_shot.ogg differ diff --git a/mods/hangglider/textures/glider_item.png b/mods/hangglider/textures/glider_item.png new file mode 100755 index 0000000..2287a54 Binary files /dev/null and b/mods/hangglider/textures/glider_item.png differ diff --git a/mods/hangglider/textures/glider_struts.png b/mods/hangglider/textures/glider_struts.png new file mode 100644 index 0000000..da71a8a Binary files /dev/null and b/mods/hangglider/textures/glider_struts.png differ diff --git a/mods/hbhunger/README.md b/mods/hbhunger/README.md new file mode 100644 index 0000000..759b794 --- /dev/null +++ b/mods/hbhunger/README.md @@ -0,0 +1,97 @@ +# Hunger with HUD bar [`hbhunger`] + +* Version: 1.0.1 + +## Using the mod + +This mod adds a mechanic for hunger. +This mod depends on the HUD bars mod [`hudbars`], version 1.4.1 or any later version +starting with “1.†or “2.â€. + +## About hunger +This mod adds a hunger mechanic to the game. Players get a new attribute called “satiationâ€: + +* A new player starts with 20 satiation points out of 30 +* Actions like digging, placing and walking cause exhaustion, which lower the satiation +* Every 800 seconds you lose 1 satiation point without doing anything +* At 1 or 0 satiation you will suffer damage and die in case you don't eat something +* If your satiation is 16 or higher, you will slowly regenerate health points +* Eating food will increase your satiation (Duh!) + +Important: Eating food will not directly increase your health anymore, as long as the food +item is supported by this mod (see below). + +Careful! Some foods may be poisoned. If you eat a poisoned item, you may still get a satiation +boost, but for a brief period you lose health points because of food poisoning. However, +food poisoning can never kill you. + +## Statbar mode +If you use the statbar mode of the HUD Bars mod, these things are important to know: +As with all mods using HUD Bars, the bread statbar symbols represent the rough percentage +out of 30 satiation points, in steps of 5%, so the symbols give you an estimate of your +satiation. This is different from the hunger mod by BlockMen. + +You gain health at 5.5 symbols or more, as 5.5 symbols correspond to 16 satiation points. +You *may* lose health at exactly 0.5 symbols, as 0.5 symbols correspond to 1-2 satiation points. + +## Supported food +All mods which add food through standard measures (`minetest.item_eat`) are already +supported automatically. Poisoned food needs special support. + +### Known supported food mods +* Apple from Minetest Game [`default`] +* Red and brown mushroom from Minetest Game [`flowers`] +* Bread from Minetest Game [`farming`] +* [`animalmaterials`] (Mob Framework (`mobf` modpack)) +* Bushes [`bushes`] +* [`bushes_classic`] +* Creatures [`creatures`] +* [`dwarves`] (beer and such) +* Docfarming [`docfarming`] +* Ethereal / Ethereal NG [`ethereal`] +* Farming Redo [`farming`] by TenPlus1 +* Farming plus [`farming_plus`] +* Ferns [`ferns`] +* Fishing [`fishing`] +* [`fruit`] +* Glooptest [`glooptest`] +* JKMod ([`jkanimals`], [`jkfarming`], [`jkwine`]) +* [`kpgmobs`] +* [`mobfcooking`] +* [`mooretrees`] +* [`mtfoods`] +* [`mushroom`] +* [`mush45`] +* Seaplants [`sea`] +* Simple mobs [`mobs`] +* Pizza [`pizza`] +* Not So Simple Mobs [`nssm`] + +### Supported mods without optional dependency (mods provide their own support) + +* Food ([`food`], [`food_basic`]) +* Sweet Foods [`food_sweet`] + +### Examples + +* Eating an apple (from Minetest Game) increases your satiation by 2; +* eating a bread (from Minetest Game) increases your satiation by 4. + +## Licensing +This mod is free software. + +### Source code + +* License: [LGPL v2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html) +* Author: by Wuzzy (2015-2016) +* Forked from the “Better HUD (and hunger)†mod by BlockMen (2013-2015), + most code comes from this mod. + +### Textures + +* `hbhunger_icon.png`—PilzAdam ([MIT License](https://opensource.org/licenses/MIT)), modified by BlockMen +* `hbhunger_bgicon.png`—PilzAdam (MIT License), modified by BlockMen +* `hbhunger_bar.png—Wuzzy` (MIT License) +* `hbhunger_icon_health_poison.png`—celeron55 ([CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)), modified by BlockMen, modified again by Wuzzy +* Everything else: MIT License, by BlockMen and Wuzzy + diff --git a/mods/hbhunger/hunger.lua b/mods/hbhunger/hunger.lua new file mode 100644 index 0000000..05f3564 --- /dev/null +++ b/mods/hbhunger/hunger.lua @@ -0,0 +1,487 @@ +-- Keep these for backwards compatibility +function hbhunger.save_hunger(player) + hbhunger.set_hunger_raw(player) +end +function hbhunger.load_hunger(player) + hbhunger.get_hunger_raw(player) +end + +-- wrapper for minetest.item_eat (this way we make sure other mods can't break this one) +local org_eat = core.do_item_eat +core.do_item_eat = function(hp_change, replace_with_item, itemstack, user, pointed_thing) + local old_itemstack = itemstack + itemstack = hbhunger.eat(hp_change, replace_with_item, itemstack, user, pointed_thing) + for _, callback in pairs(core.registered_on_item_eats) do + local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing, old_itemstack) + if result then + return result + end + end + return itemstack +end + +-- food functions +local food = hbhunger.food + +function hbhunger.register_food(name, hunger_change, replace_with_item, poisen, heal, sound) + food[name] = {} + food[name].saturation = hunger_change -- hunger points added + food[name].replace = replace_with_item -- what item is given back after eating + food[name].poisen = poisen -- time its poisening + food[name].healing = heal -- amount of HP + food[name].sound = sound -- special sound that is played when eating +end + +function hbhunger.eat(hp_change, replace_with_item, itemstack, user, pointed_thing) + local item = itemstack:get_name() + local def = food[item] + if not def then + def = {} + if type(hp_change) ~= "number" then + hp_change = 1 + core.log("error", "Wrong on_use() definition for item '" .. item .. "'") + end + def.saturation = hp_change * 1.3 + def.replace = replace_with_item + end + local func = hbhunger.item_eat(def.saturation, def.replace, def.poisen, def.healing, def.sound) + return func(itemstack, user, pointed_thing) +end + +-- Poison player +local function poisenp(tick, time, time_left, player) + -- First check if player is still there + if not player:is_player() then + return + end + time_left = time_left + tick + if time_left < time then + minetest.after(tick, poisenp, tick, time, time_left, player) + else + hbhunger.poisonings[player:get_player_name()] = hbhunger.poisonings[player:get_player_name()] - 1 + if hbhunger.poisonings[player:get_player_name()] <= 0 then + -- Reset HUD bar color + hb.change_hudbar(player, "health", nil, nil, "hudbars_icon_health.png", nil, "hudbars_bar_health.png") + end + end + if player:get_hp()-1 > 0 then + player:set_hp(player:get_hp()-1) + end + +end + +function hbhunger.item_eat(hunger_change, replace_with_item, poisen, heal, sound) + return function(itemstack, user, pointed_thing) + if itemstack:take_item() ~= nil and user ~= nil then + local name = user:get_player_name() + local h = tonumber(hbhunger.hunger[name]) + local hp = user:get_hp() + if h == nil or hp == nil then + return + end + minetest.sound_play( + {name = sound or "hbhunger_eat_generic", + gain = 1}, + {object=user, + max_hear_distance = 16, + pitch = 1 + math.random(-10, 10)*0.005,} + ) + + -- Saturation + if h < 30 and hunger_change then + h = h + hunger_change + if h > 30 then h = 30 end + hbhunger.hunger[name] = h + hbhunger.set_hunger_raw(user) + end + -- Healing + if hp < 20 and heal then + hp = hp + heal + if hp > 20 then hp = 20 end + user:set_hp(hp) + end + -- Poison + if poisen then + -- Set poison bar + hb.change_hudbar(user, "health", nil, nil, "hbhunger_icon_health_poison.png", nil, "hbhunger_bar_health_poison.png") + hbhunger.poisonings[name] = hbhunger.poisonings[name] + 1 + poisenp(1, poisen, 0, user) + end + + if itemstack:get_count() == 0 then + itemstack:add_item(replace_with_item) + else + local inv = user:get_inventory() + if inv:room_for_item("main", replace_with_item) then + inv:add_item("main", replace_with_item) + else + minetest.add_item(user:getpos(), replace_with_item) + end + end + end + return itemstack + end +end + +if minetest.get_modpath("default") ~= nil then + hbhunger.register_food("default:apple", 2) +end +if minetest.get_modpath("flowers") ~= nil then + hbhunger.register_food("flowers:mushroom_brown", 1) + hbhunger.register_food("flowers:mushroom_red", 1, "", 3) +end +if minetest.get_modpath("farming") ~= nil then + hbhunger.register_food("farming:bread", 4) +end + +if minetest.get_modpath("mobs") ~= nil then + if mobs.mod ~= nil and mobs.mod == "redo" then + hbhunger.register_food("mobs:cheese", 4) + hbhunger.register_food("mobs:meat", 8) + hbhunger.register_food("mobs:meat_raw", 4) + hbhunger.register_food("mobs:rat_cooked", 4) + hbhunger.register_food("mobs:honey", 2) + hbhunger.register_food("mobs:pork_raw", 3, "", 3) + hbhunger.register_food("mobs:pork_cooked", 8) + hbhunger.register_food("mobs:chicken_cooked", 6) + hbhunger.register_food("mobs:chicken_raw", 2, "", 3) + hbhunger.register_food("mobs:chicken_egg_fried", 2) + if minetest.get_modpath("bucket") then + hbhunger.register_food("mobs:bucket_milk", 3, "bucket:bucket_empty") + end + else + hbhunger.register_food("mobs:meat", 6) + hbhunger.register_food("mobs:meat_raw", 3) + hbhunger.register_food("mobs:rat_cooked", 5) + end +end + +if minetest.get_modpath("moretrees") ~= nil then + hbhunger.register_food("moretrees:coconut_milk", 1) + hbhunger.register_food("moretrees:raw_coconut", 2) + hbhunger.register_food("moretrees:acorn_muffin", 3) + hbhunger.register_food("moretrees:spruce_nuts", 1) + hbhunger.register_food("moretrees:pine_nuts", 1) + hbhunger.register_food("moretrees:fir_nuts", 1) +end + +if minetest.get_modpath("dwarves") ~= nil then + hbhunger.register_food("dwarves:beer", 2) + hbhunger.register_food("dwarves:apple_cider", 1) + hbhunger.register_food("dwarves:midus", 2) + hbhunger.register_food("dwarves:tequila", 2) + hbhunger.register_food("dwarves:tequila_with_lime", 2) + hbhunger.register_food("dwarves:sake", 2) +end + +if minetest.get_modpath("animalmaterials") ~= nil then + hbhunger.register_food("animalmaterials:milk", 2) + hbhunger.register_food("animalmaterials:meat_raw", 3) + hbhunger.register_food("animalmaterials:meat_pork", 3) + hbhunger.register_food("animalmaterials:meat_beef", 3) + hbhunger.register_food("animalmaterials:meat_chicken", 3) + hbhunger.register_food("animalmaterials:meat_lamb", 3) + hbhunger.register_food("animalmaterials:meat_venison", 3) + hbhunger.register_food("animalmaterials:meat_undead", 3, "", 3) + hbhunger.register_food("animalmaterials:meat_toxic", 3, "", 5) + hbhunger.register_food("animalmaterials:meat_ostrich", 3) + hbhunger.register_food("animalmaterials:fish_bluewhite", 2) + hbhunger.register_food("animalmaterials:fish_clownfish", 2) +end + +if minetest.get_modpath("fishing") ~= nil then + hbhunger.register_food("fishing:fish_raw", 2) + hbhunger.register_food("fishing:fish_cooked", 5) + hbhunger.register_food("fishing:sushi", 6) + hbhunger.register_food("fishing:shark", 4) + hbhunger.register_food("fishing:shark_cooked", 8) + hbhunger.register_food("fishing:pike", 4) + hbhunger.register_food("fishing:pike_cooked", 8) +end + +if minetest.get_modpath("glooptest") ~= nil then + hbhunger.register_food("glooptest:kalite_lump", 1) +end + +if minetest.get_modpath("bushes") ~= nil then + hbhunger.register_food("bushes:sugar", 1) + hbhunger.register_food("bushes:strawberry", 2) + hbhunger.register_food("bushes:berry_pie_raw", 3) + hbhunger.register_food("bushes:berry_pie_cooked", 4) + hbhunger.register_food("bushes:basket_pies", 15) +end + +if minetest.get_modpath("bushes_classic") then + -- bushes_classic mod, as found in the plantlife modpack + local berries = { + "strawberry", + "blackberry", + "blueberry", + "raspberry", + "gooseberry", + "mixed_berry"} + for _, berry in ipairs(berries) do + if berry ~= "mixed_berry" then + hbhunger.register_food("bushes:"..berry, 1) + end + hbhunger.register_food("bushes:"..berry.."_pie_raw", 2) + hbhunger.register_food("bushes:"..berry.."_pie_cooked", 5) + hbhunger.register_food("bushes:basket_"..berry, 15) + end +end + +if minetest.get_modpath("mushroom") ~= nil then + hbhunger.register_food("mushroom:brown", 1) + hbhunger.register_food("mushroom:red", 1, "", 3) + -- mushroom potions: red = strong poison, brown = light restorative + if minetest.get_modpath("vessels") then + hbhunger.register_food("mushroom:brown_essence", 1, "vessels:glass_bottle", nil, 4) + hbhunger.register_food("mushroom:poison", 1, "vessels:glass_bottle", 10) + end +end + +if minetest.get_modpath("docfarming") ~= nil then + hbhunger.register_food("docfarming:carrot", 3) + hbhunger.register_food("docfarming:cucumber", 2) + hbhunger.register_food("docfarming:corn", 3) + hbhunger.register_food("docfarming:potato", 4) + hbhunger.register_food("docfarming:bakedpotato", 5) + hbhunger.register_food("docfarming:raspberry", 3) +end + +if minetest.get_modpath("farming_plus") ~= nil then + hbhunger.register_food("farming_plus:carrot_item", 3) + hbhunger.register_food("farming_plus:banana", 2) + hbhunger.register_food("farming_plus:orange_item", 2) + hbhunger.register_food("farming:pumpkin_bread", 4) + hbhunger.register_food("farming_plus:strawberry_item", 2) + hbhunger.register_food("farming_plus:tomato_item", 2) + hbhunger.register_food("farming_plus:potato_item", 4) + hbhunger.register_food("farming_plus:rhubarb_item", 2) +end + +if minetest.get_modpath("mtfoods") ~= nil then + hbhunger.register_food("mtfoods:dandelion_milk", 1) + hbhunger.register_food("mtfoods:sugar", 1) + hbhunger.register_food("mtfoods:short_bread", 4) + hbhunger.register_food("mtfoods:cream", 1) + hbhunger.register_food("mtfoods:chocolate", 2) + hbhunger.register_food("mtfoods:cupcake", 2) + hbhunger.register_food("mtfoods:strawberry_shortcake", 2) + hbhunger.register_food("mtfoods:cake", 3) + hbhunger.register_food("mtfoods:chocolate_cake", 3) + hbhunger.register_food("mtfoods:carrot_cake", 3) + hbhunger.register_food("mtfoods:pie_crust", 3) + hbhunger.register_food("mtfoods:apple_pie", 3) + hbhunger.register_food("mtfoods:rhubarb_pie", 2) + hbhunger.register_food("mtfoods:banana_pie", 3) + hbhunger.register_food("mtfoods:pumpkin_pie", 3) + hbhunger.register_food("mtfoods:cookies", 2) + hbhunger.register_food("mtfoods:mlt_burger", 5) + hbhunger.register_food("mtfoods:potato_slices", 2) + hbhunger.register_food("mtfoods:potato_chips", 3) + --mtfoods:medicine + hbhunger.register_food("mtfoods:casserole", 3) + hbhunger.register_food("mtfoods:glass_flute", 2) + hbhunger.register_food("mtfoods:orange_juice", 2) + hbhunger.register_food("mtfoods:apple_juice", 2) + hbhunger.register_food("mtfoods:apple_cider", 2) + hbhunger.register_food("mtfoods:cider_rack", 2) +end + +if minetest.get_modpath("fruit") ~= nil then + hbhunger.register_food("fruit:apple", 2) + hbhunger.register_food("fruit:pear", 2) + hbhunger.register_food("fruit:bananna", 3) + hbhunger.register_food("fruit:orange", 2) +end + +if minetest.get_modpath("mush45") ~= nil then + hbhunger.register_food("mush45:meal", 4) +end + +if minetest.get_modpath("seaplants") ~= nil then + hbhunger.register_food("seaplants:kelpgreen", 1) + hbhunger.register_food("seaplants:kelpbrown", 1) + hbhunger.register_food("seaplants:seagrassgreen", 1) + hbhunger.register_food("seaplants:seagrassred", 1) + hbhunger.register_food("seaplants:seasaladmix", 6) + hbhunger.register_food("seaplants:kelpgreensalad", 1) + hbhunger.register_food("seaplants:kelpbrownsalad", 1) + hbhunger.register_food("seaplants:seagrassgreensalad", 1) + hbhunger.register_food("seaplants:seagrassgreensalad", 1) +end + +if minetest.get_modpath("mobfcooking") ~= nil then + hbhunger.register_food("mobfcooking:cooked_pork", 6) + hbhunger.register_food("mobfcooking:cooked_ostrich", 6) + hbhunger.register_food("mobfcooking:cooked_beef", 6) + hbhunger.register_food("mobfcooking:cooked_chicken", 6) + hbhunger.register_food("mobfcooking:cooked_lamb", 6) + hbhunger.register_food("mobfcooking:cooked_venison", 6) + hbhunger.register_food("mobfcooking:cooked_fish", 6) +end + +if minetest.get_modpath("creatures") ~= nil then + hbhunger.register_food("creatures:meat", 6) + hbhunger.register_food("creatures:flesh", 3) + hbhunger.register_food("creatures:rotten_flesh", 3, "", 3) +end + +if minetest.get_modpath("ethereal") then + hbhunger.register_food("ethereal:strawberry", 1) + hbhunger.register_food("ethereal:banana", 4) + hbhunger.register_food("ethereal:pine_nuts", 1) + hbhunger.register_food("ethereal:bamboo_sprout", 0, "", 3) + hbhunger.register_food("ethereal:fern_tubers", 1) + hbhunger.register_food("ethereal:banana_bread", 7) + hbhunger.register_food("ethereal:mushroom_plant", 2) + hbhunger.register_food("ethereal:coconut_slice", 2) + hbhunger.register_food("ethereal:golden_apple", 4, "", nil, 10) + hbhunger.register_food("ethereal:wild_onion_plant", 2) + hbhunger.register_food("ethereal:mushroom_soup", 4, "ethereal:bowl") + hbhunger.register_food("ethereal:mushroom_soup_cooked", 6, "ethereal:bowl") + hbhunger.register_food("ethereal:hearty_stew", 6, "ethereal:bowl", 3) + hbhunger.register_food("ethereal:hearty_stew_cooked", 10, "ethereal:bowl") + if minetest.get_modpath("bucket") then + hbhunger.register_food("ethereal:bucket_cactus", 2, "bucket:bucket_empty") + end + hbhunger.register_food("ethereal:fish_raw", 2) + hbhunger.register_food("ethereal:fish_cooked", 5) + hbhunger.register_food("ethereal:seaweed", 1) + hbhunger.register_food("ethereal:yellowleaves", 1, "", nil, 1) + hbhunger.register_food("ethereal:sashimi", 4) + hbhunger.register_food("ethereal:orange", 2) +end + +if minetest.get_modpath("farming") and farming.mod == "redo" then + hbhunger.register_food("farming:bread", 6) + hbhunger.register_food("farming:potato", 1) + hbhunger.register_food("farming:baked_potato", 6) + hbhunger.register_food("farming:cucumber", 4) + hbhunger.register_food("farming:tomato", 4) + hbhunger.register_food("farming:carrot", 3) + hbhunger.register_food("farming:carrot_gold", 6, "", nil, 8) + hbhunger.register_food("farming:corn", 3) + hbhunger.register_food("farming:corn_cob", 5) + hbhunger.register_food("farming:melon_slice", 2) + hbhunger.register_food("farming:pumpkin_slice", 1) + hbhunger.register_food("farming:pumpkin_bread", 9) + hbhunger.register_food("farming:coffee_cup", 2, "farming:drinking_cup") + hbhunger.register_food("farming:coffee_cup_hot", 3, "farming:drinking_cup", nil, 2) + hbhunger.register_food("farming:cookie", 2) + hbhunger.register_food("farming:chocolate_dark", 3) + hbhunger.register_food("farming:donut", 4) + hbhunger.register_food("farming:donut_chocolate", 6) + hbhunger.register_food("farming:donut_apple", 6) + hbhunger.register_food("farming:raspberries", 1) + hbhunger.register_food("farming:blueberries", 1) + hbhunger.register_food("farming:muffin_blueberry", 4) + if minetest.get_modpath("vessels") then + hbhunger.register_food("farming:smoothie_raspberry", 2, "vessels:drinking_glass") + end + hbhunger.register_food("farming:rhubarb", 1) + hbhunger.register_food("farming:rhubarb_pie", 6) + hbhunger.register_food("farming:beans", 1) +end + +if minetest.get_modpath("kpgmobs") ~= nil then + hbhunger.register_food("kpgmobs:uley", 3) + hbhunger.register_food("kpgmobs:meat", 6) + hbhunger.register_food("kpgmobs:rat_cooked", 5) + hbhunger.register_food("kpgmobs:med_cooked", 4) + if minetest.get_modpath("bucket") then + hbhunger.register_food("kpgmobs:bucket_milk", 4, "bucket:bucket_empty") + end +end + +if minetest.get_modpath("jkfarming") ~= nil then + hbhunger.register_food("jkfarming:carrot", 3) + hbhunger.register_food("jkfarming:corn", 3) + hbhunger.register_food("jkfarming:melon_part", 2) + hbhunger.register_food("jkfarming:cake", 3) +end + +if minetest.get_modpath("jkanimals") ~= nil then + hbhunger.register_food("jkanimals:meat", 6) +end + +if minetest.get_modpath("jkwine") ~= nil then + hbhunger.register_food("jkwine:grapes", 2) + hbhunger.register_food("jkwine:winebottle", 1) +end + +if minetest.get_modpath("cooking") ~= nil then + hbhunger.register_food("cooking:meat_beef_cooked", 4) + hbhunger.register_food("cooking:fish_bluewhite_cooked", 3) + hbhunger.register_food("cooking:fish_clownfish_cooked", 1) + hbhunger.register_food("cooking:meat_chicken_cooked", 2) + hbhunger.register_food("cooking:meat_cooked", 2) + hbhunger.register_food("cooking:meat_pork_cooked", 3) + hbhunger.register_food("cooking:meat_toxic_cooked", -3) + hbhunger.register_food("cooking:meat_venison_cooked", 3) + hbhunger.register_food("cooking:meat_undead_cooked", 1) +end + +-- ferns mod of plantlife_modpack +if minetest.get_modpath("ferns") ~= nil then + hbhunger.register_food("ferns:fiddlehead", 1, "", 1) + hbhunger.register_food("ferns:fiddlehead_roasted", 3) + hbhunger.register_food("ferns:ferntuber_roasted", 3) + hbhunger.register_food("ferns:horsetail_01", 1) +end + +if minetest.get_modpath("pizza") ~= nil then + hbhunger.register_food("pizza:pizza", 30, "", nil, 30) + hbhunger.register_food("pizza:pizzaslice", 5, "", nil, 5) +end + +if minetest.get_modpath("nssm") then + hbhunger.register_food("nssm:werewolf_leg", 3) + hbhunger.register_food("nssm:heron_leg", 2) + hbhunger.register_food("nssm:chichibios_heron_leg", 4) + hbhunger.register_food("nssm:crocodile_tail", 3) + hbhunger.register_food("nssm:duck_legs", 1) + hbhunger.register_food("nssm:ant_leg", 1) + hbhunger.register_food("nssm:spider_leg", 1) + hbhunger.register_food("nssm:tentacle", 2) + hbhunger.register_food("nssm:worm_flesh", 2, "", 2) -- poisonous + hbhunger.register_food("nssm:amphibian_heart", 1) + hbhunger.register_food("nssm:raw_scrausics_wing", 1) + -- superfoods + hbhunger.register_food("nssm:phoenix_nuggets", 20, "", nil, 20) + hbhunger.register_food("nssm:phoenix_tear", 20, "", nil, 20) +end + +-- player-action based hunger changes +function hbhunger.handle_node_actions(pos, oldnode, player, ext) + -- is_fake_player comes from the pipeworks, we are not interested in those + if not player or not player:is_player() or player.is_fake_player == true then + return + end + local name = player:get_player_name() + local exhaus = hbhunger.exhaustion[name] + if exhaus == nil then return end + local new = hbhunger.EXHAUST_PLACE + -- placenode event + if not ext then + new = hbhunger.EXHAUST_DIG + end + -- assume its send by main timer when movement detected + if not pos and not oldnode then + new = hbhunger.EXHAUST_MOVE + end + exhaus = exhaus + new + if exhaus > hbhunger.EXHAUST_LVL then + exhaus = 0 + local h = tonumber(hbhunger.hunger[name]) + h = h - 1 + if h < 0 then h = 0 end + hbhunger.hunger[name] = h + hbhunger.set_hunger_raw(player) + end + hbhunger.exhaustion[name] = exhaus +end + +minetest.register_on_placenode(hbhunger.handle_node_actions) +minetest.register_on_dignode(hbhunger.handle_node_actions) diff --git a/mods/hbhunger/init.lua b/mods/hbhunger/init.lua new file mode 100644 index 0000000..ee5019f --- /dev/null +++ b/mods/hbhunger/init.lua @@ -0,0 +1,150 @@ +local S = minetest.get_translator("hbhunger") + +if minetest.settings:get_bool("enable_damage") then + +hbhunger = {} +hbhunger.food = {} + +-- HUD statbar values +hbhunger.hunger = {} +hbhunger.hunger_out = {} + +-- Count number of poisonings a player has at once +hbhunger.poisonings = {} + +-- HUD item ids +local hunger_hud = {} + +hbhunger.HUD_TICK = 0.1 + +--Some hunger settings +hbhunger.exhaustion = {} -- Exhaustion is experimental! + +hbhunger.HUNGER_TICK = 800 -- time in seconds after that 1 hunger point is taken +hbhunger.EXHAUST_DIG = 3 -- exhaustion increased this value after digged node +hbhunger.EXHAUST_PLACE = 1 -- exhaustion increased this value after placed +hbhunger.EXHAUST_MOVE = 0.3 -- exhaustion increased this value if player movement detected +hbhunger.EXHAUST_LVL = 160 -- at what exhaustion player satiation gets lowerd + + +--load custom settings +local set = io.open(minetest.get_modpath("hbhunger").."/hbhunger.conf", "r") +if set then + dofile(minetest.get_modpath("hbhunger").."/hbhunger.conf") + set:close() +end + +local function custom_hud(player) + hb.init_hudbar(player, "satiation", hbhunger.get_hunger_raw(player)) +end + +dofile(minetest.get_modpath("hbhunger").."/hunger.lua") + +-- register satiation hudbar +hb.register_hudbar("satiation", 0xFFFFFF, S("Satiation"), { icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, 20, 30, false, nil, { format_value = "%.1f", format_max_value = "%d" }) + +-- update hud elemtens if value has changed +local function update_hud(player) + local name = player:get_player_name() + --hunger + local h_out = tonumber(hbhunger.hunger_out[name]) + local h = tonumber(hbhunger.hunger[name]) + if h_out ~= h then + hbhunger.hunger_out[name] = h + hb.change_hudbar(player, "satiation", h) + end +end + +hbhunger.get_hunger_raw = function(player) + local inv = player:get_inventory() + if not inv then return nil end + local hgp = inv:get_stack("hunger", 1):get_count() + if hgp == 0 then + hgp = 21 + inv:set_stack("hunger", 1, ItemStack({name=":", count=hgp})) + else + hgp = hgp + end + return hgp-1 +end + +hbhunger.set_hunger_raw = function(player) + local inv = player:get_inventory() + local name = player:get_player_name() + local value = hbhunger.hunger[name] + if not inv or not value then return nil end + if value > 30 then value = 30 end + if value < 0 then value = 0 end + + inv:set_stack("hunger", 1, ItemStack({name=":", count=value+1})) + + return true +end + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + local inv = player:get_inventory() + inv:set_size("hunger",1) + hbhunger.hunger[name] = hbhunger.get_hunger_raw(player) + hbhunger.hunger_out[name] = hbhunger.hunger[name] + hbhunger.exhaustion[name] = 0 + hbhunger.poisonings[name] = 0 + custom_hud(player) + hbhunger.set_hunger_raw(player) +end) + +minetest.register_on_respawnplayer(function(player) + -- reset hunger (and save) + local name = player:get_player_name() + hbhunger.hunger[name] = 20 + hbhunger.set_hunger_raw(player) + hbhunger.exhaustion[name] = 0 +end) + +local main_timer = 0 +local timer = 0 +local timer2 = 0 +minetest.register_globalstep(function(dtime) + main_timer = main_timer + dtime + timer = timer + dtime + timer2 = timer2 + dtime + if main_timer > hbhunger.HUD_TICK or timer > 4 or timer2 > hbhunger.HUNGER_TICK then + if main_timer > hbhunger.HUD_TICK then main_timer = 0 end + for _,player in ipairs(minetest.get_connected_players()) do + local name = player:get_player_name() + + local h = tonumber(hbhunger.hunger[name]) + local hp = player:get_hp() + if timer > 4 then + -- heal player by 1 hp if not dead and satiation is > 15 (of 30) + if h > 15 and hp > 0 and player:get_breath() > 0 then + player:set_hp(hp+1) + -- or damage player by 1 hp if satiation is < 2 (of 30) + elseif h <= 1 then + if hp-1 >= 0 then player:set_hp(hp-1) end + end + end + -- lower satiation by 1 point after xx seconds + if timer2 > hbhunger.HUNGER_TICK then + if h > 0 then + h = h-1 + hbhunger.hunger[name] = h + hbhunger.set_hunger_raw(player) + end + end + + -- update all hud elements + update_hud(player) + + local controls = player:get_player_control() + -- Determine if the player is walking + if controls.up or controls.down or controls.left or controls.right then + hbhunger.handle_node_actions(nil, nil, player) + end + end + end + if timer > 4 then timer = 0 end + if timer2 > hbhunger.HUNGER_TICK then timer2 = 0 end +end) + +end diff --git a/mods/hbhunger/license.txt b/mods/hbhunger/license.txt new file mode 100644 index 0000000..03b85b7 --- /dev/null +++ b/mods/hbhunger/license.txt @@ -0,0 +1,14 @@ +### Source code + +* License: [LGPL v2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html) +* Author: by Wuzzy (2015-2016) +* Forked from the “Better HUD (and hunger)†mod by BlockMen (2013-2015), + most code comes from this mod. + +### Textures + +* `hbhunger_icon.png`—PilzAdam ([MIT License](https://opensource.org/licenses/MIT)), modified by BlockMen +* `hbhunger_bgicon.png`—PilzAdam (MIT License), modified by BlockMen +* `hbhunger_bar.png—Wuzzy` (MIT License) +* `hbhunger_icon_health_poison.png`—celeron55 ([CC BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)), modified by BlockMen, modified again by Wuzzy +* Everything else: MIT License, by BlockMen and Wuzzy diff --git a/mods/hbhunger/locale/hbhunger.de.tr b/mods/hbhunger/locale/hbhunger.de.tr new file mode 100644 index 0000000..4223564 --- /dev/null +++ b/mods/hbhunger/locale/hbhunger.de.tr @@ -0,0 +1,2 @@ +# textdomain:hbhunger +Satiation=Sättigung diff --git a/mods/hbhunger/locale/hbhunger.it.tr b/mods/hbhunger/locale/hbhunger.it.tr new file mode 100644 index 0000000..b99dc61 --- /dev/null +++ b/mods/hbhunger/locale/hbhunger.it.tr @@ -0,0 +1,2 @@ +# textdomain:hbhunger +Satiation=Sazietà diff --git a/mods/hbhunger/locale/hbhunger.ms.tr b/mods/hbhunger/locale/hbhunger.ms.tr new file mode 100644 index 0000000..67f08f7 --- /dev/null +++ b/mods/hbhunger/locale/hbhunger.ms.tr @@ -0,0 +1,2 @@ +# textdomain:hbhunger +Satiation=Kekenyangan diff --git a/mods/hbhunger/locale/hbhunger.pt.tr b/mods/hbhunger/locale/hbhunger.pt.tr new file mode 100644 index 0000000..82be594 --- /dev/null +++ b/mods/hbhunger/locale/hbhunger.pt.tr @@ -0,0 +1,2 @@ +# textdomain:hbhunger +Satiation=Saciedade diff --git a/mods/hbhunger/locale/hbhunger.ru.tr b/mods/hbhunger/locale/hbhunger.ru.tr new file mode 100644 index 0000000..afd6e66 --- /dev/null +++ b/mods/hbhunger/locale/hbhunger.ru.tr @@ -0,0 +1,2 @@ +# textdomain:hbhunger +Satiation=голод diff --git a/mods/hbhunger/locale/template.txt b/mods/hbhunger/locale/template.txt new file mode 100644 index 0000000..84ad832 --- /dev/null +++ b/mods/hbhunger/locale/template.txt @@ -0,0 +1,2 @@ +# textdomain:hbhunger +Satiation= diff --git a/mods/hbhunger/mod.conf b/mods/hbhunger/mod.conf new file mode 100644 index 0000000..da6c465 --- /dev/null +++ b/mods/hbhunger/mod.conf @@ -0,0 +1,4 @@ +name = hbhunger +description = Adds a simple hunger meachanic with satiation, food poisoning and different healing. +depends = hudbars +optional_depends = default, flowers, animalmaterials, bucket, bushes, bushes_classic, cooking, creatures, docfarming, dwarves, ethereal, farming, farming_plus, ferns, fishing, fruit, glooptest, jkanimals, jkfarming, jkwine, kpgmobs, mobfcooking, mobs, moretrees, mtfoods, mush45, mushroom, seaplants, pizza, nssm diff --git a/mods/hbhunger/sounds/hbhunger_eat_generic.ogg b/mods/hbhunger/sounds/hbhunger_eat_generic.ogg new file mode 100644 index 0000000..b6acd07 Binary files /dev/null and b/mods/hbhunger/sounds/hbhunger_eat_generic.ogg differ diff --git a/mods/hbhunger/textures/hbhunger_bar.png b/mods/hbhunger/textures/hbhunger_bar.png new file mode 100644 index 0000000..c94bf52 Binary files /dev/null and b/mods/hbhunger/textures/hbhunger_bar.png differ diff --git a/mods/hbhunger/textures/hbhunger_bar_health_poison.png b/mods/hbhunger/textures/hbhunger_bar_health_poison.png new file mode 100644 index 0000000..255a287 Binary files /dev/null and b/mods/hbhunger/textures/hbhunger_bar_health_poison.png differ diff --git a/mods/hbhunger/textures/hbhunger_bgicon.png b/mods/hbhunger/textures/hbhunger_bgicon.png new file mode 100644 index 0000000..07e21e7 Binary files /dev/null and b/mods/hbhunger/textures/hbhunger_bgicon.png differ diff --git a/mods/hbhunger/textures/hbhunger_icon.png b/mods/hbhunger/textures/hbhunger_icon.png new file mode 100644 index 0000000..a5cc2a1 Binary files /dev/null and b/mods/hbhunger/textures/hbhunger_icon.png differ diff --git a/mods/hbhunger/textures/hbhunger_icon_health_poison.png b/mods/hbhunger/textures/hbhunger_icon_health_poison.png new file mode 100644 index 0000000..8ce2db8 Binary files /dev/null and b/mods/hbhunger/textures/hbhunger_icon_health_poison.png differ diff --git a/mods/hbsprint/README.md b/mods/hbsprint/README.md new file mode 100644 index 0000000..c9d48b1 --- /dev/null +++ b/mods/hbsprint/README.md @@ -0,0 +1,39 @@ +# hbSprint + +## Description +A flexible sprint mod supporting stamina, hunger and coexistance with other physics altering mods. + +## Licensing +- LGPLv2.1/CC BY-SA 3.0. Particle code: copyright (c) 2017 Elijah Duffy. +- sprint_stamina_\*icon textures: + - CC0 + - Created by Jordan Irwin (AntumDeluge) + - Based on [Running man icon by manio1](https://openclipart.org/detail/254287) + +## Notes +hbSprint can be played with Minetest 0.4.16 or above. +It has no dependencies, but supports [hudbars](https://repo.or.cz/minetest_hudbars.git) and [player_monoids](https://github.com/minetest-mods/player_monoids). + +Compatible hunger mods: [hbhunger](https://repo.or.cz/minetest_hbhunger.git) or [hunger_ng](https://gitlab.com/4w/hunger_ng). + +## List of features + +- Displays and drains stamina (by default, if hudbars is present). Hides stamina bar if full. +- Displays and drains satiation (by default, if compatible hunger mod found) +- Drains air faster while sprinting on walkable ground but in water (by default) +- Requires only forward key to be pressed, not left and right (by default) +- Requires walkable ground (no water surface sprinting) +- Particle spawning based on ground type (Thanks to [octacian](https://github.com/octacian/sprint/)) +- All variables customizable in Advanced settings or directly in minetest.conf + + +## Known issues +- Forward double tap support not implemented + +## Bug reports and suggestions +You can report bugs or suggest ideas by [filing an issue](http://github.com/tacotexmex/hbsprint/issues/new). + +## Links +* [Download ZIP](https://github.com/minetest-mods/hbsprint/archive/master.zip) +* [Source](https://github.com/minetest-mods/hbsprint) +* [Forum thread](https://forum.minetest.net/viewtopic.php?f=9&t=18069&p=282981) diff --git a/mods/hbsprint/init.lua b/mods/hbsprint/init.lua new file mode 100644 index 0000000..6f3d163 --- /dev/null +++ b/mods/hbsprint/init.lua @@ -0,0 +1,259 @@ +-- Vars + +local function setting_get(name, default) + return minetest.settings:get(name) or default +end + +local speed = tonumber(setting_get("sprint_speed", "1.3")) +local jump = tonumber(setting_get("sprint_jump", "1.1")) +local dir = minetest.is_yes(setting_get("sprint_forward_only", "false")) +local particles = tonumber(setting_get("sprint_particles", "2")) +local stamina = minetest.is_yes(setting_get("sprint_stamina", "true")) +local stamina_drain = tonumber(setting_get("sprint_stamina_drain", "2")) +local replenish = tonumber(setting_get("sprint_stamina_replenish", "2")) +local starve = minetest.is_yes(setting_get("sprint_starve", "true")) +local starve_drain = tonumber(setting_get("sprint_starve_drain", "0.5")) +local starve_limit = tonumber(setting_get("sprint_starve_limit", "6")) +local breath = minetest.is_yes(setting_get("sprint_breath", "true")) +local breath_drain = tonumber(setting_get("sprint_breath_drain", "1")) +local autohide = minetest.is_yes(setting_get("hudbars_autohide_stamina", "true")) + +local sprint_timer_step = 0.5 +local sprint_timer = 0 +local sprinting = {} +local stamina_timer = {} +local breath_timer = {} + +local mod_hudbars = minetest.get_modpath("hudbars") ~= nil +local mod_player_monoids = minetest.get_modpath("player_monoids") ~= nil +local mod_playerphysics = minetest.get_modpath("playerphysics") ~= nil + +if starve then + if minetest.get_modpath("hbhunger") then + starve = "hbhunger" + elseif minetest.get_modpath("hunger_ng") then + starve = "hunger_ng" + else + starve = false + end +end +if minetest.settings:get_bool("creative_mode") then + starve = false +end + +-- Functions + +local function start_sprint(player) + local name = player:get_player_name() + local speed = player:get_physics_override().speed + local jump = player:get_physics_override().jump + if not sprinting[name] then + if mod_player_monoids then + player_monoids.speed:add_change(player, speed, "hbsprint:speed") + player_monoids.jump:add_change(player, jump, "hbsprint:jump") + elseif mod_playerphysics then + playerphysics.add_physics_factor(player, "speed", "hbsprint:speed", speed) + playerphysics.add_physics_factor(player, "jump", "hbsprint:jump", jump) + else + player:set_physics_override({speed = speed+.3, jump = jump+.1}) + end + sprinting[name] = true + end +end + +local function stop_sprint(player) + local name = player:get_player_name() + local speed = player:get_physics_override().speed + local jump = player:get_physics_override().jump + if sprinting[name] then + if mod_player_monoids then + player_monoids.speed:del_change(player, "hbsprint:speed") + player_monoids.jump:del_change(player, "hbsprint:jump") + elseif mod_playerphysics then + playerphysics.remove_physics_factor(player, "speed", "hbsprint:speed") + playerphysics.remove_physics_factor(player, "jump", "hbsprint:jump") + else + player:set_physics_override({speed = speed-.3, jump = jump-.1}) + end + sprinting[name] = false + end +end + +local function drain_stamina(player) + local player_stamina = player:get_meta():get_float("hbsprint:stamina") + if player_stamina > 0 then + player_stamina = math.max(0, player_stamina - stamina_drain) + player:get_meta():set_float("hbsprint:stamina", player_stamina) + end + if mod_hudbars then + if autohide and player_stamina < 20 then hb.unhide_hudbar(player, "stamina") end + hb.change_hudbar(player, "stamina", player_stamina) + end +end + +local function replenish_stamina(player) + local player_stamina = player:get_meta():get_float("hbsprint:stamina") + if player_stamina < 20 then + player_stamina = math.min(20, player_stamina + stamina_drain) + player:get_meta():set_float("hbsprint:stamina", player_stamina) + end + if mod_hudbars then + hb.change_hudbar(player, "stamina", player_stamina) + if autohide and player_stamina >= 20 then hb.hide_hudbar(player, "stamina") end + end +end + +local function drain_hunger(player, name) + if starve == "hbhunger" then + local hunger = tonumber(hbhunger.hunger[name]) - starve_drain + hbhunger.hunger[name] = math.max(0, hunger) + hbhunger.set_hunger_raw(player) + elseif starve == "hunger_ng" then + hunger_ng.alter_hunger(name, -starve_drain, "Sprinting") + end +end + +local function drain_breath(player) + local player_breath = player:get_breath() + if player_breath < player:get_properties().breath_max then + player_breath = math.max(0, player_breath - breath_drain) + player:set_breath(player_breath) + end +end + +local function is_walkable(ground) + local ground_def = minetest.registered_nodes[ground.name] + return ground_def and (ground_def.walkable and ground_def.liquidtype == "none") +end + +local function create_particles(player, name, ground) + local def = minetest.registered_nodes[ground.name] + local tile = def.tiles[1] or def.inventory_image + if type(tile) == "table" then + tile = tile.name + end + if not tile then + return + end + + local pos = player:get_pos() + local rand = function() return math.random(-1,1) * math.random() / 2 end + for i = 1, particles do + minetest.add_particle({ + pos = {x = pos.x + rand(), y = pos.y + 0.1, z = pos.z + rand()}, + velocity = {x = 0, y = 5, z = 0}, + acceleration = {x = 0, y = -13, z = 0}, + expirationtime = math.random(), + size = math.random() + 0.5, + vertical = false, + texture = tile, + }) + end +end + +-- Registrations + +if mod_hudbars and stamina then + hb.register_hudbar( + "stamina", + 0xFFFFFF, + "Stamina", + { + bar = "sprint_stamina_bar.png", + icon = "sprint_stamina_icon.png", + bgicon = "sprint_stamina_bgicon.png" + }, + 20, + 20, + autohide) +end + +minetest.register_on_joinplayer(function(player) + if stamina then + if mod_hudbars then + hb.init_hudbar(player, "stamina", 20, 20, autohide) + end + player:get_meta():set_float("hbsprint:stamina", 20) + end +end) + +local function sprint_step(player, dtime) + local name = player:get_player_name() + + if minetest.get_player_privs(name).fast then + return + end + + if stamina then + stamina_timer[name] = (stamina_timer[name] or 0) + dtime + end + if breath then + breath_timer[name] = (breath_timer[name] or 0) + dtime + end + + local ctrl = player:get_player_control() + local key_press + if dir then + key_press = ctrl.aux1 and ctrl.up and not ctrl.left and not ctrl.right + else + key_press = ctrl.aux1 + end + + if not key_press then + stop_sprint(player) + if stamina and stamina_timer[name] >= replenish then + replenish_stamina(player) + stamina_timer[name] = 0 + end + return + end + + local ground_pos = player:get_pos() + ground_pos.y = math.floor(ground_pos.y) + -- check if player is reasonably near a walkable node + local ground + for _, y_off in ipairs({0, -1, -2}) do + local testpos = vector.add(ground_pos, {x=0, y=y_off, z=0}) + local testnode = minetest.get_node_or_nil(testpos) + if testnode ~= nil and is_walkable(testnode) then + ground = testnode + break + end + end + + local player_stamina = 1 + if stamina then + player_stamina = player:get_meta():get_float("hbsprint:stamina") + end + local hunger = 30 + if starve == "hbhunger" then + hunger = tonumber(hbhunger.hunger[name]) + elseif starve == "hunger_ng" then + hunger = hunger_ng.get_hunger_information(name).hunger.exact + end + + if player_stamina > 0 and hunger > starve_limit and ground then + start_sprint(player) + if stamina then drain_stamina(player) end + if starve then drain_hunger(player, name) end + if breath and breath_timer[name] >= 2 then + drain_breath(player) + breath_timer[name] = 0 + end + if particles then + create_particles(player, name, ground) + end + else + stop_sprint(player) + end +end + +minetest.register_globalstep(function(dtime) + sprint_timer = sprint_timer + dtime + if sprint_timer >= sprint_timer_step then + for _, player in ipairs(minetest.get_connected_players()) do + sprint_step(player, sprint_timer) + end + sprint_timer = 0 + end +end) diff --git a/mods/hbsprint/license.txt b/mods/hbsprint/license.txt new file mode 100644 index 0000000..82da218 --- /dev/null +++ b/mods/hbsprint/license.txt @@ -0,0 +1,504 @@ +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. + +{description} +Copyright (C) {year} {fullname} + +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. + +{signature of Ty Coon}, 1 April 1990 +Ty Coon, President of Vice + +That's all there is to it! diff --git a/mods/hbsprint/mod.conf b/mods/hbsprint/mod.conf new file mode 100644 index 0000000..07be93e --- /dev/null +++ b/mods/hbsprint/mod.conf @@ -0,0 +1,3 @@ +name = hbsprint +optional_depends = player_monoids, hudbars, hbhunger, hunger_ng +description = A flexible sprint mod supporting stamina, hunger and monoids. diff --git a/mods/hbsprint/settingtypes.txt b/mods/hbsprint/settingtypes.txt new file mode 100644 index 0000000..2014a0d --- /dev/null +++ b/mods/hbsprint/settingtypes.txt @@ -0,0 +1,36 @@ +#Sprint speed multiplier +sprint_speed (Sprint speed multiplier) float 1.3 + +#Sprint jump multiplier +sprint_jump (Sprint jump multiplier) float 1.1 + +#Require player to move forward only to be able to sprint +sprint_forward_only (Sprint forward only) bool true + +#The amount of particles to spawn behind a sprinting player +sprint_particles (Particles) float 2 + +#Drain stamina while sprinting +sprint_stamina (Stamina) bool true + +#The amount of stamina to drain while sprinting +sprint_stamina_drain (Stamina drain) float 2 + +#The amount of seconds before starting to replenish stamina +sprint_stamina_replenish (Stamina replenish) float 2 + +#Drain satiation while sprinting +sprint_starve (Starve) bool true + +#The amount of satiation to drain while sprinting +sprint_starve_drain (Starve drain) float 0.5 + +#Drain air while sprinting under water +sprint_breath (Breath) bool true + +#The amount of air to drain while sprinting under water +sprint_breath_drain (Breath drain) float 1 + +#If enabled (default), the stamina indicators in the HUD will be automatically hidden shortly +#after stamina has filled up. Otherwise, stamina will always be displayed. +hudbars_autohide_stamina (Automatically hide staminal indicator) bool true diff --git a/mods/hbsprint/textures/sprint_stamina_bar.png b/mods/hbsprint/textures/sprint_stamina_bar.png new file mode 100644 index 0000000..55e1462 Binary files /dev/null and b/mods/hbsprint/textures/sprint_stamina_bar.png differ diff --git a/mods/hbsprint/textures/sprint_stamina_bgicon.png b/mods/hbsprint/textures/sprint_stamina_bgicon.png new file mode 100644 index 0000000..8e56295 Binary files /dev/null and b/mods/hbsprint/textures/sprint_stamina_bgicon.png differ diff --git a/mods/hbsprint/textures/sprint_stamina_icon.png b/mods/hbsprint/textures/sprint_stamina_icon.png new file mode 100644 index 0000000..89fce3b Binary files /dev/null and b/mods/hbsprint/textures/sprint_stamina_icon.png differ diff --git a/mods/hot_air_balloons/README.txt b/mods/hot_air_balloons/README.txt new file mode 100644 index 0000000..00af589 --- /dev/null +++ b/mods/hot_air_balloons/README.txt @@ -0,0 +1,57 @@ +This mod adds craftable and ridable hot air balloons to minetest. +Controls: + right click with coal lump: increase heat and buoyancy (*) + right click without coal: enter or leave balloon + left, right, up, down (default WASD): accelerate the balloon + sneak (default shift): decrease heat, lowering buoyancy + jump (default space): turn the balloon towards where the player is looking + + + +optional dependencies: + default, bucket (enable crafting recipe 1 if installed together) + mcl_core, mcl_mobitems, mcl_buckets (enable crafting recipe 2 if installed together) + + +Crafting recipe 1 (Minetest Game and most derivatives): +[P] := paper +[W] := wood +[L] := lava bucket +[ ] := nothing + +[P][P][P] +[P][L][P] +[ ][W][ ] + +Crafting recipe 2 (MineClone 2): +[L] := leather +[W] := wood +[V] := lava bucket +[S] := string + +[L][L][L] +[L][V][L] +[S][W][S] + +(*)any item with the "coal" group works for fuel. Higher coal group means higher heat + Note that coal blocks and ore from the default mod don't have the coal group + +See license.txt for proper license information. + +Author of code +---------------------------------------- +NetherEran (LGPL v2.1) + +Authors of media (models, textures) +---------------------------------------- +Textures +-------- +NetherEran (CC BY-SA 3.0): + hot_air_balloons_balloon.png + hot_air_balloons_balloon_flame.png + hot_air_balloons_balloon_model.png --Contains default_wood.png (by BlockMen) and default_aspen_wood.png (by sofar) (derived from default_pine_wood by paramat) + +Models +-------- +NetherEran (CC BY-SA 3.0): + ballon.blend (= hot_air_balloons_balloon.obj) diff --git a/mods/hot_air_balloons/absent_ballooner_rescuing.lua b/mods/hot_air_balloons/absent_ballooner_rescuing.lua new file mode 100644 index 0000000..b80c3e1 --- /dev/null +++ b/mods/hot_air_balloons/absent_ballooner_rescuing.lua @@ -0,0 +1,101 @@ +--localize things for better performance +local serialize = minetest.serialize +local add_entity = minetest.add_entity +local after = minetest.after + +--for storing which players left while in a balloon +local storage = minetest.get_mod_storage() +local absent_ballooners = minetest.deserialize(storage:get_string("absent_ballooners")) or {} + + +--putting leaving people into storage +local leave_while_ballooning = function(player) + local parent = player:get_attach() + if parent and not parent:is_player() + then + local balloon_type = parent:get_luaentity().balloon_type + if balloon_type + then + --remove() only works if someone else is in the area, + --hence the need for mark_for_deletion + parent:remove() + absent_ballooners[player:get_player_name()] = balloon_type + end + end +end + +--same as on_leave but for all players at once +local on_shutdown = function() + local connected_players = minetest.get_connected_players() + for i, p in ipairs(connected_players) + do + leave_while_ballooning(p) + end + storage:set_string("absent_ballooners", serialize(absent_ballooners)) +end +--putting leaving people into storage and saving storage +local on_leave = function(player) + leave_while_ballooning(player) + storage:set_string("absent_ballooners", serialize(absent_ballooners)) +end + +minetest.register_on_leaveplayer(on_leave) +minetest.register_on_shutdown(on_shutdown) + +--checking if player who joined was ballooning when they left +--if so spawn a new balloon and set them as attachment +local on_join = function(player) + if player + then + local name = player:get_player_name() + if absent_ballooners[name] + then + local pos = player:get_pos() + + --for compatibility with version 1.1 of the mod + if absent_ballooners[name] == true + then + absent_ballooners[name] = "hot_air_balloons:balloon" + end + --minetest doesn't seem to like add_entity on init so a minetest.after is used + --player is set as pilot in on_activate + after(2, + function() + --concatenating "P" with name signals that player should be set as attach + add_entity(pos, absent_ballooners[name], "P" .. name) + end) + end + end +end +minetest.register_on_joinplayer(on_join) + + +--called in on_activate if balloon was spawned to rescue an absent ballooner +local set_rescue = function(self, playername) + local player = minetest.get_player_by_name(playername) + self.pilot = playername + if not player --player logged off right away + then + self.object:remove() + return + end + player:set_attach(self.object, "", + {x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0}) + absent_ballooners[playername] = nil +end +--set as get_staticdata +local mark_for_deletion = function(self) + if self.pilot + then + --pilot logged off while ballooning, deleting balloon on next activation + return "R" + else + --normally save and load balloon + return "" + end +end + + +return set_rescue, mark_for_deletion + + diff --git a/mods/hot_air_balloons/api.txt b/mods/hot_air_balloons/api.txt new file mode 100644 index 0000000..97f1feb --- /dev/null +++ b/mods/hot_air_balloons/api.txt @@ -0,0 +1,30 @@ +API functions: + hot_air_balloons.get_entity(name, mesh_name, texture_name) + arguments: + 'name': string in the format "modname:entityname" + 'mesh_name': string in the format "modname_meshFileName" + 'texture_name': string in the format "modname_textureFileName" + Example usage: minetest.register_entity(hot_air_balloons.get_entity(foo, raa, see)) + you can also store the values in a local variable and change the fields of the entity definition table before registering the entity. + passing the entity name to the function is used when a balloon pilot logs off + + + + hot_air_balloons.get_item(name, description, texture, object_name) + arguments: + 'name': string in the format "modname:itemname" + 'description': string that appears in the tooltip. Use minetest.translate with this. + 'texture': string in the format "modname_textureFileName" + 'object_name' is the name specified in hot_air_balloons.get_entity + Example usage: minetest.register_craftitem(hot_air_balloons.get_item(foo, raa, see, mon)) + returns an item name and an item definition table + as with get_entity you can store the item definition table and change its fields before registering the item. + + + +explanation of the custom fields of the entitiy definition table: + pilot: stores the player name of the pilot or nil if there is no pilot + heat: integer in the interval [0, 12000) + Decides wether to fly up or down + balloon_type: entity name of the balloon, e.g."hot_air_balloons:balloon". + used to make the balloon log off and log back in together with its pilot \ No newline at end of file diff --git a/mods/hot_air_balloons/craft.lua b/mods/hot_air_balloons/craft.lua new file mode 100644 index 0000000..d75d1ab --- /dev/null +++ b/mods/hot_air_balloons/craft.lua @@ -0,0 +1,62 @@ +--This file adds crafting recipes depending on which dependencies are installed + + +if minetest.get_modpath("default") and + minetest.get_modpath("bucket") +then + minetest.register_craft( + { + output = "hot_air_balloons:item", + recipe = + { + {"default:paper", "default:paper", "default:paper"}, + {"default:paper", "bucket:bucket_lava", "default:paper"}, + {"", "group:wood", "" }, + }, + }) + minetest.register_craft( + { + type = "fuel", + recipe = "hot_air_balloons:item", + burntime = 20, + }) + return +end +if minetest.get_modpath("mcl_buckets") and + minetest.get_modpath("mcl_mobitems") and + minetest.get_modpath("mcl_core") +then + minetest.register_craft( + { + output = "hot_air_balloons:item", + recipe = + { + {"mcl_mobitems:leather", "mcl_mobitems:leather", "mcl_mobitems:leather"}, + {"mcl_mobitems:leather", "bucket:bucket_lava", "mcl_mobitems:leather"}, + {"mcl_mobitems:string", "group:wood", "mcl_mobitems:string" }, + }, + }) + minetest.register_craft( + { + type = "fuel", + recipe = "hot_air_balloons:item", + burntime = 20, + }) + return +end +--[[ +minetest.register_craft( +{ + type = "aircraft" +} +]] + +--make balloon work with mcl2 creative mode + +--announce in chat if no crafting recipe was added. +minetest.after(2, + function() + minetest.chat_send_all("Optional dependencies for hot_air_balloons are missing so no crafting recipe was added.\n".. + "Install either 'default' and 'bucket' or 'mcl_core', 'mcl_mobitems' 'and mcl_buckets' if this bothers you.\n".. + "All other functions of the mod should be unaffected by this.") + end) \ No newline at end of file diff --git a/mods/hot_air_balloons/depends.txt b/mods/hot_air_balloons/depends.txt new file mode 100644 index 0000000..a2d05cb --- /dev/null +++ b/mods/hot_air_balloons/depends.txt @@ -0,0 +1,5 @@ +default? +bucket? +mcl_buckets? +mcl_mobitems? +mcl_core? \ No newline at end of file diff --git a/mods/hot_air_balloons/init.lua b/mods/hot_air_balloons/init.lua new file mode 100644 index 0000000..5dd10b2 --- /dev/null +++ b/mods/hot_air_balloons/init.lua @@ -0,0 +1,221 @@ +--localize functions for better performance +local string_byte = string.byte +local string_sub = string.sub +local get_item_group = minetest.get_item_group +local add_particlespawner = minetest.add_particlespawner +local add_item = minetest.add_item +local get_node = minetest.get_node +local add_entity = minetest.add_entity + +local modpath = minetest.get_modpath("hot_air_balloons") +local set_rescue, mark_for_deletion_if_piloted = dofile(modpath .. "/absent_ballooner_rescuing.lua") +local handle_movement = dofile(modpath .. "/movement.lua") + +local is_in_creative = function(name) + return creative and creative.is_enabled_for + and creative.is_enabled_for(name) +end + +local get_fire_particle = function (pos) + pos.y = pos.y + 3 + return { + amount = 3, + time = 1, + minpos = pos, + maxpos = pos, + minvel = {x = 0, y = 1, z = 0}, + maxvel = {x = 0, y = 1, z = 0}, + minexptime = 1, + maxexptime = 1, + minsize = 10, + maxsize = 5, + collisiondetection = false, + vertical = false, + texture = "hot_air_balloons_flame.png" + } +end + +local add_heat = function(self, player) + local item_stack = player:get_wielded_item() + local item_name = item_stack:get_name() + local group_coal = get_item_group(item_name, "coal") + if group_coal == 0 + then + return false + end + local heat = self.heat + heat = heat + 1200 * group_coal --1 min until heat is back to original + if heat < 12000 --cap heat at 12000 (10 min) + then + self.heat = heat + --adding particle effect + local pos = self.object:get_pos() + add_particlespawner(get_fire_particle(pos)) + if not is_in_creative(player:get_player_name()) + then + item_stack:take_item() + player:set_wielded_item(item_stack) + end + end + return true +end + +--global table, has fields get_entity_def and get_item_def +--custom balloons right now turn into normal ones when the pilot leaves +hot_air_balloons = {} +hot_air_balloons.get_entity = function(name, mesh_name, texture_name) + return + name, + { + initial_properties = + { + hp_max = 1, + physical = true, + weight = 5, + collisionbox = {-0.65, -0.01, -0.65, 0.65, 1.11, 0.65}, + visual = "mesh", + mesh = "hot_air_balloons_balloon.obj", + textures = {"hot_air_balloons_balloon_model.png"}, + is_visible = true, + makes_footstep_sound = false, + automatic_rotate = false, + backface_culling = false, + }, + heat = 0, + balloon_type = name, + + on_step = function(self, dtime) + --decrease heat, move + if self.heat > 0 + then + self.heat = self.heat - 1 + end + handle_movement(self) + end, + on_rightclick = function (self, clicker) + --if hoding coal, increase heat, else mount/dismount + if not clicker or not clicker:is_player() + then + return + end + --checking if clicker is holding coal + --heating balloon and returning if yes + if add_heat(self, clicker) + then + return + end + + --if not holding coal: + local playername = clicker:get_player_name() + if self.pilot and self.pilot == playername + then + self.pilot = nil + clicker:set_detach() + elseif not self.pilot + then + --attach + self.pilot = playername + clicker:set_attach(self.object, "", + {x = 0, y = 1, z = 0}, {x = 0, y = 0, z = 0}) + end + end, + --if pilot leaves start sinking and prepare for next pilot + on_detach_child = function(self, child) + self.heat = 0 + self.object:setvelocity({x = 0, y = 0, z = 0}) + end, + + on_activate = function(self, staticdata, dtime_s) + self.object:set_armor_groups({punch_operable = 1}) + --so balloons don't get lost + self.object:setvelocity({x = 0, y = 0, z = 0}) + + --checking if balloon was spawned from item or unloaded without pilot + if staticdata == "" + then + return + end + --checking if balloon should despawn when pilot logged off + local first_char = string_byte(staticdata) + --ballooner logged off, balloon will respawn when ballooner logs back in + if first_char == 82 --chr 82 = R + then + self.object:remove() + return + --absent ballooner logged back in + elseif first_char == 80 --chr 80 = P + then + set_rescue(self, string_sub(staticdata, 2)) + end + end, + + get_staticdata = mark_for_deletion_if_piloted, + + + on_punch = function(self, puncher) --drop balloon item + if self.pilot + then + return + elseif not (puncher and puncher:is_player()) + then + return + else + self.object:remove() + local inv = puncher:get_inventory() + if not is_in_creative(puncher:get_player_name()) + or not inv:contains_item("main", "hot_air_balloons:item") + then + local leftover = inv:add_item("main", "hot_air_balloons:item") + if not leftover:is_empty() + then + add_item(self.object:get_pos(), leftover) + end + end + end + end, + } +end + +hot_air_balloons.get_item = function(name, description, texture, object_name) +return + name, + { + description = description, + inventory_image = texture, + stack_max = 1, + liquids_pointable = true, + groups = {flammable = 2}, + on_place = + function (itemstack, placer, pointed_thing) + --places balloon if the clicked thing is a node and the above node is air + if pointed_thing.type == "node" + and get_node (pointed_thing.above).name == "air" + then + if not is_in_creative(placer:get_player_name()) + then + itemstack:take_item() + end + local pos_to_place = pointed_thing.above + pos_to_place.y = pos_to_place.y - 0.5 --subtracting 0.5 to place on ground + add_entity(pointed_thing.above, object_name) + end + --add remaining items to inventory + return itemstack + end + } +end +--registering the balloon entity, item and recepies + +minetest.register_entity(hot_air_balloons.get_entity( + "hot_air_balloons:balloon", + "hot_air_balloons_balloon.obj", + "hot_air_balloons_balloon_model.png")) + +minetest.register_craftitem(hot_air_balloons.get_item( + "hot_air_balloons:item", + minetest.translate("hot_air_balloons", "Hot Air Balloon"), + "hot_air_balloons_balloon.png", + "hot_air_balloons:balloon")) + + +dofile(modpath .. "/craft.lua") \ No newline at end of file diff --git a/mods/hot_air_balloons/license.txt b/mods/hot_air_balloons/license.txt new file mode 100644 index 0000000..8dc6208 --- /dev/null +++ b/mods/hot_air_balloons/license.txt @@ -0,0 +1,54 @@ +License of source code +---------------------- + +GNU Lesser General Public License, version 2.1 +Copyright (C) 2019 NetherEran + +This program 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 program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU Lesser General Public License for more details: +https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + +Licenses of media (textures, models and sounds) +----------------------------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2010-2018: + + NetherEran + BlockMen + sofar + paramat + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ \ No newline at end of file diff --git a/mods/hot_air_balloons/locale/hot_air_balloons.de.tr b/mods/hot_air_balloons/locale/hot_air_balloons.de.tr new file mode 100644 index 0000000..610cc41 --- /dev/null +++ b/mods/hot_air_balloons/locale/hot_air_balloons.de.tr @@ -0,0 +1,2 @@ +# textdomain:hot_air_balloons +Hot Air Balloon=Heißluftballon \ No newline at end of file diff --git a/mods/hot_air_balloons/locale/hot_air_balloons.es.tr b/mods/hot_air_balloons/locale/hot_air_balloons.es.tr new file mode 100644 index 0000000..05f331e --- /dev/null +++ b/mods/hot_air_balloons/locale/hot_air_balloons.es.tr @@ -0,0 +1,2 @@ +# textdomain:hot_air_balloons +Hot Air Balloon=Globo Aerostático \ No newline at end of file diff --git a/mods/hot_air_balloons/locale/hot_air_balloons.ro.tr b/mods/hot_air_balloons/locale/hot_air_balloons.ro.tr new file mode 100644 index 0000000..99cf77d --- /dev/null +++ b/mods/hot_air_balloons/locale/hot_air_balloons.ro.tr @@ -0,0 +1,2 @@ +# textdomain:hot_air_balloons +Hot Air Balloon=Balon cu aer cald \ No newline at end of file diff --git a/mods/hot_air_balloons/mod.conf b/mods/hot_air_balloons/mod.conf new file mode 100644 index 0000000..aa27390 --- /dev/null +++ b/mods/hot_air_balloons/mod.conf @@ -0,0 +1,4 @@ +name = hot_air_balloons +author = Eran +description = Adds craftable and controllable hot air balloons. +optional_depends = default, bucket, mcl_buckets, mcl_mobitems, mcl_core diff --git a/mods/hot_air_balloons/models/balloon.blend b/mods/hot_air_balloons/models/balloon.blend new file mode 100644 index 0000000..68cecf6 Binary files /dev/null and b/mods/hot_air_balloons/models/balloon.blend differ diff --git a/mods/hot_air_balloons/models/hot_air_balloons_balloon.obj b/mods/hot_air_balloons/models/hot_air_balloons_balloon.obj new file mode 100644 index 0000000..871dada --- /dev/null +++ b/mods/hot_air_balloons/models/hot_air_balloons_balloon.obj @@ -0,0 +1,485 @@ +# Blender v2.79 (sub 0) OBJ File: 'balloon.blend' +# www.blender.org +mtllib hot_air_balloons_balloon.mtl +o Cube.001 +v -19.500000 44.216793 19.500000 +v -19.500000 83.216797 19.500000 +v -19.500000 44.216793 -19.500000 +v -19.500000 83.216797 -19.500000 +v 19.500000 44.216793 19.500000 +v 19.500000 83.216797 19.500000 +v 19.500000 44.216793 -19.500000 +v 19.500000 83.216797 -19.500000 +v -6.500000 0.016788 6.500000 +v 6.500000 0.016788 6.500000 +v -6.500000 0.016788 -6.500000 +v 6.500000 0.016788 -6.500000 +v -6.500000 1.441189 6.500000 +v 6.500000 1.441189 6.500000 +v -6.500000 1.441189 -6.500000 +v 6.500000 1.441189 -6.500000 +v -6.500000 0.016788 -4.550000 +v -6.500000 0.016788 4.550000 +v 6.500000 0.016788 4.550000 +v 6.500000 0.016788 -4.550000 +v -6.500000 1.441189 -4.550000 +v -6.500000 1.441189 4.550000 +v 6.500000 1.441189 4.550000 +v 6.500000 1.441189 -4.550000 +v -4.550000 0.016788 6.500000 +v 4.550000 0.016788 6.500000 +v 4.550000 0.016788 -6.500000 +v -4.550000 0.016788 -6.500000 +v -4.550000 1.441189 6.500000 +v 4.550000 1.441189 6.500000 +v 4.550000 1.441189 -6.500000 +v -4.550000 1.441189 -6.500000 +v 4.550000 1.441189 4.550000 +v -4.550000 1.441189 4.550000 +v -4.550000 1.441189 -4.550000 +v -4.550000 0.016788 4.550000 +v 4.550000 0.016788 4.550000 +v -4.550000 0.016788 -4.550000 +v 4.550000 0.016788 -4.550000 +v 6.500000 11.077995 6.500000 +v -6.500000 11.077995 6.500000 +v 6.500000 11.077995 6.500000 +v -6.500000 11.077995 -6.500000 +v -6.500000 11.077995 6.500000 +v 6.500000 11.077995 -6.500000 +v 4.550000 11.077995 4.550000 +v 4.550000 11.077995 -4.550000 +v -4.550000 11.077995 -4.550000 +v -4.550000 11.077995 -4.550000 +v -4.550000 1.441189 -4.550000 +v 4.550000 1.441189 -4.550000 +v 4.550000 11.077995 -4.550000 +v -4.550000 11.077995 4.550000 +v 4.550000 1.441189 4.550000 +v 6.500000 1.441189 -6.500000 +v 4.550000 11.077995 4.550000 +v -4.550000 11.077995 -6.500000 +v -6.500000 1.441189 -6.500000 +v 4.550000 11.077995 -6.500000 +v 4.550000 11.077995 6.500000 +v -4.550000 11.077995 6.500000 +v 6.500000 11.077995 -4.550000 +v 6.500000 1.441189 6.500000 +v 6.500000 11.077995 4.550000 +v -6.500000 11.077995 4.550000 +v -6.500000 11.077995 -4.550000 +v -6.500000 1.441189 6.500000 +v 6.500000 11.077995 -6.500000 +v -6.500000 11.077995 -6.500000 +v 5.586319 8.609333 -5.559702 +v 11.988016 44.915165 -12.060156 +v 5.537368 8.331722 -7.158404 +v 11.939065 44.637550 -13.658857 +v 7.185020 8.327442 -5.559702 +v 13.586718 44.633270 -12.060156 +v 7.136070 8.049831 -7.158404 +v 13.537767 44.355656 -13.658857 +v -5.586318 8.609333 -5.559702 +v -11.988014 44.915165 -12.060155 +v -5.537367 8.331722 -7.158404 +v -11.939065 44.637554 -13.658857 +v -7.185020 8.327442 -5.559702 +v -13.586717 44.633270 -12.060155 +v -7.136071 8.049831 -7.158404 +v -13.537764 44.355656 -13.658857 +v 5.586319 8.609337 5.559702 +v 11.988015 44.915161 12.060157 +v 5.537368 8.331722 7.158404 +v 11.939065 44.637547 13.658860 +v 7.185020 8.327442 5.559702 +v 13.586717 44.633270 12.060157 +v 7.136070 8.049831 7.158404 +v 13.537766 44.355652 13.658860 +v -5.586318 8.609337 5.559702 +v -11.988016 44.915161 12.060155 +v -5.537367 8.331722 7.158405 +v -11.939065 44.637550 13.658857 +v -7.185019 8.327442 5.559704 +v -13.586717 44.633266 12.060157 +v -7.136071 8.049831 7.158405 +v -13.537766 44.355652 13.658860 +vt 0.666667 0.666667 +vt 0.333333 0.666667 +vt 0.333333 0.333333 +vt 0.666667 0.333333 +vt 0.000000 1.000000 +vt 0.000000 0.666667 +vt 0.333333 0.666667 +vt 0.333333 1.000000 +vt 0.333333 0.333333 +vt 0.000000 0.333333 +vt 0.000000 0.000000 +vt 0.333333 0.000000 +vt 0.333333 0.333333 +vt 0.333333 0.000000 +vt 0.666667 0.000000 +vt 0.666667 0.333333 +vt 0.000000 0.666667 +vt 0.000000 0.333333 +vt 0.333333 0.666667 +vt 0.666667 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.333333 +vt 0.666667 0.333333 +vt 0.350615 0.683822 +vt 0.333949 0.683822 +vt 0.333949 0.667155 +vt 0.350615 0.667155 +vt 0.761207 0.649225 +vt 0.761207 0.665892 +vt 0.749033 0.665892 +vt 0.749033 0.649225 +vt 0.761207 0.427778 +vt 0.761207 0.444444 +vt 0.749033 0.444444 +vt 0.749033 0.427778 +vt 0.538985 0.761111 +vt 0.538985 0.777778 +vt 0.526810 0.777778 +vt 0.526810 0.761111 +vt 0.667442 0.461111 +vt 0.667442 0.444444 +vt 0.679616 0.444444 +vt 0.679616 0.461111 +vt 0.667442 0.555556 +vt 0.667442 0.538889 +vt 0.679616 0.538889 +vt 0.679616 0.555556 +vt 0.761207 0.555556 +vt 0.761207 0.572222 +vt 0.749033 0.572222 +vt 0.749033 0.555556 +vt 0.761207 0.650000 +vt 0.749033 0.650000 +vt 0.749420 0.427778 +vt 0.749420 0.444444 +vt 0.667054 0.444444 +vt 0.667054 0.427778 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.445060 0.683822 +vt 0.428393 0.683822 +vt 0.428393 0.667155 +vt 0.445060 0.667155 +vt 0.428393 0.777778 +vt 0.350615 0.777778 +vt 0.350615 0.761111 +vt 0.428393 0.761111 +vt 0.350615 0.683333 +vt 0.428393 0.683333 +vt 0.445060 0.777778 +vt 0.445060 0.761111 +vt 0.445060 0.683333 +vt 0.749420 0.555556 +vt 0.749420 0.572222 +vt 0.667054 0.572222 +vt 0.667054 0.555556 +vt 0.616763 0.749521 +vt 0.538985 0.749521 +vt 0.538985 0.667155 +vt 0.616763 0.667155 +vt 0.750035 0.334724 +vt 0.750035 0.351390 +vt 0.667669 0.351390 +vt 0.667669 0.334724 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.538985 0.667362 +vt 0.538985 0.684029 +vt 0.526810 0.684029 +vt 0.526810 0.667362 +vt 0.538985 0.683333 +vt 0.526810 0.683333 +vt 0.761822 0.334724 +vt 0.761822 0.351390 +vt 0.749648 0.351390 +vt 0.749648 0.334724 +vt 0.761207 0.350000 +vt 0.749033 0.350000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.333949 0.777778 +vt 0.333949 0.761111 +vt 0.333949 0.683333 +vt 0.744444 0.749033 +vt 0.666667 0.749033 +vt 0.666667 0.666667 +vt 0.744444 0.666667 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.744444 0.666667 +vt 0.822222 0.666667 +vt 0.822222 0.749033 +vt 0.744444 0.749033 +vt 0.444445 0.777778 +vt 0.444445 0.761111 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.616763 0.777778 +vt 0.616763 0.666667 +vt 0.633429 0.666667 +vt 0.633429 0.777778 +vt 0.616763 0.831398 +vt 0.538985 0.831398 +vt 0.538985 0.749033 +vt 0.616763 0.749033 +vt 0.444445 0.683333 +vt 0.749420 0.650000 +vt 0.667054 0.650000 +vt 0.678841 0.538889 +vt 0.678841 0.461111 +vt 0.761207 0.461111 +vt 0.761207 0.538889 +vt 0.749420 0.649225 +vt 0.749420 0.665892 +vt 0.667054 0.665892 +vt 0.667054 0.649225 +vt 0.678841 0.555556 +vt 0.761207 0.555556 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.678841 0.444444 +vt 0.761207 0.444444 +vt 0.749420 0.350000 +vt 0.667054 0.350000 +vt 0.000000 0.000000 +vt 0.000000 0.000000 +vt 0.444445 0.684029 +vt 0.444445 0.667362 +vt 0.633429 0.666667 +vt 0.650096 0.666667 +vt 0.650096 0.777778 +vt 0.633429 0.777778 +vt 0.744444 0.749033 +vt 0.761111 0.749033 +vt 0.761111 0.826810 +vt 0.744444 0.826810 +vt 0.777778 0.749033 +vt 0.777778 0.826810 +vt 0.761111 0.826810 +vt 0.761111 0.749033 +vt 0.666667 0.749033 +vt 0.744444 0.749033 +vt 0.744444 0.826810 +vt 0.666667 0.826810 +vt 0.858286 0.648647 +vt 0.858286 0.333406 +vt 0.872154 0.333333 +vt 0.872154 0.648574 +vt 0.941529 0.333333 +vt 0.941529 0.648427 +vt 0.927654 0.648427 +vt 0.927654 0.333333 +vt 0.844417 0.333406 +vt 0.844417 0.648647 +vt 0.830549 0.648574 +vt 0.830549 0.333333 +vt 0.955404 0.333333 +vt 0.955404 0.648427 +vt 0.941529 0.648427 +vt 0.941529 0.333333 +vt 0.650096 0.694844 +vt 0.663754 0.695262 +vt 0.663754 0.708933 +vt 0.650096 0.708515 +vt 0.663754 0.722603 +vt 0.650096 0.723022 +vt 0.650096 0.709351 +vt 0.663754 0.708933 +vt 0.844417 0.333333 +vt 0.858286 0.333406 +vt 0.858286 0.648647 +vt 0.844417 0.648574 +vt 0.913779 0.333333 +vt 0.927654 0.333333 +vt 0.927654 0.648427 +vt 0.913779 0.648427 +vt 0.830549 0.648574 +vt 0.816681 0.648647 +vt 0.816681 0.333406 +vt 0.830549 0.333333 +vt 0.886029 0.648427 +vt 0.872154 0.648427 +vt 0.872154 0.333333 +vt 0.886029 0.333333 +vt 0.650096 0.694844 +vt 0.650096 0.681174 +vt 0.663754 0.680755 +vt 0.663754 0.694426 +vt 0.650096 0.750781 +vt 0.650096 0.737110 +vt 0.663754 0.737528 +vt 0.663754 0.751199 +vt 0.802812 0.648647 +vt 0.788944 0.648574 +vt 0.788944 0.333333 +vt 0.802812 0.333406 +vt 0.886029 0.648427 +vt 0.899904 0.648427 +vt 0.899904 0.963520 +vt 0.886029 0.963520 +vt 0.762184 0.333406 +vt 0.776052 0.333333 +vt 0.776052 0.648574 +vt 0.762183 0.648647 +vt 0.913779 0.648426 +vt 0.899904 0.648427 +vt 0.899904 0.333333 +vt 0.913779 0.333333 +vt 0.650096 0.765288 +vt 0.650096 0.751617 +vt 0.663754 0.751199 +vt 0.663754 0.764869 +vt 0.650096 0.680337 +vt 0.650096 0.666667 +vt 0.663754 0.667085 +vt 0.663754 0.680755 +vt 0.816681 0.333333 +vt 0.816681 0.648574 +vt 0.802812 0.648647 +vt 0.802812 0.333406 +vt 0.886029 0.648427 +vt 0.886029 0.333333 +vt 0.899904 0.333333 +vt 0.899904 0.648426 +vt 0.788944 0.333406 +vt 0.788944 0.648647 +vt 0.775075 0.648574 +vt 0.775075 0.333333 +vt 0.872154 0.963520 +vt 0.872154 0.648427 +vt 0.886029 0.648427 +vt 0.886029 0.963520 +vt 0.650096 0.723022 +vt 0.663754 0.723440 +vt 0.663754 0.737110 +vt 0.650096 0.736692 +vt 0.774865 0.662317 +vt 0.761207 0.662735 +vt 0.761207 0.649065 +vt 0.774865 0.648647 +vn -1.0000 0.0000 0.0000 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 0.0000 1.0000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn -0.9848 0.1736 0.0000 +vn -0.0302 -0.1710 -0.9848 +vn 0.9848 -0.1736 0.0000 +vn 0.0302 0.1710 0.9848 +vn -0.1710 -0.9698 0.1736 +vn 0.1710 0.9698 -0.1736 +vn 0.9848 0.1736 -0.0000 +vn 0.0302 -0.1710 -0.9848 +vn -0.9848 -0.1736 -0.0000 +vn -0.0302 0.1710 0.9848 +vn 0.1710 -0.9698 0.1736 +vn -0.1710 0.9698 -0.1737 +vn -0.0302 -0.1710 0.9848 +vn 0.0302 0.1710 -0.9848 +vn -0.1710 -0.9698 -0.1736 +vn 0.1710 0.9698 0.1737 +vn 0.0302 -0.1710 0.9848 +vn -0.0302 0.1710 -0.9848 +vn 0.1710 -0.9698 -0.1736 +vn -0.1710 0.9698 0.1736 +usemtl None +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/5/2 4/6/2 8/7/2 7/8/2 +f 7/9/3 8/10/3 6/11/3 5/12/3 +f 5/13/4 6/14/4 2/15/4 1/16/4 +f 3/17/5 7/18/5 5/13/5 1/19/5 +f 8/20/6 4/21/6 2/22/6 6/23/6 +f 39/24/5 27/25/5 12/26/5 20/27/5 +f 18/28/1 9/29/1 13/30/1 22/31/1 +f 28/32/2 11/33/2 15/34/2 32/35/2 +f 26/36/4 10/37/4 14/38/4 30/39/4 +f 20/40/3 12/41/3 16/42/3 24/43/3 +f 10/44/3 19/45/3 23/46/3 14/47/3 +f 19/45/3 20/40/3 24/43/3 23/46/3 +f 11/48/1 17/49/1 21/50/1 15/51/1 +f 17/49/1 18/52/1 22/53/1 21/50/1 +f 32/54/2 15/55/2 69/56/2 57/57/2 +f 15/58/4 58/59/4 43/60/4 69/61/4 +f 26/62/5 37/63/5 19/64/5 10/65/5 +f 37/63/5 39/24/5 20/27/5 19/64/5 +f 18/66/5 17/67/5 38/68/5 36/69/5 +f 36/69/5 38/68/5 39/70/5 37/71/5 +f 9/72/5 18/66/5 36/69/5 25/73/5 +f 25/73/5 36/69/5 37/71/5 26/74/5 +f 15/75/1 21/76/1 66/77/1 69/78/1 +f 51/79/2 50/80/2 48/81/2 47/82/2 +f 16/83/2 31/84/2 59/85/2 68/86/2 +f 52/87/4 56/88/4 46/89/4 47/90/4 +f 9/91/4 25/92/4 29/93/4 13/94/4 +f 25/95/4 26/36/4 30/39/4 29/96/4 +f 12/97/2 27/98/2 31/99/2 16/100/2 +f 27/101/2 28/32/2 32/35/2 31/102/2 +f 49/103/4 52/87/4 47/90/4 48/104/4 +f 17/67/5 11/105/5 28/106/5 38/68/5 +f 38/68/5 28/106/5 27/107/5 39/70/5 +f 34/108/4 33/109/4 56/110/4 53/111/4 +f 13/112/4 67/113/4 41/114/4 44/115/4 +f 16/116/4 55/117/4 45/118/4 68/119/4 +f 54/120/3 51/121/3 47/122/3 46/123/3 +f 30/39/4 14/38/4 40/124/4 60/125/4 +f 14/126/4 63/127/4 42/128/4 40/129/4 +f 44/130/6 42/131/6 64/132/6 65/133/6 +f 35/134/1 34/135/1 53/136/1 49/137/1 +f 29/96/4 30/39/4 60/125/4 61/138/4 +f 21/76/1 22/139/1 65/140/1 66/77/1 +f 23/141/3 24/142/3 62/143/3 64/144/3 +f 22/145/1 13/146/1 44/147/1 65/148/1 +f 14/149/3 23/141/3 64/144/3 40/150/3 +f 50/151/4 35/152/4 49/103/4 48/104/4 +f 24/142/3 16/153/3 68/154/3 62/143/3 +f 31/155/2 32/54/2 57/57/2 59/156/2 +f 33/157/4 54/158/4 46/89/4 56/88/4 +f 13/94/4 29/93/4 61/159/4 44/160/4 +f 62/161/6 68/162/6 69/163/6 66/164/6 +f 62/165/6 52/166/6 56/167/6 64/168/6 +f 66/169/6 65/170/6 53/171/6 49/172/6 +f 51/173/5 54/174/5 34/175/5 50/176/5 +f 70/177/7 71/178/7 73/179/7 72/180/7 +f 72/181/8 73/182/8 77/183/8 76/184/8 +f 76/185/9 77/186/9 75/187/9 74/188/9 +f 74/189/10 75/190/10 71/191/10 70/192/10 +f 72/193/11 76/194/11 74/195/11 70/196/11 +f 77/197/12 73/198/12 71/199/12 75/200/12 +f 78/201/13 80/202/13 81/203/13 79/204/13 +f 80/205/14 84/206/14 85/207/14 81/208/14 +f 84/209/15 82/210/15 83/211/15 85/212/15 +f 82/213/16 78/214/16 79/215/16 83/216/16 +f 80/217/17 78/218/17 82/219/17 84/220/17 +f 85/221/18 83/222/18 79/223/18 81/224/18 +f 86/225/7 88/226/7 89/227/7 87/228/7 +f 88/229/19 92/230/19 93/231/19 89/232/19 +f 92/233/9 90/234/9 91/235/9 93/236/9 +f 90/237/20 86/238/20 87/239/20 91/240/20 +f 88/241/21 86/242/21 90/243/21 92/244/21 +f 93/245/22 91/246/22 87/247/22 89/248/22 +f 94/249/13 95/250/13 97/251/13 96/252/13 +f 96/253/23 97/254/23 101/255/23 100/256/23 +f 100/257/15 101/258/15 99/259/15 98/260/15 +f 98/261/24 99/262/24 95/263/24 94/264/24 +f 96/265/25 100/266/25 98/267/25 94/268/25 +f 101/269/26 97/270/26 95/271/26 99/272/26 diff --git a/mods/hot_air_balloons/movement.lua b/mods/hot_air_balloons/movement.lua new file mode 100644 index 0000000..1db168b --- /dev/null +++ b/mods/hot_air_balloons/movement.lua @@ -0,0 +1,209 @@ +--localize global functions +local vector_new = vector.new +local math_hypot = math.hypot +local atan = math.atan +local cos = math.cos +local sin = math.sin +local abs = math.abs +local pi = math.pi +local min = math.min + +--max speed settings +local max_ballooning_vertical_speed = 1 +local max_ballooning_horizontal_speed = 3 + +local function is_water_is_air(pos) + local node_name = minetest.get_node(pos).name + return minetest.get_item_group(node_name, "water") > 0, + node_name == "air" +end +local function get_vertical_acceleration(self) + local heat = self.heat + local vel_y = self.object:getvelocity().y + local acc_candidate = heat / 1000 - 0.5 + + --enforce max speed + if vel_y > max_ballooning_vertical_speed + and acc_candidate * vel_y > 0 + then + return 0 + else + return acc_candidate + end +end + +--if balloon is submerged +local function float_up(self, vel) + self.submerged = true + vel.y = 1 + return vel +end + +local function swim(self, vel) + --allow controls, allow up + local pos = self.object:get_pos() + --keep y constant or rising + local acc_y = get_vertical_acceleration(self) + + if self.submerged or acc_y < 0 + then + self.submerged = false + vel.y = 0 + return 0, vel + else + return acc_y, vel + end +end + + +local tau = pi * 2 +--returns the radian equivalent of a in the range [0, tau) +local function to_radian(a) + if a < 0 + then + return to_radian(a + tau) + elseif a >= tau + then + return to_radian(a - tau) + else + return a + end +end +--decides which is the shortest way to rotate towards where the player is looking +local function get_rotate_direction(a, b) + return to_radian(a - b) < to_radian(b - a) +end + +--rotates the balloon towards where the player is looking +local pi_192ths = pi / 192 --radians to turn each step +local function rotate(self, player) + -- + pi so it finishes rotating when looking towards where the player is looking + local player_yaw = player:get_look_horizontal() + pi + local self_yaw = self.object:getyaw() + + if get_rotate_direction(player_yaw, self_yaw) + then + self.object:setyaw(to_radian(self_yaw - pi_192ths)) + else + self.object:setyaw(to_radian(self_yaw + pi_192ths)) + end +end + +--takes wasd and turns it into a 2d vector +local pi_halves = pi / 2 +function get_direction(right, left, up, down) + local inline, cross = 0, 0 + local move = right or left or up or down + if left then cross = 1 end + if right then cross = cross - 1 end + if up then inline = 1 end + if down then inline = inline - 1 end + local arg + if inline < 0 + then + return atan(cross / inline) + pi, move + elseif inline > 0 + then + return atan(cross / inline), move + else + return pi_halves * cross, move + end +end + + +--[[ +space to rotate where the player is looking +wasd to apply acceleration +shift to let out hot air, cooling the balloon +]] +local function handle_control(self, vel) + if not self.pilot + then + return 0, 0 + end + local player = minetest.get_player_by_name(self.pilot) + if not player --player left, balloon should get deleted + then + return 0, 0 + end + local control = player:get_player_control() + if control.sneak --lowering heat quickly + then + local heat = self.heat - 30 + if heat < 0 + then + self.heat = 0 + else + self.heat = heat + end + end + + if control.jump --rotate towards player yaw + then + rotate(self, player) + end + + --taking direction from get_direction + --and turning it into radians. + --if max speed is reached, only acceleration in the opposite direction is applied. + local dir_radians, move = get_direction(control.right, control.left, control.up, control.down) + if move and math_hypot(vel.x, vel.z) + then + dir_radians = dir_radians + player:get_look_horizontal() + local x, z = -sin(dir_radians), cos(dir_radians) + if math_hypot(vel.x, vel.z) > max_ballooning_horizontal_speed + then + if x * vel.x > 0 + then + x = 0 + end + if z * vel.z > 0 + then + z = 0 + end + end + return x, z + end + return 0, 0 +end + +--[[handle movement in different cases +movement restrictions: + -on ground: only vertical movement + -on water: free movement, though vertical only if up + -submerged: free movement, vertical goes up automatically + -in air: completely free movement +]] + +return function(self) + local pos_in = self.object:get_pos() + local pos_under = vector_new(pos_in.x, pos_in.y - 0.1, pos_in.z) + local on_water, in_air = is_water_is_air(pos_under) + local acc = vector_new(0, 0, 0) + local vel = self.object:getvelocity() + + + if is_water_is_air(pos_in) --if submerged + then + vel = float_up(self, vel) + acc.x, acc.z = handle_control(self, vel) + self.object:setvelocity(vel) + elseif on_water --if on water + then + acc.y, vel = swim(self, vel) + self.object:setvelocity(vel) + acc.x, acc.z = handle_control(self, vel) + elseif in_air + then + --allow controls and height change + acc.y = get_vertical_acceleration(self) + acc.x, acc.z = handle_control(self, vel) + else --if on ground + --only allow height change + acc.y = get_vertical_acceleration(self) + vel.x = 0 + vel.z = 0 + self.object:setvelocity(vel) + end + self.object:setacceleration(acc) +end \ No newline at end of file diff --git a/mods/hot_air_balloons/screenshot.png b/mods/hot_air_balloons/screenshot.png new file mode 100644 index 0000000..f1395b2 Binary files /dev/null and b/mods/hot_air_balloons/screenshot.png differ diff --git a/mods/hot_air_balloons/textures/hot_air_balloons_balloon.png b/mods/hot_air_balloons/textures/hot_air_balloons_balloon.png new file mode 100644 index 0000000..2dec7b1 Binary files /dev/null and b/mods/hot_air_balloons/textures/hot_air_balloons_balloon.png differ diff --git a/mods/hot_air_balloons/textures/hot_air_balloons_balloon_model.png b/mods/hot_air_balloons/textures/hot_air_balloons_balloon_model.png new file mode 100644 index 0000000..6a0a6ba Binary files /dev/null and b/mods/hot_air_balloons/textures/hot_air_balloons_balloon_model.png differ diff --git a/mods/hot_air_balloons/textures/hot_air_balloons_flame.png b/mods/hot_air_balloons/textures/hot_air_balloons_flame.png new file mode 100644 index 0000000..658fbe5 Binary files /dev/null and b/mods/hot_air_balloons/textures/hot_air_balloons_flame.png differ diff --git a/mods/hudbars/API.md b/mods/hudbars/API.md new file mode 100644 index 0000000..ca6144a --- /dev/null +++ b/mods/hudbars/API.md @@ -0,0 +1,210 @@ +API documentation for the HUD bars mod +====================================== + +## Introduction +This API allows you to add, change, hide and unhide custom HUD bars for this mod. + +## Overview +To give you a *very* brief overview over this API, here is the basic workflow on how to add your own custom HUD bar: + +* Create images for your HUD bar +* Call `hb.register_hudbar` to make the definition of the HUD bar known to this mod +* Call `hb.init_hudbar` for each player for which you want to use previously defined HUD bar +* Use `hb.change_hudbar` whenever you need to change the values of a HUD bar of a certain player +* If you need it: Use `hb.hide_hudbar` and `hb.unhide_hudbar` to hide or unhide HUD bars of a certain player + +## The basic rules +In order to use this API, you should be aware of a few basic rules in order to understand it: + +* A HUD bar is an approximate graphical representation of the ratio of a current value and a maximum value, i.e. current health of 15 and maximum health of 20. A full HUD bar represents 100%, an empty HUD bar represents 0%. +* The current value must always be equal to or smaller then the maximum +* Both current value and maximum must not be smaller than 0 +* Both current value and maximum must be real numbers. So no NaN, infinity, etc. +* The HUD bar will be hidden if the maximum equals 0. This is intentional. +* The health and breath HUD bars are hardcoded. + +These are soft rules, the HUD bars mod will not enforce all of these. +But this mod has been programmed under the assumption that these rules are followed, for integrity. + +## Adding a HUD bar +To make a new HUD bar known to this mod, you need … + +* … an image of size 2×16 for the bar +* … an icon of size 16×16 (optional) +* … to register it with `hb.register_hudbar` + +### Bar image +The image for the bar will be repeated horizontally to denote the “value†of the HUD bar. +It **must** be of size 2×16. +If neccessary, the image will be split vertically in half, and only the left half of the image +is displayed. So the final HUD bar will always be displayed on a per-pixel basis. + +The default bar images are single-colored, but you can use other styles as well, for instance, +a vertical gradient. + +### Icon +A 16×16 image shown left of the HUD bar. This is optional. + +### `hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)` +This function registers a new custom HUD bar definition to the HUD bars mod, so it can be later used to be displayed, changed, hidden +and unhidden on a per-player basis. +Note this does not yet display the HUD bar. + +The HUD bars will be displayed in a “first come, first serve†order. This API does not allow fow a custom order or a way to set it +manually in a reliable way. However, you can use the setting `hudbars_sorting` for this. See the advanced setting menu in Minetest +for more information. + + +#### Parameters +* `identifier`: A globally unique internal name for the HUD bar, will be used later to refer to it. Please only rely on alphanumeric characters for now. The identifiers “`health`†and “`breath`†are used internally for the built-in health and breath bar, respectively. Please do not use these names. +* `text_color`: A 3-octet number defining the color of the text. The octets denote, in this order red, green and blue and range from `0x00` (complete lack of this component) to `0xFF` (full intensity of this component). Example: `0xFFFFFF` for white. +* `label`: A string which is displayed on the HUD bar itself to describe the HUD bar. Try to keep this string short. +* `textures`: A table with the following fields: + * `bar`: The file name of the bar image (as string). This is only used for the `progress_bar` bar type (see `README.txt`, settings section). + * `icon`: The file name of the icon, as string. For the `progress_bar` type, it is shown as single image left of the bar, for the two statbar bar types, it is used as the statbar icon and will be repeated. This field can be `nil`, in which case no icon will be used, but this is not recommended, because the HUD bar will be invisible if the one of the statbar bar types is used. + * `bgicon`: The file name of the background icon, it is used as the background for the modern statbar mode only. This field can be `nil`, in which case no background icon will be displayed in this mode. +* `default_start_value`: If this HUD bar is added to a player, and no initial value is specified, this value will be used as initial current value +* `default_max_value`: If this HUD bar is added to a player, and no initial maximum value is specified, this value will be used as initial maximum value +* `default_start_hidden`: The HUD bar will be initially start hidden by default when added to a player. Use `hb.unhide_hudbar` to unhide it. +* `format_string`: Optional; You can specify an alternative format string to use for the final text on the HUD bar. The default format string is “`@1: @2/@3`†(The “@†numbers are placeholders that have a meaning in this order: @1 = Label, @2 = current value, @3 = maximum value). Do *not* use minetest.translator on this string, the string will be translated by `hudbars`, but you still must put this string into the translation catalogue file. +* `format_string_config`: Required if `format_string` is set. This allows to change which parameters to use in the format string. It's a table with these fields: + * `textdomain`: Text domain of the format string, used by `minetest.translate` + * `order`: Table that contains the order of the placeholders. It's also possible to remove placeholders. Default order: `{ "label", "value", "max_value" }` + * `format_value`: Format string to apply when displaying `value`. Syntax is same as in `string.format`. Default: `"%d"` + * `format_max_value`: Same as `format_value` but is applied to `max_value` + +#### Example +Example (mostly) from `hbarmor` mod: + +``` +hb.register_hudbar("armor", 0xFFFFFF, minetest.translator("hbarmor", "Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 100, hbarmor.autohide, N("@1: @2%"), { order = { "label", "value" }, textdomain = "hbarmor" } ) +``` + +Displays an armor HUD bar with a label of the form „Armor: 53%“. (`N` is a dummy function that returns its argument, used to make the string visible for translator scripts.) + +#### Return value +Always `nil`. + + +## Displaying a HUD bar +After a HUD bar has been registered, they are not yet displayed yet for any player. HUD bars must be +explicitly initialized on a per-player basis. + +You probably want to do this in the `minetest.register_on_joinplayer`. + +### `hb.init_hudbar(player, identifier, start_value, start_max, start_hidden)` +This function initialzes and activates a previously registered HUD bar and assigns it to a +certain client/player. This has only to be done once per player and after that, you can change +the values using `hb.change_hudbar`. + +However, if `start_hidden` was set to `true` for the HUD bar (in `hb.register_hudbar`), the HUD bar +will initially be hidden, but the HUD elements are still sent to the client. Otherwise, +the HUD bar will be initially be shown to the player. + +#### Parameters +* `player`: `ObjectRef` of the player to which the new HUD bar should be displayed to. +* `identifier`: The identifier of the HUD bar type, as specified in `hb.register_hudbar`. +* `start_value`: The initial current value of the HUD bar. This is optional, `default_start_value` of the registration function will be used, if this is `nil`. +* `start_max`: The initial maximum value of the HUD bar. This is optional, `default_start_max` of the registration function will be used, if this is `nil` +* `start_hidden`: Whether the HUD bar is initially hidden. This is optional, `default_start_hidden` of the registration function will be used as default + +#### Return value +`true` on success, `false` otherwise. + + +## Modifying a HUD bar +After a HUD bar has been added, you can change the current and maximum value and other attributes on a per-player basis. +You use the function `hb.change_hudbar` for this. + +### `hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon, new_bgicon, new_bar, new_label, new_text_color)` +Changes the values and the appearance of an initialized HUD bar for a certain player. `new_value` +and `new_max_value` are the most important parameters as they specify the new current and maximum new values, you do not need +to worry too much about the other parameters. + +The following parameters are less important and provided for styling the HUD bar after registration (if +this is desired). The “styling†parameters parallel the parameters of `hb.register_hudbar`. It is +recommended to not change the style of a HUD bar too often as this can be distracting or confusing +for players. + +`new_value`, `new_max_value` `new_icon`, `new_bgicon`, `new_bar`, `new_label` and `new_text_color` can be +`nil`; if one of them is `nil`, that means the value is unchanged. If all those values are `nil`, this +function is a no-op. + +This function tries to minimize the amount of calls to `hud_change` of the Minetest Lua API +(and thus, network traffic), when you only change the value and/or maximum value. In this case, +`hud_change` is only called if it is actually needed, e.g. when the actual length of the bar +or the displayed string changed, so you do not have to worry about it. There is, however, no +such network optimization for the “styling†parameters, so keep this in mind. + +#### Parameters +* `player`: `ObjectRef` of the player to which the HUD bar belongs to +* `identifier`: The identifier of the HUD bar type to change, as specified in `hb.register_hudbar`. +* `new_value`: The new current value of the HUD bar +* `new_max_value`: The new maximum value of the HUD bar +* `new_icon`: File name of the new icon +* `new_bgicon`: File name of the new background icon for the modern-style statbar +* `new_bar`: File name of the new bar segment image +* `new_label`: A new text label of the HUD bar. Note the format string still applies +* `new_text_color`: A 3-octet number defining the new color of the text. + +#### Return value +`true` on success, `false` otherwise. + + +## Hiding and unhiding a HUD bar +You can also hide custom HUD bars, meaning they will not be displayed for a certain player. You can still +use `hb.change_hudbar` on a hidden HUD bar, the new values will be correctly displayed after the HUD bar +has been unhidden. Both functions will only call `hud_change` if there has been an actual change to avoid +unneccessary traffic. + +Note that the hidden state of a HUD bar will *not* be saved by this mod on server shutdown, so you may need +to write your own routines for this or by setting the correct value for `start_hidden` when calling +`hb.init_hudbar`. + +### `hb.hide_hudbar(player, identifier)` +Hides the specified HUD bar from the screen of the specified player. + +#### Parameters +* `player`: `ObjectRef` of the player to which the HUD bar belongs to +* `identifier`: The identifier of the HUD bar type to hide, as specified in `hb.register_hudbar`. + +#### Return value +`true` on success, `false` otherwise. + + +### `hb.unhide_hudbar(player, identifier)` +Makes a previously hidden HUD bar visible again to a player. + +#### Parameters +* `player`: `ObjectRef` of the player to which the HUD bar belongs to +* `identifier`: The identifier of the HUD bar type to unhide, as specified in `hb.register_hudbar`. + +#### Return value +`true` on success, `false` otherwise. + + +## Reading HUD bar information +It is also possible to read information about existing HUD bars. + +### `hb.get_hudbar_state(player, identifier)` +Returns the current state of the active player's HUD bar. + +#### Parameters +* `player`: `ObjectRef` of the player to which the HUD bar belongs to +* `identifier`: The identifier of the HUD bar type to hide, as specified in `hb.register_hudbar`. + +#### Return value +On success, returns a table which holds information on the current state of the HUD bar. Note +the table is a deep copy of the internal HUD bar state, it is *not* a reference; the information +hold by the table is only true for the moment you called this function. The fields of this table are: + +* `value`: Current value of HUD bar. +* `max`: Current maximum value of HUD bar. +* `hidden`: Boolean denoting whether the HUD bar is hidden. +* `barlength`: The length of the HUD bar in pixels. This field is meaningless if the HUD bar is currently hidden. +* `text`: The text shown on the HUD bar. This fiels is meaningless if the HUD bar is currently hidden. + +If the player does not exist, returns `nil` instead. + +### `hb.get_hudbar_identifiers()` +Returns a table of all currently registered HUD bar identifiers. diff --git a/mods/hudbars/README.md b/mods/hudbars/README.md new file mode 100644 index 0000000..f83cac8 --- /dev/null +++ b/mods/hudbars/README.md @@ -0,0 +1,25 @@ +# HUD bars + +## Description +This mod changes the HUD of Minetest. It replaces the default health and breath +symbols by horizontal colored bars with text showing the number. + +Furthermore, it enables other mods to add their own custom bars to the HUD, +this mod will place them accordingly. + +**Important**: Keep in mind if running a server with this mod, that the custom +position should be displayed correctly on every screen size. + +## Current version +The current version is 2.1.0. + +This software uses [semantic versioning](http://semver.org), as defined by version 2.0.0 of the SemVer +standard. + +## Settings +This mod can be configured quite a bit. You can change HUD bar appearance, offsets, ordering, and more. +Use the advanced settings menu in Minetest for detailed configuration. + +## API +The API is used to add your own custom HUD bars. +Documentation for the API of this mod can be found in `API.md`. diff --git a/mods/hudbars/default_settings.lua b/mods/hudbars/default_settings.lua new file mode 100644 index 0000000..d2a325b --- /dev/null +++ b/mods/hudbars/default_settings.lua @@ -0,0 +1,48 @@ +-- (Hardcoded) default settings + +hb.settings.max_bar_length = 160 +hb.settings.statbar_length = 20 + +-- Statbar positions +hb.settings.pos_left = {} +hb.settings.pos_right = {} +hb.settings.start_offset_left = {} +hb.settings.start_offset_right= {} +hb.settings.pos_left.x = hb.load_setting("hudbars_pos_left_x", "number", 0.5) +hb.settings.pos_left.y = hb.load_setting("hudbars_pos_left_y", "number", 1) +hb.settings.pos_right.x = hb.load_setting("hudbars_pos_right_x", "number", 0.5) +hb.settings.pos_right.y = hb.load_setting("hudbars_pos_right_y", "number", 1) +hb.settings.bar_type = hb.load_setting("hudbars_bar_type", "string", "progress_bar", {"progress_bar", "statbar_classic", "statbar_modern"}) +if hb.settings.bar_type == "progress_bar" then + hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_offset_left_x", "number", -175) + hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_offset_left_y", "number", -86) + hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15) + hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86) +else + hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -265) + hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_statbar_offset_left_y", "number", -90) + hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 25) + hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_statbar_offset_right_y", "number", -90) +end +hb.settings.vmargin = hb.load_setting("hudbars_vmargin", "number", 24) +hb.settings.tick = hb.load_setting("hudbars_tick", "number", 0.1) + +-- Experimental setting: Changing this setting is not officially supported, do NOT rely on it! +hb.settings.forceload_default_hudbars = hb.load_setting("hudbars_forceload_default_hudbars", "bool", true) + +-- Misc. settings +hb.settings.alignment_pattern = hb.load_setting("hudbars_alignment_pattern", "string", "zigzag", {"zigzag", "stack_up", "stack_down"}) +hb.settings.autohide_breath = hb.load_setting("hudbars_autohide_breath", "bool", true) + +local sorting = minetest.settings:get("hudbars_sorting") +if sorting ~= nil then + hb.settings.sorting = {} + hb.settings.sorting_reverse = {} + for k,v in string.gmatch(sorting, "(%w+)=(%w+)") do + hb.settings.sorting[k] = tonumber(v) + hb.settings.sorting_reverse[tonumber(v)] = k + end +else + hb.settings.sorting = { ["health"] = 0, ["breath"] = 1 } + hb.settings.sorting_reverse = { [0] = "health", [1] = "breath" } +end diff --git a/mods/hudbars/init.lua b/mods/hudbars/init.lua new file mode 100644 index 0000000..0f91960 --- /dev/null +++ b/mods/hudbars/init.lua @@ -0,0 +1,569 @@ +local S = minetest.get_translator("hudbars") +local N = function(s) return s end + +hb = {} + +hb.hudtables = {} + +-- number of registered HUD bars +hb.hudbars_count = 0 + +-- table which records which HUD bar slots have been “registered†so far; used for automatic positioning +hb.registered_slots = {} + +hb.settings = {} + +function hb.load_setting(sname, stype, defaultval, valid_values) + local sval + if stype == "string" then + sval = minetest.settings:get(sname) + elseif stype == "bool" then + sval = minetest.settings:get_bool(sname) + elseif stype == "number" then + sval = tonumber(minetest.settings:get(sname)) + end + if sval ~= nil then + if valid_values ~= nil then + local valid = false + for i=1,#valid_values do + if sval == valid_values[i] then + valid = true + end + end + if not valid then + minetest.log("error", "[hudbars] Invalid value for "..sname.."! Using default value ("..tostring(defaultval)..").") + return defaultval + else + return sval + end + else + return sval + end + else + return defaultval + end +end + +-- Load default settings +dofile(minetest.get_modpath("hudbars").."/default_settings.lua") + +local function player_exists(player) + return player ~= nil and player:is_player() +end + +local function make_label(format_string, format_string_config, label, start_value, max_value) + local params = {} + local order = format_string_config.order + for o=1, #order do + if order[o] == "label" then + table.insert(params, label) + elseif order[o] == "value" then + if format_string_config.format_value then + table.insert(params, string.format(format_string_config.format_value, start_value)) + else + table.insert(params, start_value) + end + elseif order[o] == "max_value" then + if format_string_config.format_max_value then + table.insert(params, string.format(format_string_config.format_max_value, max_value)) + else + table.insert(params, max_value) + end + end + end + local ret + if format_string_config.textdomain then + ret = minetest.translate(format_string_config.textdomain, format_string, unpack(params)) + else + ret = S(format_string, unpack(params)) + end + return ret +end + +-- Table which contains all players with active default HUD bars (only for internal use) +hb.players = {} + +function hb.value_to_barlength(value, max) + if max == 0 then + return 0 + else + if hb.settings.bar_type == "progress_bar" then + local x + if value < 0 then x=-0.5 else x = 0.5 end + local ret = math.modf((value/max) * hb.settings.max_bar_length + x) + return ret + else + local x + if value < 0 then x=-0.5 else x = 0.5 end + local ret = math.modf((value/max) * hb.settings.statbar_length + x) + return ret + end + end +end + +function hb.get_hudtable(identifier) + return hb.hudtables[identifier] +end + +function hb.get_hudbar_position_index(identifier) + if hb.settings.sorting[identifier] ~= nil then + return hb.settings.sorting[identifier] + else + local i = 0 + while true do + if hb.registered_slots[i] ~= true and hb.settings.sorting_reverse[i] == nil then + return i + end + i = i + 1 + end + end +end + +function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config) + minetest.log("action", "hb.register_hudbar: "..tostring(identifier)) + local hudtable = {} + local pos, offset + local index = math.floor(hb.get_hudbar_position_index(identifier)) + hb.registered_slots[index] = true + if hb.settings.alignment_pattern == "stack_up" then + pos = hb.settings.pos_left + offset = { + x = hb.settings.start_offset_left.x, + y = hb.settings.start_offset_left.y - hb.settings.vmargin * index + } + elseif hb.settings.alignment_pattern == "stack_down" then + pos = hb.settings.pos_left + offset = { + x = hb.settings.start_offset_left.x, + y = hb.settings.start_offset_left.y + hb.settings.vmargin * index + } + else + if index % 2 == 0 then + pos = hb.settings.pos_left + offset = { + x = hb.settings.start_offset_left.x, + y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2) + } + else + pos = hb.settings.pos_right + offset = { + x = hb.settings.start_offset_right.x, + y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2) + } + end + end + if format_string == nil then + format_string = N("@1: @2/@3") + end + if format_string_config == nil then + format_string_config = {} + end + if format_string_config.order == nil then + format_string_config.order = { "label", "value", "max_value" } + end + if format_string_config.format_value == nil then + format_string_config.format_value = "%d" + end + if format_string_config.format_max_value == nil then + format_string_config.format_max_value = "%d" + end + + hudtable.add_all = function(player, hudtable, start_value, start_max, start_hidden) + if start_value == nil then start_value = hudtable.default_start_value end + if start_max == nil then start_max = hudtable.default_start_max end + if start_hidden == nil then start_hidden = hudtable.default_start_hidden end + local ids = {} + local state = {} + local name = player:get_player_name() + local bgscale, iconscale, text, barnumber, bgiconnumber + if start_max == 0 or start_hidden then + bgscale = { x=0, y=0 } + else + bgscale = { x=1, y=1 } + end + if start_hidden then + iconscale = { x=0, y=0 } + barnumber = 0 + bgiconnumber = 0 + text = "" + else + iconscale = { x=1, y=1 } + barnumber = hb.value_to_barlength(start_value, start_max) + bgiconnumber = hb.settings.statbar_length + text = make_label(format_string, format_string_config, label, start_value, start_max) + end + if hb.settings.bar_type == "progress_bar" then + ids.bg = player:hud_add({ + hud_elem_type = "image", + position = pos, + scale = bgscale, + text = "hudbars_bar_background.png", + alignment = {x=1,y=1}, + offset = { x = offset.x - 1, y = offset.y - 1 }, + }) + if textures.icon ~= nil then + ids.icon = player:hud_add({ + hud_elem_type = "image", + position = pos, + scale = iconscale, + text = textures.icon, + alignment = {x=-1,y=1}, + offset = { x = offset.x - 3, y = offset.y }, + }) + end + elseif hb.settings.bar_type == "statbar_modern" then + if textures.bgicon ~= nil then + ids.bg = player:hud_add({ + hud_elem_type = "statbar", + position = pos, + text = textures.bgicon, + number = bgiconnumber, + alignment = {x=-1,y=-1}, + offset = { x = offset.x, y = offset.y }, + direction = 0, + size = {x=24, y=24}, + }) + end + end + local bar_image, bar_size + if hb.settings.bar_type == "progress_bar" then + bar_image = textures.bar + -- NOTE: Intentionally set to nil. For some reason, on some systems, + -- the progress bar is displaced when the bar_size is set explicitly here. + -- On the other hand, setting this to nil is deprecated in MT 5.0.0 due to + -- a debug log warning, but nothing is explained in lua_api.txt. + -- This section is a potential bug magnet, please watch with care! + -- The size of the bar image is expected to be exactly 2×16 pixels. + bar_size = nil + elseif hb.settings.bar_type == "statbar_classic" or hb.settings.bar_type == "statbar_modern" then + bar_image = textures.icon + bar_size = {x=24, y=24} + end + ids.bar = player:hud_add({ + hud_elem_type = "statbar", + position = pos, + text = bar_image, + number = barnumber, + alignment = {x=-1,y=-1}, + offset = offset, + direction = 0, + size = bar_size, + }) + if hb.settings.bar_type == "progress_bar" then + ids.text = player:hud_add({ + hud_elem_type = "text", + position = pos, + text = text, + alignment = {x=1,y=1}, + number = text_color, + direction = 0, + offset = { x = offset.x + 2, y = offset.y - 1}, + }) + end + -- Do not forget to update hb.get_hudbar_state if you add new fields to the state table + state.hidden = start_hidden + state.value = start_value + state.max = start_max + state.text = text + state.barlength = hb.value_to_barlength(start_value, start_max) + + local main_error_text = + "[hudbars] Bad initial values of HUD bar identifier “"..tostring(identifier).."†for player "..name..". " + + if start_max < start_value then + minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than start_value ("..start_value..")!") + end + if start_max < 0 then + minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than 0!") + end + if start_value < 0 then + minetest.log("error", main_error_text.."start_value ("..start_value..") is smaller than 0!") + end + + hb.hudtables[identifier].hudids[name] = ids + hb.hudtables[identifier].hudstate[name] = state + end + + hudtable.identifier = identifier + hudtable.format_string = format_string + hudtable.format_string_config = format_string_config + hudtable.label = label + hudtable.hudids = {} + hudtable.hudstate = {} + hudtable.default_start_hidden = default_start_hidden + hudtable.default_start_value = default_start_value + hudtable.default_start_max = default_start_max + + hb.hudbars_count= hb.hudbars_count + 1 + + hb.hudtables[identifier] = hudtable +end + +function hb.init_hudbar(player, identifier, start_value, start_max, start_hidden) + if not player_exists(player) then return false end + local hudtable = hb.get_hudtable(identifier) + hb.hudtables[identifier].add_all(player, hudtable, start_value, start_max, start_hidden) + return true +end + +function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon, new_bgicon, new_bar, new_label, new_text_color) + if new_value == nil and new_max_value == nil and new_icon == nil and new_bgicon == nil and new_bar == nil and new_label == nil and new_text_color == nil then + return true + end + if not player_exists(player) then + return false + end + + local name = player:get_player_name() + local hudtable = hb.get_hudtable(identifier) + local value_changed, max_changed = false, false + + if new_value ~= nil then + if new_value ~= hudtable.hudstate[name].value then + hudtable.hudstate[name].value = new_value + value_changed = true + end + else + new_value = hudtable.hudstate[name].value + end + if new_max_value ~= nil then + if new_max_value ~= hudtable.hudstate[name].max then + hudtable.hudstate[name].max = new_max_value + max_changed = true + end + else + new_max_value = hudtable.hudstate[name].max + end + + if hb.settings.bar_type == "progress_bar" then + if new_icon ~= nil and hudtable.hudids[name].icon ~= nil then + player:hud_change(hudtable.hudids[name].icon, "text", new_icon) + end + if new_bgicon ~= nil and hudtable.hudids[name].bgicon ~= nil then + player:hud_change(hudtable.hudids[name].bgicon, "text", new_bgicon) + end + if new_bar ~= nil then + player:hud_change(hudtable.hudids[name].bar , "text", new_bar) + end + if new_label ~= nil then + hudtable.label = new_label + local new_text = make_label(hudtable.format_string, hudtable.format_string_config, new_label, hudtable.hudstate[name].value, hudtable.hudstate[name].max) + player:hud_change(hudtable.hudids[name].text, "text", new_text) + end + if new_text_color ~= nil then + player:hud_change(hudtable.hudids[name].text, "number", new_text_color) + end + else + if new_icon ~= nil and hudtable.hudids[name].bar ~= nil then + player:hud_change(hudtable.hudids[name].bar, "text", new_icon) + end + if new_bgicon ~= nil and hudtable.hudids[name].bg ~= nil then + player:hud_change(hudtable.hudids[name].bg, "text", new_bgicon) + end + end + + local main_error_text = + "[hudbars] Bad call to hb.change_hudbar, identifier: “"..tostring(identifier).."â€, player name: “"..name.."â€. " + if new_max_value < new_value then + minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than new_value ("..new_value..")!") + end + if new_max_value < 0 then + minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than 0!") + end + if new_value < 0 then + minetest.log("error", main_error_text.."new_value ("..new_value..") is smaller than 0!") + end + + if hudtable.hudstate[name].hidden == false then + if max_changed and hb.settings.bar_type == "progress_bar" then + if hudtable.hudstate[name].max == 0 then + player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0}) + else + player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1}) + end + end + + if value_changed or max_changed then + local new_barlength = hb.value_to_barlength(new_value, new_max_value) + if new_barlength ~= hudtable.hudstate[name].barlength then + player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(new_value, new_max_value)) + hudtable.hudstate[name].barlength = new_barlength + end + + if hb.settings.bar_type == "progress_bar" then + local new_text = make_label(hudtable.format_string, hudtable.format_string_config, hudtable.label, new_value, new_max_value) + if new_text ~= hudtable.hudstate[name].text then + player:hud_change(hudtable.hudids[name].text, "text", new_text) + hudtable.hudstate[name].text = new_text + end + end + end + end + return true +end + +function hb.hide_hudbar(player, identifier) + if not player_exists(player) then return false end + local name = player:get_player_name() + local hudtable = hb.get_hudtable(identifier) + if hudtable == nil then return false end + if hb.settings.bar_type == "progress_bar" then + if hudtable.hudids[name].icon ~= nil then + player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0}) + end + player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0}) + player:hud_change(hudtable.hudids[name].text, "text", "") + elseif hb.settings.bar_type == "statbar_modern" then + player:hud_change(hudtable.hudids[name].bg, "number", 0) + end + player:hud_change(hudtable.hudids[name].bar, "number", 0) + hudtable.hudstate[name].hidden = true + return true +end + +function hb.unhide_hudbar(player, identifier) + if not player_exists(player) then return false end + local name = player:get_player_name() + local hudtable = hb.get_hudtable(identifier) + if hudtable == nil then return false end + local value = hudtable.hudstate[name].value + local max = hudtable.hudstate[name].max + if hb.settings.bar_type == "progress_bar" then + if hudtable.hudids[name].icon ~= nil then + player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1}) + end + if hudtable.hudstate[name].max ~= 0 then + player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1}) + end + player:hud_change(hudtable.hudids[name].text, "text", make_label(hudtable.format_string, hudtable.format_string_config, hudtable.label, value, max)) + elseif hb.settings.bar_type == "statbar_modern" then + player:hud_change(hudtable.hudids[name].bg, "number", hb.settings.statbar_length) + end + player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(value, max)) + hudtable.hudstate[name].hidden = false + return true +end + +function hb.get_hudbar_state(player, identifier) + if not player_exists(player) then return nil end + local ref = hb.get_hudtable(identifier).hudstate[player:get_player_name()] + -- Do not forget to update this chunk of code in case the state changes + local copy = { + hidden = ref.hidden, + value = ref.value, + max = ref.max, + text = ref.text, + barlength = ref.barlength, + } + return copy +end + +function hb.get_hudbar_identifiers() + local ids = {} + for id, _ in pairs(hb.hudtables) do + table.insert(ids, id) + end + return ids +end + +--register built-in HUD bars +if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then + hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 20, 20, false) + hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 10, 10, true) +end + +local function hide_builtin(player) + local flags = player:hud_get_flags() + flags.healthbar = false + flags.breathbar = false + player:hud_set_flags(flags) +end + + +local function custom_hud(player) + if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then + local hide + if minetest.settings:get_bool("enable_damage") then + hide = false + else + hide = true + end + local hp = player:get_hp() + local hp_max = player:get_properties().hp_max + hb.init_hudbar(player, "health", math.min(hp, hp_max), hp_max, hide) + local breath = player:get_breath() + local breath_max = player:get_properties().breath_max + local hide_breath + if breath >= breath_max and hb.settings.autohide_breath == true then hide_breath = true else hide_breath = false end + hb.init_hudbar(player, "breath", math.min(breath, breath_max-1), breath_max-1, hide_breath or hide) + end +end + +local function update_health(player) + local hp_max = player:get_properties().hp_max + hb.change_hudbar(player, "health", player:get_hp(), hp_max) +end + +-- update built-in HUD bars +local function update_hud(player) + if not player_exists(player) then return end + if minetest.settings:get_bool("enable_damage") then + if hb.settings.forceload_default_hudbars then + hb.unhide_hudbar(player, "health") + end + --air + local breath_max = player:get_properties().breath_max + local breath = player:get_breath() + + if breath >= breath_max and hb.settings.autohide_breath == true then + hb.hide_hudbar(player, "breath") + else + hb.unhide_hudbar(player, "breath") + hb.change_hudbar(player, "breath", math.min(breath, breath_max-1), breath_max-1) + end + --health + update_health(player) + elseif hb.settings.forceload_default_hudbars then + hb.hide_hudbar(player, "health") + hb.hide_hudbar(player, "breath") + end +end + +minetest.register_on_player_hpchange(function(player) + if hb.players[player:get_player_name()] ~= nil then + update_health(player) + end +end) + +minetest.register_on_respawnplayer(function(player) + update_health(player) + hb.hide_hudbar(player, "breath") +end) + +minetest.register_on_joinplayer(function(player) + hide_builtin(player) + custom_hud(player) + hb.players[player:get_player_name()] = player +end) + +minetest.register_on_leaveplayer(function(player) + hb.players[player:get_player_name()] = nil +end) + +local main_timer = 0 +local timer = 0 +minetest.register_globalstep(function(dtime) + main_timer = main_timer + dtime + timer = timer + dtime + if main_timer > hb.settings.tick or timer > 4 then + if main_timer > hb.settings.tick then main_timer = 0 end + -- only proceed if damage is enabled + if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then + for _, player in pairs(hb.players) do + -- update all hud elements + update_hud(player) + end + end + end + if timer > 4 then timer = 0 end +end) diff --git a/mods/hudbars/license.txt b/mods/hudbars/license.txt new file mode 100644 index 0000000..6630503 --- /dev/null +++ b/mods/hudbars/license.txt @@ -0,0 +1,34 @@ +## Legal +### License of source code +Author: Wuzzy (2015) + +Also: This mod was forked from the “Better HUD†[hud] mod by BlockMen. + +Translations: + +* German: Wuzzy +* Portuguese: BrunoMine +* Turkish: admicos +* Dutch: kingoscargames +* Italian: Hamlet +* Malay: muhdnurhidayat +* Russian: Imk + +This program is free software. It comes without any warranty, to +the extent permitted by applicable law. You can redistribute it +and/or modify it under the terms of the MIT License. + +### Licenses of textures + +* `hudbars_icon_health.png`—celeron55 (CC BY-SA 3.0), modified by BlockMen +* `hudbars_bgicon_health.png`—celeron55 (CC BY-SA 3.0), modified by BlockMen +* `hudbars_icon_breath.png`—kaeza (MIT License), modified by BlockMen, modified again by Wuzzy +* `hudbars_bgicon_breath.png`—based on previous image, edited by Wuzzy (MIT License) +* `hudbars_bar_health.png`—Wuzzy (MIT License) +* `hudbars_bar_breath.png`—Wuzzy (MIT License) +* `hudbars_bar_background.png`—Wuzzy (MIT License) + +### License references + +* [CC-BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/) +* [MIT License](https://opensource.org/licenses/MIT) diff --git a/mods/hudbars/locale/hudbars.de.tr b/mods/hudbars/locale/hudbars.de.tr new file mode 100644 index 0000000..3d1e697 --- /dev/null +++ b/mods/hudbars/locale/hudbars.de.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=Leben +Breath=Atem +@1: @2/@3=@1: @2/@3 diff --git a/mods/hudbars/locale/hudbars.it.tr b/mods/hudbars/locale/hudbars.it.tr new file mode 100644 index 0000000..3ada5b6 --- /dev/null +++ b/mods/hudbars/locale/hudbars.it.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=Salute +Breath=Ossigeno + +# Default format string for progress bar-style HUD bars, e.g. “Health 5/20†+@1: @2/@3=@1: @2/@3 diff --git a/mods/hudbars/locale/hudbars.ms.tr b/mods/hudbars/locale/hudbars.ms.tr new file mode 100644 index 0000000..eb811ab --- /dev/null +++ b/mods/hudbars/locale/hudbars.ms.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=Kesihatan +Breath=Nafas +@1: @2/@3=@1: @2/@3 diff --git a/mods/hudbars/locale/hudbars.nl.tr b/mods/hudbars/locale/hudbars.nl.tr new file mode 100644 index 0000000..b9c4a41 --- /dev/null +++ b/mods/hudbars/locale/hudbars.nl.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=Gezondheid +Breath=Adem + +# Default format string for progress bar-style HUD bars, e.g. “Health 5/20†+@1: @2/@3=@1: @2/@3 diff --git a/mods/hudbars/locale/hudbars.pt.tr b/mods/hudbars/locale/hudbars.pt.tr new file mode 100644 index 0000000..a818f09 --- /dev/null +++ b/mods/hudbars/locale/hudbars.pt.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=Saude +Breath=Folego + +# Formato de string padrão para progresso bar-style de barras do HUD, por exemplo “Saude 5/20†+@1: @2/@3=@1: @2/@3 diff --git a/mods/hudbars/locale/hudbars.ru.tr b/mods/hudbars/locale/hudbars.ru.tr new file mode 100644 index 0000000..2d278e3 --- /dev/null +++ b/mods/hudbars/locale/hudbars.ru.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=HP +Breath=дыхание +@1: @2/@3=@1: @2/@3 diff --git a/mods/hudbars/locale/hudbars.tr.tr b/mods/hudbars/locale/hudbars.tr.tr new file mode 100644 index 0000000..6a2ce0b --- /dev/null +++ b/mods/hudbars/locale/hudbars.tr.tr @@ -0,0 +1,4 @@ +# textdomain: hudbars +Health=Can +Breath=Nefes +@1: @2/@3=@1: @2/@3 diff --git a/mods/hudbars/locale/template.txt b/mods/hudbars/locale/template.txt new file mode 100644 index 0000000..37b0559 --- /dev/null +++ b/mods/hudbars/locale/template.txt @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health= +Breath= + +# Default format string for progress bar-style HUD bars, e.g. “Health 5/20†+@1: @2/@3= diff --git a/mods/hudbars/mod.conf b/mods/hudbars/mod.conf new file mode 100644 index 0000000..5fa238a --- /dev/null +++ b/mods/hudbars/mod.conf @@ -0,0 +1,2 @@ +name = hudbars +description = Replaces the health and breath symbols in the HUD by “progress bars†and shows exact values. Other mods can add more progress bars for custom player stats. diff --git a/mods/hudbars/settingtypes.txt b/mods/hudbars/settingtypes.txt new file mode 100644 index 0000000..3e4390e --- /dev/null +++ b/mods/hudbars/settingtypes.txt @@ -0,0 +1,119 @@ +[Appearance] +# Specifies how the value indicators (i.e. health, breah, etc.) look. There are 3 styles +# available. You can choose between the default progress-bar-like bars and the good +# old statbars like you know from vanilla Minetest. +# These values are possible: +# - progress_bar: A horizontal progress-bar-like bar with a label, showing numerical value +# (current, maximum), and an icon. These bars usually convey the most +# information. This is the default and recommended value. +# - statbar_classic: Classic statbar, like in vanilla Minetest. Made out of up to 20 +# half-symbols. Those bars represent the vague ratio between +# the current value and the maximum value. 1 half-symbol stands for +# approximately 5% of the maximum value. +# - statbar_modern: Like the classic statbar, but also supports background images, this +# kind of statbar may be considered to be more user-friendly than the +# classic statbar. This bar type closely resembles the mod +# “Better HUD†[hud] by BlockMen. +hudbars_bar_type (HUD bars style) enum progress_bar progress_bar,statbar_classic,statbar_modern + + +# If enabled (default), the breath indicators in the HUD will be automatically hidden shortly +# after the breath has been filled up. Otherwise, the breath will always be displayed. +hudbars_autohide_breath (Automatically hide breath indicators) bool true + +# This setting changes the way the HUD bars are ordered on the display. You can choose +# between a zig-zag pattern (default) or a vertically stacked pattern. +# The following values are allowed: +# - zigzag: Starting from the left bottom, the next is right from the first, +# the next is above the first, the next is right of the third, etc. +# - stack_up: The HUD bars are stacked vertically, going upwards. +# - stack_down: The HUD bars are stacked vertically, going downwards. +hudbars_alignment_pattern (HUD bars alignment pattern) enum zigzag zigzag,stack_up,stack_down + +# This setting allows you to specify the order of the HUD bars explicitly. If left empty +# (the default), the health and breath indicators come first, additional indicators +# may appear in any order. This setting is quite technical and normal users probably do not +# need to worry about it. +# +# Syntax: +# The setting has to be specified as a comma-seperated list of key=value pairs, where a key +# refers to the identifier of a HUD bar and the value refers to the slot number of where the +# HUD bar should be placed. The slot number must be an integer greater of equal to 0. Where +# the HUD bars will be displayed exactly depends on the alignment pattern being used. +# All HUD bars to which no order value has been applied will fill in all slots which have +# not been occupied by the HUD bars specified in this setting, the slots will be filled in +# from the lowest slot number. +# Note that the order of those remaining HUD bars is not fixed, it basically just boils +# down on which mod “came†first. Don't worry, the mod will still work perfectly fine, this +# setting is entirely optional. +# The identifier for the health bar is “health†and the identifier for the breath bar is +# “breathâ€. For other HUD bars, you have to learn it from the mod which is supplying them. +# +# Be careful not to use slot indices twice, or else different HUD bars will be drawn over +# each other! +# +# Example: “breath=0, health=1†+# This makes the breath bar first and the health bar second, which is the opposite order +# of the default one. +hudbars_sorting (HUD bars order) string + +[Positions and offsets] +# Horizontal (x) main position of the HUD bars over the entire screen. +# 0.0 is left-most, 1.0 is right-most. +# For the zig-zag alignment pattern, this is for the left HUD bars. +hudbars_pos_left_x (Left HUD bar screen x position) float 0.5 0.0 1.0 +# Vertical (y) main position of the HUD bars over the entire screen. +# 0.0 is top, 1.0 is bottom. +# For the zig-zag alignment pattern, this is for the left HUD bars. +hudbars_pos_left_y (Left HUD bar screen y position) float 1.0 0.0 1.0 +# Horizontal (x) main position of the right HUD bars over the entire screen. +# 0.0 is left-most, 1.0 is right-most. +# Only used for the zig-zag alignment pattern. +hudbars_pos_right_x (Right HUD bar screen x position) float 0.5 0.0 1.0 +# Vertical main position (y) of the right HUD bars over the entire screen. +# 0.0 is top, 1.0 is bottom. +# Only used for the zig-zag alignment pattern. +hudbars_pos_right_y (Right HUD bar screen y position) float 1.0 0.0 1.0 + +# Precise x offset in pixels from the basic screen x position of the HUD bars. +# For the zig-zag alignment pattern, this is for the left HUD bars. +# This setting is used for the progress bar HUD bar style. +hudbars_start_offset_left_x (Left HUD bar x offset) int -175 +# Precise y offset in pixels from the basic screen y position of the HUD bars. +# For the zig-zag alignment pattern, this is for the left HUD bars. +# This setting is used for the progress bar HUD bar style. +hudbars_start_offset_left_y (Left HUD bar y offset) int -86 +# Precise x offset in pixels from the basic screen x position of the right HUD bars. +# Only used for the zig-zag alignment pattern. +# This setting is used for the progress bar HUD bar style. +hudbars_start_offset_right_x (Right HUD bar x offset) int 15 +# Precise y offset in pixels from the basic screen y position of the right HUD bars. +# Only used for the zig-zag alignment pattern. +# This setting is used for the progress bar HUD bar style. +hudbars_start_offset_right_y (Right HUD bar y offset) int -86 + +# Precise x offset in pixels from the basic screen x position of the HUD statbars. +# For the zig-zag alignment pattern, this is for the left HUD statbars. +# This setting is used for the classic and modern statbar styles. +hudbars_start_statbar_offset_left_x (Left HUD statbar x offset) int -265 +# Precise y offset in pixels from the basic screen y position of the HUD statbars. +# For the zig-zag alignment pattern, this is for the left HUD statbars. +# This setting is used for the classic and modern statbar styles. +hudbars_start_statbar_offset_left_y (Left HUD statbar y offset) int -90 +# Precise x offset in pixels from the basic screen x position of the right HUD statbars. +# Only used for the zig-zag alignment pattern. +# This setting is used for the classic and modern statbar styles. +hudbars_start_statbar_offset_right_x (Right HUD statbar x offset) int 25 +# Precise y offset in pixels from the basic screen y position of the right HUD statbars. +# Only used for the zig-zag alignment pattern. +# This setting is used for the classic and modern statbar styles. +hudbars_start_statbar_offset_right_y (Right HUD statbar y offset) int -90 + +# The vertical distance between two HUD bars, in pixels. +hudbars_vmargin (Vertical distance between HUD bars) int 24 0 + +[Performance] +# The of seconds which need to pass before the server updates the default HUD bars +# (health and breath). Increase this number if you have a slow server or a slow network +# connection and experience performance problems. +hudbars_tick (Default HUD bars update interval) float 0.1 0.0 4.0 diff --git a/mods/hudbars/textures/hudbars_bar_background.png b/mods/hudbars/textures/hudbars_bar_background.png new file mode 100644 index 0000000..cbc6c3f Binary files /dev/null and b/mods/hudbars/textures/hudbars_bar_background.png differ diff --git a/mods/hudbars/textures/hudbars_bar_breath.png b/mods/hudbars/textures/hudbars_bar_breath.png new file mode 100644 index 0000000..7d19a57 Binary files /dev/null and b/mods/hudbars/textures/hudbars_bar_breath.png differ diff --git a/mods/hudbars/textures/hudbars_bar_health.png b/mods/hudbars/textures/hudbars_bar_health.png new file mode 100644 index 0000000..6530916 Binary files /dev/null and b/mods/hudbars/textures/hudbars_bar_health.png differ diff --git a/mods/hudbars/textures/hudbars_bgicon_breath.png b/mods/hudbars/textures/hudbars_bgicon_breath.png new file mode 100644 index 0000000..176629a Binary files /dev/null and b/mods/hudbars/textures/hudbars_bgicon_breath.png differ diff --git a/mods/hudbars/textures/hudbars_bgicon_health.png b/mods/hudbars/textures/hudbars_bgicon_health.png new file mode 100644 index 0000000..e2be276 Binary files /dev/null and b/mods/hudbars/textures/hudbars_bgicon_health.png differ diff --git a/mods/hudbars/textures/hudbars_icon_breath.png b/mods/hudbars/textures/hudbars_icon_breath.png new file mode 100644 index 0000000..d1a5bcc Binary files /dev/null and b/mods/hudbars/textures/hudbars_icon_breath.png differ diff --git a/mods/hudbars/textures/hudbars_icon_health.png b/mods/hudbars/textures/hudbars_icon_health.png new file mode 100644 index 0000000..941e973 Binary files /dev/null and b/mods/hudbars/textures/hudbars_icon_health.png differ diff --git a/mods/jail/init.lua b/mods/jail/init.lua new file mode 100644 index 0000000..df1bb65 --- /dev/null +++ b/mods/jail/init.lua @@ -0,0 +1,77 @@ +jail = {} +local storage = minetest.get_mod_storage() + +function release_prisoners(name) + local player = minetest.get_player_by_name(name) + if not player then + return + end + minetest.chat_send_player(name, ' We hope you enjoyed your stay.') + minetest.set_player_privs(name, {shout=true, home=true}) + player:setpos({x=2555, y=2002, z=4442}) + minetest.log('action', name..' was freed from jail') + storage:set_string(name, '') + storage:set_string(name..'_length', '') + minetest.show_formspec(name, 'rules', spawn_rules_formspec) +end + +minetest.register_privilege('warden', { + description = 'Can send people to jail', + give_to_singleplayer = false +}) + +minetest.register_chatcommand('release', { + params = '', + privs = {warden=true}, + func = function(warden, name) + release_prisoners(name) + end, +}) + +minetest.register_chatcommand('jail', { + params = ' [