diff --git a/basic_materials/.github/workflows/luacheck.yml b/basic_materials/.github/workflows/luacheck.yml new file mode 100644 index 0000000..a13efa9 --- /dev/null +++ b/basic_materials/.github/workflows/luacheck.yml @@ -0,0 +1,13 @@ +name: luacheck +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: apt + run: sudo apt-get install -y luarocks + - name: luacheck install + run: luarocks install --local luacheck + - name: luacheck run + run: $HOME/.luarocks/bin/luacheck ./ diff --git a/basic_materials/.luacheckrc b/basic_materials/.luacheckrc new file mode 100644 index 0000000..55879b0 --- /dev/null +++ b/basic_materials/.luacheckrc @@ -0,0 +1,30 @@ +std = "lua51+minetest" +unused_args = false +allow_defined_top = true +max_line_length = 999 + +stds.minetest = { + read_globals = { + "DIR_DELIM", + "minetest", + "core", + "dump", + "vector", + "nodeupdate", + "VoxelManip", + "VoxelArea", + "PseudoRandom", + "ItemStack", + "default", + table = { + fields = { + "copy", + }, + }, + } +} + +read_globals = { + "default", + "moreores", +} diff --git a/basic_materials/LICENSE b/basic_materials/LICENSE new file mode 100644 index 0000000..c5885ae --- /dev/null +++ b/basic_materials/LICENSE @@ -0,0 +1,600 @@ +License for code: LGPL 3.0 +License for media and all other assets: CC-by-SA 4.0 + +############################################################################### + + GNU LESSER 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. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +############################################################################### + +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/basic_materials/electrical-electronic.lua b/basic_materials/electrical-electronic.lua new file mode 100644 index 0000000..91fac4e --- /dev/null +++ b/basic_materials/electrical-electronic.lua @@ -0,0 +1,86 @@ +-- Translation support +local S = minetest.get_translator("basic_materials") + +-- items + +minetest.register_craftitem("basic_materials:silicon", { + description = S("Silicon lump"), + inventory_image = "basic_materials_silicon.png", +}) + +minetest.register_craftitem("basic_materials:ic", { + description = S("Simple Integrated Circuit"), + inventory_image = "basic_materials_ic.png", +}) + +minetest.register_craftitem("basic_materials:motor", { + description = S("Simple Motor"), + inventory_image = "basic_materials_motor.png", +}) + +minetest.register_craftitem("basic_materials:heating_element", { + description = S("Heating element"), + inventory_image = "basic_materials_heating_element.png", +}) + +minetest.register_craftitem("basic_materials:energy_crystal_simple", { + description = S("Simple energy crystal"), + inventory_image = "basic_materials_energy_crystal.png", +}) + +-- crafts + +minetest.register_craft( { + output = "mesecons_materials:silicon 4", + recipe = { + { "default:sand", "default:sand" }, + { "default:sand", "default:steel_ingot" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:ic 4", + recipe = { + { "mesecons_materials:silicon", "mesecons_materials:silicon" }, + { "mesecons_materials:silicon", "default:copper_ingot" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:motor 2", + recipe = { + { "default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet" }, + { "default:copper_ingot", "default:steel_ingot", "default:steel_ingot" }, + { "default:mese_crystal_fragment", "basic_materials:copper_wire", "basic_materials:plastic_sheet" } + }, + replacements = { + { "basic_materials:copper_wire", "basic_materials:empty_spool" }, + { "basic_materials:copper_wire", "basic_materials:empty_spool" }, + } +}) + +minetest.register_craft( { + output = "basic_materials:heating_element 2", + recipe = { + { "default:copper_ingot", "default:mese_crystal_fragment", "default:copper_ingot" } + }, +}) + +minetest.register_craft({ + --type = "shapeless", + output = "basic_materials:energy_crystal_simple 2", + recipe = { + { "default:mese_crystal_fragment", "default:torch", "default:mese_crystal_fragment" }, + { "default:diamond", "default:gold_ingot", "default:diamond" } + }, +}) + +-- aliases + +minetest.register_alias("homedecor:ic", "basic_materials:ic") +minetest.register_alias("homedecor:motor", "basic_materials:motor") +minetest.register_alias("technic:motor", "basic_materials:motor") +minetest.register_alias("homedecor:heating_element", "basic_materials:heating_element") +minetest.register_alias("homedecor:power_crystal", "basic_materials:energy_crystal_simple") + +minetest.register_alias_force("mesecons_materials:silicon", "basic_materials:silicon") diff --git a/basic_materials/init.lua b/basic_materials/init.lua new file mode 100644 index 0000000..348c059 --- /dev/null +++ b/basic_materials/init.lua @@ -0,0 +1,15 @@ +-- Basic materials mod +-- by Vanessa Dannenberg + +-- This mod supplies all those little random craft items that everyone always +-- seems to need, such as metal bars (ala rebar), plastic, wire, and so on. + +local modpath = minetest.get_modpath("basic_materials") + +basic_materials = {} +basic_materials.mod = { author = "Vanessa Dannenberg" } + +dofile(modpath.."/metals.lua") +dofile(modpath.."/plastics.lua") +dofile(modpath.."/electrical-electronic.lua") +dofile(modpath.."/misc.lua") diff --git a/basic_materials/locale/basic_materials.de.tr b/basic_materials/locale/basic_materials.de.tr new file mode 100644 index 0000000..8fddd8a --- /dev/null +++ b/basic_materials/locale/basic_materials.de.tr @@ -0,0 +1,33 @@ +# textdomain: basic_materials +Silicon lump=Siliziumklumpen +Simple Integrated Circuit=Einfacher Integrierter Schaltkreis +Simple Motor=Einfacher Motor +Heating element=Heizelement +Simple energy crystal=Einfacher Energiekristall + +Spool of steel wire=Spule mit Stahldraht +Spool of copper wire=Spule mit Kupferdraht +Spool of silver wire=Spule mit Silberdraht +Spool of gold wire=Spule mit Golddraht +Steel Strip=Stahlstreifen +Copper Strip=Kupferstreifen +Steel Bar=Stahlstab +Chainlinks (brass)=Messingkettenglieder +Chainlinks (steel)=Stahlkettenglieder +Brass Ingot=Messingbarren +Steel gear=Stahlzahnrad +Padlock=Vorhängeschloss +Chain (steel, hanging)=Hängende Stahlkette +Chain (brass, hanging)=Hängende Messingkette +Brass Block=Messingblock + +Oil extract=Ölextrakt +Unprocessed paraffin=Unverarbeitetes Paraffin +Uncooked Terracotta Base=Ungebranntes Terrakotta +Wet Cement=Nasser Zement +Cement=Zement +Concrete Block=Betonblock + +Plastic sheet=Kunststoffplatte +Plastic strips=Kunststoffstreifen +Empty wire spool=Leere Drahtspule diff --git a/basic_materials/locale/basic_materials.fr.tr b/basic_materials/locale/basic_materials.fr.tr new file mode 100644 index 0000000..0bebf79 --- /dev/null +++ b/basic_materials/locale/basic_materials.fr.tr @@ -0,0 +1,33 @@ +# textdomain: basic_materials +Silicon lump=Morceau de silicium +Simple Integrated Circuit=Circuit intégré simple +Simple Motor=Moteur simple +Heating element=Élément chauffant +Simple energy crystal=Cristal d’énergie simple + +Spool of steel wire=Bobine de fil d’acier +Spool of copper wire=Bobine de fil de cuivre +Spool of silver wire=Bobine de fil d’argent +Spool of gold wire=Bobine de fil d’or +Steel Strip=Bande de acier +Copper Strip=Bande de cuivre +Steel Bar=Barre d’acier +Chainlinks (brass)=Maillon en laiton +Chainlinks (steel)=Maillon en acier +Brass Ingot=Lingot de laiton +Steel gear=Rouage en acier +Padlock=Cadenas +Chain (steel, hanging)=Chaine en acier +Chain (brass, hanging)=Chaine en laiton +Brass Block=Bloc de laiton + +Oil extract=Extrait d’huile +Unprocessed paraffin=Paraffine non transformée +Uncooked Terracotta Base=Argile crue +Wet Cement=Ciment humide +Cement=Ciment +Concrete Block=Bloc de béton + +Plastic sheet=Morceau de plastique +Plastic strips=Bande de plastique +Empty wire spool=Bobine de fil vide diff --git a/basic_materials/locale/basic_materials.it.tr b/basic_materials/locale/basic_materials.it.tr new file mode 100644 index 0000000..aae0b3b --- /dev/null +++ b/basic_materials/locale/basic_materials.it.tr @@ -0,0 +1,34 @@ +# textdomain: basic_materials +# Author: Salvo 'LtWorf' Tomaselli +Silicon lump=Grumo di silicio +Simple Integrated Circuit=Circuito integrato semplice +Simple Motor=Motore semplice +Heating element=Elemento riscaldante +Simple energy crystal=Cristallo di energia semplice + +Spool of steel wire=Bobina di filo d'acciaio +Spool of copper wire=Bobina di filo di rame +Spool of silver wire=Bobina di filo d'argento +Spool of gold wire=Bobina di filo d'oro +Steel Strip=Striscia d'acciaio +Copper Strip=Striscia di rame +Steel Bar=Barra d'acciaio +Chainlinks (brass)=Catena (ottone) +Chainlinks (steel)=Catena (acciaio) +Brass Ingot=Lingotto di ottone +Steel gear=Ingranaggio d'acciaio +Padlock=Catenaccio +Chain (steel, hanging)=Catena (acciaio, pendente) +Chain (brass, hanging)=Catena (ottone, pendente) +Brass Block=Blocco di ottone + +Oil extract=Estratto d'olio +Unprocessed paraffin=Paraffina grezza +Uncooked Terracotta Base=Argilla cruda +Wet Cement=Cemento umido +Cement=Cemento +Concrete Block=Blocco di calcestruzzo + +Plastic sheet=Foglio di plastica +Plastic strips=Striscia di plastica +Empty wire spool=Rocchetto vuoto diff --git a/basic_materials/locale/basic_materials.ru.tr b/basic_materials/locale/basic_materials.ru.tr new file mode 100644 index 0000000..85e9c0c --- /dev/null +++ b/basic_materials/locale/basic_materials.ru.tr @@ -0,0 +1,33 @@ +# textdomain: basic_materials +Silicon lump=Кусок Кремния +Simple Integrated Circuit=Микросхема +Simple Motor=Мотор +Heating element=Нить Накала +Simple energy crystal=Энергетический Кристалл + +Spool of steel wire=Катушка Стальной Проволоки +Spool of copper wire=Катушка Медной Проволоки +Spool of silver wire=Катушка Серебрянной Проволоки +Spool of gold wire=Катушка Золотой Проволоки +Steel Strip=Стальная Полоса +Copper Strip=Медная Полоса +Steel Bar=Стальной Прут +Chainlinks (brass)=Латунные Звенья +Chainlinks (steel)=Стальные Звенья +Brass Ingot=Латунный Брусок +Steel gear=Стальная Шестерня +Padlock=Навесной Замок +Chain (steel, hanging)=Стальная Цепь +Chain (brass, hanging)=Латунная Цепь +Brass Block=Латунный Блок + +Oil extract=Масляный Экстракт +Unprocessed paraffin=Необработанный Парафин +Uncooked Terracotta Base=Ком Мокрого Терракота +Wet Cement=Ком Мокрого Цемента +Cement=Цемент +Concrete Block=Железобетон + +Plastic sheet=Пластиковый Лист +Plastic strips=Пластиковая Полоса +Empty wire spool=Пустая Катушка diff --git a/basic_materials/metals.lua b/basic_materials/metals.lua new file mode 100644 index 0000000..0a3243b --- /dev/null +++ b/basic_materials/metals.lua @@ -0,0 +1,300 @@ +-- Translation support +local S = minetest.get_translator("basic_materials") + +-- items + +minetest.register_craftitem("basic_materials:steel_wire", { + description = S("Spool of steel wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_steel_wire.png" +}) + +minetest.register_craftitem("basic_materials:copper_wire", { + description = S("Spool of copper wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_copper_wire.png" +}) + +minetest.register_craftitem("basic_materials:silver_wire", { + description = S("Spool of silver wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_silver_wire.png" +}) + +minetest.register_craftitem("basic_materials:gold_wire", { + description = S("Spool of gold wire"), + groups = { wire = 1 }, + inventory_image = "basic_materials_gold_wire.png" +}) + +minetest.register_craftitem("basic_materials:steel_strip", { + description = S("Steel Strip"), + groups = { strip = 1 }, + inventory_image = "basic_materials_steel_strip.png" +}) + +minetest.register_craftitem("basic_materials:copper_strip", { + description = S("Copper Strip"), + groups = { strip = 1 }, + inventory_image = "basic_materials_copper_strip.png" +}) + +minetest.register_craftitem("basic_materials:steel_bar", { + description = S("Steel Bar"), + inventory_image = "basic_materials_steel_bar.png", +}) + +minetest.register_craftitem("basic_materials:chainlink_brass", { + description = S("Chainlinks (brass)"), + groups = { chainlinks = 1 }, + inventory_image = "basic_materials_chainlink_brass.png" +}) + +minetest.register_craftitem("basic_materials:chainlink_steel", { + description = S("Chainlinks (steel)"), + groups = { chainlinks = 1 }, + inventory_image = "basic_materials_chainlink_steel.png" +}) + +minetest.register_craftitem("basic_materials:brass_ingot", { + description = S("Brass Ingot"), + inventory_image = "basic_materials_brass_ingot.png", +}) + +minetest.register_craftitem("basic_materials:gear_steel", { + description = S("Steel gear"), + inventory_image = "basic_materials_gear_steel.png" +}) + +minetest.register_craftitem("basic_materials:padlock", { + description = S("Padlock"), + inventory_image = "basic_materials_padlock.png" +}) + +-- nodes + +local chains_sbox = { + type = "fixed", + fixed = { -0.1, -0.5, -0.1, 0.1, 0.5, 0.1 } +} + +minetest.register_node("basic_materials:chain_steel", { + description = S("Chain (steel, hanging)"), + drawtype = "mesh", + mesh = "basic_materials_chains.obj", + tiles = {"basic_materials_chain_steel.png"}, + walkable = false, + climbable = true, + sunlight_propagates = true, + paramtype = "light", + inventory_image = "basic_materials_chain_steel_inv.png", + groups = {cracky=3}, + selection_box = chains_sbox, +}) + +minetest.register_node("basic_materials:chain_brass", { + description = S("Chain (brass, hanging)"), + drawtype = "mesh", + mesh = "basic_materials_chains.obj", + tiles = {"basic_materials_chain_brass.png"}, + walkable = false, + climbable = true, + sunlight_propagates = true, + paramtype = "light", + inventory_image = "basic_materials_chain_brass_inv.png", + groups = {cracky=3}, + selection_box = chains_sbox, +}) + +minetest.register_node("basic_materials:brass_block", { + description = S("Brass Block"), + tiles = { "basic_materials_brass_block.png" }, + is_ground_content = false, + groups = {cracky=1, level=2}, + sounds = default.node_sound_metal_defaults() +}) + +-- crafts + +minetest.register_craft( { + output = "basic_materials:copper_wire 2", + type = "shapeless", + recipe = { + "default:copper_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, +}) + +minetest.register_craft( { + output = "basic_materials:silver_wire 2", + type = "shapeless", + recipe = { + "moreores:silver_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, +}) + +minetest.register_craft( { + output = "basic_materials:gold_wire 2", + type = "shapeless", + recipe = { + "default:gold_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, +}) + +minetest.register_craft( { + output = "basic_materials:steel_wire 2", + type = "shapeless", + recipe = { + "default:steel_ingot", + "basic_materials:empty_spool", + "basic_materials:empty_spool", + }, +}) + +minetest.register_craft( { + output = "basic_materials:steel_strip 12", + recipe = { + { "", "default:steel_ingot", "" }, + { "default:steel_ingot", "", "" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:copper_strip 12", + recipe = { + { "", "default:copper_ingot", "" }, + { "default:copper_ingot", "", "" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:steel_bar 6", + recipe = { + { "", "", "default:steel_ingot" }, + { "", "default:steel_ingot", "" }, + { "default:steel_ingot", "", "" }, + }, +}) + +minetest.register_craft( { + output = "basic_materials:padlock 2", + recipe = { + { "basic_materials:steel_bar" }, + { "default:steel_ingot" }, + { "default:steel_ingot" }, + }, +}) + +minetest.register_craft({ + output = "basic_materials:chainlink_steel 12", + recipe = { + {"", "default:steel_ingot", "default:steel_ingot"}, + { "default:steel_ingot", "", "default:steel_ingot" }, + { "default:steel_ingot", "default:steel_ingot", "" }, + }, +}) + +minetest.register_craft({ + output = "basic_materials:chainlink_brass 12", + recipe = { + {"", "basic_materials:brass_ingot", "basic_materials:brass_ingot"}, + { "basic_materials:brass_ingot", "", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "" }, + }, +}) + +minetest.register_craft({ + output = 'basic_materials:chain_steel 2', + recipe = { + {"basic_materials:chainlink_steel"}, + {"basic_materials:chainlink_steel"}, + {"basic_materials:chainlink_steel"} + } +}) + +minetest.register_craft({ + output = 'basic_materials:chain_brass 2', + recipe = { + {"basic_materials:chainlink_brass"}, + {"basic_materials:chainlink_brass"}, + {"basic_materials:chainlink_brass"} + } +}) + +minetest.register_craft( { + output = "basic_materials:gear_steel 6", + recipe = { + { "", "default:steel_ingot", "" }, + { "default:steel_ingot","basic_materials:chainlink_steel", "default:steel_ingot" }, + { "", "default:steel_ingot", "" } + }, +}) + +minetest.register_craft( { + type = "shapeless", + output = "basic_materials:brass_ingot 3", + recipe = { + "default:copper_ingot", + "default:copper_ingot", + "moreores:silver_ingot", + }, +}) + +if not minetest.get_modpath("moreores") then + -- Without moreores, there still should be a way to create brass. + minetest.register_craft( { + output = "basic_materials:brass_ingot 9", + recipe = { + {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, + {"default:gold_ingot", "default:copper_ingot", "default:gold_ingot"}, + {"default:copper_ingot", "default:tin_ingot", "default:copper_ingot"}, + }, + }) +end + +minetest.register_craft( { + type = "shapeless", + output = "basic_materials:brass_ingot 9", + recipe = { "basic_materials:brass_block" }, +}) + +minetest.register_craft( { + output = "basic_materials:brass_block", + recipe = { + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + { "basic_materials:brass_ingot", "basic_materials:brass_ingot", "basic_materials:brass_ingot" }, + }, +}) + +-- aliases + +minetest.register_alias("homedecor:copper_wire", "basic_materials:copper_wire") +minetest.register_alias("technic:fine_copper_wire", "basic_materials:copper_wire") +minetest.register_alias("technic:fine_silver_wire", "basic_materials:silver_wire") +minetest.register_alias("technic:fine_gold_wire", "basic_materials:gold_wire") + +minetest.register_alias("homedecor:steel_wire", "basic_materials:steel_wire") + +minetest.register_alias("homedecor:brass_ingot", "basic_materials:brass_ingot") +minetest.register_alias("technic:brass_ingot", "basic_materials:brass_ingot") +minetest.register_alias("technic:brass_block", "basic_materials:brass_block") + +minetest.register_alias("homedecor:copper_strip", "basic_materials:copper_strip") +minetest.register_alias("homedecor:steel_strip", "basic_materials:steel_strip") + +minetest.register_alias_force("glooptest:chainlink", "basic_materials:chainlink_steel") +minetest.register_alias_force("homedecor:chainlink_steel", "basic_materials:chainlink_steel") +minetest.register_alias("homedecor:chainlink_brass", "basic_materials:chainlink_brass") +minetest.register_alias("chains:chain", "basic_materials:chain_steel") +minetest.register_alias("chains:chain_brass", "basic_materials:chain_brass") + +minetest.register_alias("pipeworks:gear", "basic_materials:gear_steel") + +minetest.register_alias("technic:rebar", "basic_materials:steel_bar") + diff --git a/basic_materials/misc.lua b/basic_materials/misc.lua new file mode 100644 index 0000000..0012897 --- /dev/null +++ b/basic_materials/misc.lua @@ -0,0 +1,126 @@ +-- Translation support +local S = minetest.get_translator("basic_materials") + +-- items + +minetest.register_craftitem("basic_materials:oil_extract", { + description = S("Oil extract"), + inventory_image = "basic_materials_oil_extract.png", +}) + +minetest.register_craftitem("basic_materials:paraffin", { + description = S("Unprocessed paraffin"), + inventory_image = "basic_materials_paraffin.png", +}) + +minetest.register_craftitem("basic_materials:terracotta_base", { + description = S("Uncooked Terracotta Base"), + inventory_image = "basic_materials_terracotta_base.png", +}) + +minetest.register_craftitem("basic_materials:wet_cement", { + description = S("Wet Cement"), + inventory_image = "basic_materials_wet_cement.png", +}) + +-- nodes + +minetest.register_node("basic_materials:cement_block", { + description = S("Cement"), + tiles = {"basic_materials_cement_block.png"}, + is_ground_content = true, + groups = {cracky=2}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_node("basic_materials:concrete_block", { + description = S("Concrete Block"), + tiles = {"basic_materials_concrete_block.png",}, + groups = {cracky=1, level=2, concrete=1}, + sounds = default.node_sound_stone_defaults(), +}) + +-- crafts + +minetest.register_craft({ + type = "shapeless", + output = "basic_materials:oil_extract 2", + recipe = { + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves", + "group:leaves" + } +}) + +minetest.register_craft({ + type = "cooking", + output = "basic_materials:paraffin", + recipe = "basic_materials:oil_extract", +}) + +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:oil_extract", + burntime = 30, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:paraffin", + burntime = 30, +}) + +minetest.register_craft( { + type = "shapeless", + output = "basic_materials:terracotta_base 8", + recipe = { + "bucket:bucket_water", + "default:clay_lump", + "default:gravel", + }, + replacements = { {"bucket:bucket_water", "bucket:bucket_empty"}, }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "basic_materials:wet_cement 3", + recipe = { + "default:dirt", + "dye:dark_grey", + "dye:dark_grey", + "dye:dark_grey", + "bucket:bucket_water" + }, + replacements = {{'bucket:bucket_water', 'bucket:bucket_empty'},}, +}) + +minetest.register_craft({ + type = "cooking", + output = "basic_materials:cement_block", + recipe = "basic_materials:wet_cement", + cooktime = 8 +}) + +minetest.register_craft({ + output = 'basic_materials:concrete_block 6', + recipe = { + {'group:sand', 'basic_materials:wet_cement', 'default:gravel'}, + {'basic_materials:steel_bar', 'basic_materials:wet_cement', 'basic_materials:steel_bar'}, + {'default:gravel', 'basic_materials:wet_cement', 'group:sand'}, + } +}) + +-- aliases + +minetest.register_alias("homedecor:oil_extract", "basic_materials:oil_extract") +minetest.register_alias("homedecor:paraffin", "basic_materials:paraffin") +minetest.register_alias("homedecor:plastic_base", "basic_materials:paraffin") +minetest.register_alias("homedecor:terracotta_base", "basic_materials:terracotta_base") + +minetest.register_alias("gloopblocks:wet_cement", "basic_materials:wet_cement") +minetest.register_alias("gloopblocks:cement", "basic_materials:cement_block") + +minetest.register_alias("technic:concrete", "basic_materials:concrete_block") diff --git a/basic_materials/mod.conf b/basic_materials/mod.conf new file mode 100644 index 0000000..7234bfe --- /dev/null +++ b/basic_materials/mod.conf @@ -0,0 +1,4 @@ +name = basic_materials +depends = default +optional_depends = moreores +min_minetest_version = 5.2.0 diff --git a/basic_materials/models/basic_materials_chains.obj b/basic_materials/models/basic_materials_chains.obj new file mode 100644 index 0000000..78724c9 --- /dev/null +++ b/basic_materials/models/basic_materials_chains.obj @@ -0,0 +1,881 @@ +# Blender v2.73 (sub 0) OBJ File: 'chains.blend' +# www.blender.org +o Torus.016_Torus +v 0.000000 -0.429978 0.000002 +v 0.000000 -0.401109 0.055211 +v -0.014044 -0.391975 0.048870 +v -0.014044 -0.423304 0.000002 +v -0.009826 -0.379748 0.040970 +v -0.009826 -0.406012 0.000002 +v 0.009826 -0.379748 0.040970 +v 0.009826 -0.406012 0.000002 +v 0.014044 -0.391975 0.048870 +v 0.014044 -0.423304 0.000002 +v 0.000000 -0.316336 0.080195 +v -0.014044 -0.316336 0.069112 +v -0.009826 -0.316336 0.057941 +v 0.009826 -0.316336 0.057941 +v 0.014044 -0.316336 0.069112 +v 0.000000 -0.231564 0.055211 +v -0.014044 -0.240700 0.048870 +v -0.009826 -0.252925 0.040970 +v 0.009826 -0.252925 0.040970 +v 0.014044 -0.240700 0.048870 +v 0.000000 -0.202695 0.000002 +v -0.014044 -0.209368 0.000002 +v -0.009826 -0.226661 0.000002 +v 0.009826 -0.226661 0.000002 +v 0.014044 -0.209368 0.000002 +v 0.000000 -0.231564 -0.055206 +v -0.014044 -0.240700 -0.048868 +v -0.009826 -0.252925 -0.040967 +v 0.009826 -0.252925 -0.040967 +v 0.014044 -0.240700 -0.048865 +v 0.000000 -0.316336 -0.080190 +v -0.014044 -0.316336 -0.069108 +v -0.009826 -0.316336 -0.057936 +v 0.009826 -0.316336 -0.057936 +v 0.014044 -0.316336 -0.069108 +v 0.000000 -0.400361 -0.055206 +v -0.014044 -0.391975 -0.048868 +v -0.009826 -0.379748 -0.040967 +v 0.009826 -0.379748 -0.040967 +v 0.014044 -0.391975 -0.048868 +v 0.000000 -0.262249 0.000002 +v -0.061672 -0.233381 0.000002 +v -0.054590 -0.224245 -0.012569 +v 0.000000 -0.255577 -0.012569 +v -0.045765 -0.212018 -0.008794 +v 0.000000 -0.238285 -0.008794 +v -0.045765 -0.212018 0.008798 +v 0.000000 -0.238285 0.008798 +v -0.054590 -0.224245 0.012574 +v 0.000000 -0.255577 0.012574 +v -0.089582 -0.148609 0.000002 +v -0.077200 -0.148609 -0.012569 +v -0.064722 -0.148609 -0.008794 +v -0.064722 -0.148609 0.008799 +v -0.077200 -0.148609 0.012574 +v -0.061672 -0.063837 0.000002 +v -0.054590 -0.072971 -0.012569 +v -0.045765 -0.085198 -0.008794 +v -0.045765 -0.085198 0.008799 +v -0.054590 -0.072971 0.012574 +v 0.000000 -0.034967 0.000002 +v 0.000000 -0.041641 -0.012569 +v 0.000000 -0.058933 -0.008794 +v 0.000000 -0.058933 0.008799 +v 0.000000 -0.041641 0.012574 +v 0.061672 -0.063837 0.000002 +v 0.054590 -0.072971 -0.012569 +v 0.045765 -0.085198 -0.008794 +v 0.045765 -0.085198 0.008799 +v 0.054590 -0.072971 0.012574 +v 0.089582 -0.148609 0.000002 +v 0.077200 -0.148609 -0.012569 +v 0.064722 -0.148609 -0.008794 +v 0.064722 -0.148609 0.008799 +v 0.077200 -0.148609 0.012574 +v 0.061672 -0.232631 0.000002 +v 0.054590 -0.224245 -0.012569 +v 0.045765 -0.212018 -0.008794 +v 0.045765 -0.212018 0.008798 +v 0.054590 -0.224245 0.012574 +v 0.000000 0.073316 0.000002 +v 0.061672 0.102183 0.000002 +v 0.054590 0.111319 0.012574 +v 0.000000 0.079988 0.012574 +v 0.045765 0.123546 0.008799 +v 0.000000 0.097280 0.008799 +v 0.045765 0.123546 -0.008794 +v 0.000000 0.097280 -0.008794 +v 0.054590 0.111319 -0.012569 +v 0.000000 0.079988 -0.012569 +v 0.089582 0.186956 0.000002 +v 0.077200 0.186956 0.012574 +v 0.064722 0.186956 0.008799 +v 0.064722 0.186956 -0.008794 +v 0.077200 0.186956 -0.012569 +v 0.061672 0.271728 0.000002 +v 0.054590 0.262594 0.012574 +v 0.045765 0.250367 0.008799 +v 0.045765 0.250367 -0.008794 +v 0.054590 0.262594 -0.012569 +v 0.000000 0.300597 0.000002 +v 0.000000 0.293923 0.012574 +v 0.000000 0.276631 0.008799 +v 0.000000 0.276631 -0.008794 +v 0.000000 0.293923 -0.012569 +v -0.061672 0.271728 0.000002 +v -0.054590 0.262594 0.012574 +v -0.045765 0.250367 0.008799 +v -0.045765 0.250367 -0.008794 +v -0.054590 0.262594 -0.012569 +v -0.089582 0.186956 0.000002 +v -0.077200 0.186956 0.012574 +v -0.064722 0.186956 0.008799 +v -0.064722 0.186956 -0.008794 +v -0.077200 0.186956 -0.012569 +v -0.061672 0.102931 0.000002 +v -0.054590 0.111319 0.012574 +v -0.045765 0.123546 0.008799 +v -0.045765 0.123546 -0.008794 +v -0.054590 0.111319 -0.012569 +v 0.000000 -0.095037 0.000002 +v 0.000000 -0.066168 -0.055206 +v 0.014044 -0.057034 -0.048868 +v 0.014044 -0.088363 0.000002 +v 0.009826 -0.044807 -0.040967 +v 0.009826 -0.071071 0.000002 +v -0.009826 -0.044807 -0.040967 +v -0.009826 -0.071071 0.000002 +v -0.014044 -0.057034 -0.048868 +v -0.014044 -0.088363 0.000002 +v 0.000000 0.018605 -0.080190 +v 0.014044 0.018605 -0.069108 +v 0.009826 0.018605 -0.057936 +v -0.009826 0.018605 -0.057936 +v -0.014044 0.018605 -0.069108 +v 0.000000 0.103377 -0.055206 +v 0.014044 0.094243 -0.048868 +v 0.009826 0.082016 -0.040967 +v -0.009826 0.082016 -0.040967 +v -0.014044 0.094243 -0.048868 +v 0.000000 0.132246 0.000002 +v 0.014044 0.125572 0.000002 +v 0.009826 0.108280 0.000002 +v -0.009826 0.108280 0.000002 +v -0.014044 0.125572 0.000002 +v 0.000000 0.103377 0.055211 +v 0.014044 0.094243 0.048870 +v 0.009826 0.082016 0.040970 +v -0.009826 0.082016 0.040970 +v -0.014044 0.094243 0.048870 +v 0.000000 0.018605 0.080195 +v 0.014044 0.018605 0.069112 +v 0.009826 0.018605 0.057941 +v -0.009826 0.018605 0.057941 +v -0.014044 0.018605 0.069112 +v 0.000000 -0.065420 0.055211 +v 0.014044 -0.057032 0.048870 +v 0.009826 -0.044807 0.040970 +v -0.009826 -0.044807 0.040970 +v -0.014044 -0.057032 0.048870 +v 0.000000 -0.598329 0.000002 +v 0.061672 -0.569460 0.000002 +v 0.054590 -0.560326 0.012574 +v 0.000000 -0.591655 0.012574 +v 0.045765 -0.548099 0.008798 +v 0.000000 -0.574363 0.008798 +v 0.045765 -0.548099 -0.008794 +v 0.000000 -0.574363 -0.008794 +v 0.054590 -0.560326 -0.012569 +v 0.000000 -0.591655 -0.012569 +v 0.089582 -0.484687 0.000002 +v 0.077200 -0.484687 0.012574 +v 0.064722 -0.484687 0.008798 +v 0.064722 -0.484687 -0.008794 +v 0.077200 -0.484687 -0.012569 +v 0.061672 -0.399915 0.000002 +v 0.054590 -0.409051 0.012574 +v 0.045765 -0.421278 0.008798 +v 0.045765 -0.421278 -0.008794 +v 0.054590 -0.409051 -0.012569 +v 0.000000 -0.371048 0.000002 +v 0.000000 -0.377719 0.012574 +v 0.000000 -0.395012 0.008798 +v 0.000000 -0.395012 -0.008794 +v 0.000000 -0.377719 -0.012569 +v -0.061672 -0.399915 0.000002 +v -0.054590 -0.409051 0.012574 +v -0.045765 -0.421278 0.008798 +v -0.045765 -0.421278 -0.008794 +v -0.054590 -0.409051 -0.012569 +v -0.089582 -0.484687 0.000002 +v -0.077200 -0.484687 0.012574 +v -0.064722 -0.484687 0.008798 +v -0.064722 -0.484687 -0.008794 +v -0.077200 -0.484687 -0.012569 +v -0.061672 -0.568712 0.000002 +v -0.054590 -0.560326 0.012574 +v -0.045765 -0.548099 0.008798 +v -0.045765 -0.548099 -0.008794 +v -0.054590 -0.560326 -0.012569 +v 0.000000 0.241043 0.000002 +v 0.000000 0.269910 0.055211 +v -0.014044 0.279047 0.048870 +v -0.014044 0.247717 0.000002 +v -0.009826 0.291274 0.040970 +v -0.009826 0.265007 0.000002 +v 0.009826 0.291274 0.040970 +v 0.009826 0.265007 0.000002 +v 0.014044 0.279047 0.048870 +v 0.014044 0.247717 0.000002 +v 0.000000 0.354683 0.080195 +v -0.014044 0.354683 0.069112 +v -0.009826 0.354683 0.057941 +v 0.009826 0.354683 0.057941 +v 0.014044 0.354683 0.069112 +v 0.000000 0.439455 0.055211 +v -0.014044 0.430321 0.048870 +v -0.009826 0.418094 0.040970 +v 0.009826 0.418094 0.040970 +v 0.014044 0.430321 0.048870 +v 0.000000 0.468325 0.000002 +v -0.014044 0.461651 0.000002 +v -0.009826 0.444361 0.000002 +v 0.009826 0.444361 0.000002 +v 0.014044 0.461651 0.000002 +v 0.000000 0.439455 -0.055206 +v -0.014044 0.430321 -0.048868 +v -0.009826 0.418094 -0.040967 +v 0.009826 0.418094 -0.040967 +v 0.014044 0.430321 -0.048868 +v 0.000000 0.354683 -0.080190 +v -0.014044 0.354683 -0.069108 +v -0.009826 0.354683 -0.057936 +v 0.009826 0.354683 -0.057936 +v 0.014044 0.354683 -0.069108 +v 0.000000 0.270661 -0.055206 +v -0.014044 0.279047 -0.048868 +v -0.009826 0.291274 -0.040967 +v 0.009826 0.291274 -0.040967 +v 0.014044 0.279047 -0.048868 +vt 0.187500 0.125000 +vt 0.250000 0.125000 +vt 0.250000 0.187500 +vt 0.187500 0.187500 +vt 0.250000 0.250000 +vt 0.187500 0.250000 +vt 0.250000 0.312500 +vt 0.187500 0.312500 +vt 0.250000 0.375000 +vt 0.187500 0.375000 +vt 0.187500 0.062500 +vt 0.250000 0.062500 +vt 0.312500 0.125000 +vt 0.312500 0.187500 +vt 0.312500 0.250000 +vt 0.312500 0.312500 +vt 0.312500 0.375000 +vt 0.312500 0.062500 +vt 0.375000 0.125000 +vt 0.375000 0.187500 +vt 0.375000 0.250000 +vt 0.375000 0.312500 +vt 0.375000 0.375000 +vt 0.375000 0.062500 +vt 0.437500 0.125000 +vt 0.437500 0.187500 +vt 0.437500 0.250000 +vt 0.437500 0.312500 +vt 0.437500 0.375000 +vt 0.437500 0.062500 +vt 0.500000 0.125000 +vt 0.500000 0.187500 +vt 0.500000 0.250000 +vt 0.500000 0.312500 +vt 0.500000 0.375000 +vt 0.500000 0.062500 +vt -0.000000 0.125000 +vt 0.062500 0.125000 +vt 0.062500 0.187500 +vt -0.000000 0.187500 +vt 0.062500 0.250000 +vt -0.000000 0.250000 +vt 0.062500 0.312500 +vt -0.000000 0.312500 +vt 0.062500 0.375000 +vt -0.000000 0.375000 +vt -0.000000 0.062500 +vt 0.062500 0.062500 +vt 0.125000 0.125000 +vt 0.125000 0.187500 +vt 0.125000 0.250000 +vt 0.125000 0.312500 +vt 0.125000 0.375000 +vt 0.125000 0.062500 +vt 0.750000 0.625000 +vt 0.812500 0.625000 +vt 0.812500 0.687500 +vt 0.750000 0.687500 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.437500 +vt 0.750000 0.437500 +vt 0.812500 0.500000 +vt 0.750000 0.500000 +vt 0.812500 0.562500 +vt 0.750000 0.562500 +vt 0.875000 0.625000 +vt 0.875000 0.687500 +vt 0.875000 0.375000 +vt 0.875000 0.437500 +vt 0.875000 0.500000 +vt 0.875000 0.562500 +vt 0.937500 0.625000 +vt 0.937500 0.687500 +vt 0.937500 0.375000 +vt 0.937500 0.437500 +vt 0.937500 0.500000 +vt 0.937500 0.562500 +vt 1.000000 0.625000 +vt 1.000000 0.687500 +vt 1.000000 0.375000 +vt 1.000000 0.437500 +vt 1.000000 0.500000 +vt 1.000000 0.562500 +vt 0.500000 0.625000 +vt 0.562500 0.625000 +vt 0.562500 0.687500 +vt 0.500000 0.687500 +vt 0.562500 0.375000 +vt 0.562500 0.437500 +vt 0.500000 0.437500 +vt 0.562500 0.500000 +vt 0.500000 0.500000 +vt 0.562500 0.562500 +vt 0.500000 0.562500 +vt 0.625000 0.625000 +vt 0.625000 0.687500 +vt 0.625000 0.375000 +vt 0.625000 0.437500 +vt 0.625000 0.500000 +vt 0.625000 0.562500 +vt 0.687500 0.625000 +vt 0.687500 0.687500 +vt 0.687500 0.375000 +vt 0.687500 0.437500 +vt 0.687500 0.500000 +vt 0.687500 0.562500 +vt 0.250000 0.625000 +vt 0.312500 0.625000 +vt 0.312500 0.687500 +vt 0.250000 0.687500 +vt 0.312500 0.437500 +vt 0.250000 0.437500 +vt 0.312500 0.500000 +vt 0.250000 0.500000 +vt 0.312500 0.562500 +vt 0.250000 0.562500 +vt 0.375000 0.625000 +vt 0.375000 0.687500 +vt 0.375000 0.437500 +vt 0.375000 0.500000 +vt 0.375000 0.562500 +vt 0.437500 0.625000 +vt 0.437500 0.687500 +vt 0.437500 0.437500 +vt 0.437500 0.500000 +vt 0.437500 0.562500 +vt -0.000000 0.625000 +vt 0.062500 0.625000 +vt 0.062500 0.687500 +vt -0.000000 0.687500 +vt 0.062500 0.437500 +vt -0.000000 0.437500 +vt 0.062500 0.500000 +vt -0.000000 0.500000 +vt 0.062500 0.562500 +vt -0.000000 0.562500 +vt 0.125000 0.625000 +vt 0.125000 0.687500 +vt 0.125000 0.437500 +vt 0.125000 0.500000 +vt 0.125000 0.562500 +vt 0.187500 0.625000 +vt 0.187500 0.687500 +vt 0.187500 0.437500 +vt 0.187500 0.500000 +vt 0.187500 0.562500 +vt 0.687500 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.812500 +vt 0.687500 0.812500 +vt 0.750000 0.875000 +vt 0.687500 0.875000 +vt 0.750000 0.937500 +vt 0.687500 0.937500 +vt 0.750000 1.000000 +vt 0.687500 1.000000 +vt 0.812500 0.750000 +vt 0.812500 0.812500 +vt 0.812500 0.875000 +vt 0.812500 0.937500 +vt 0.812500 1.000000 +vt 0.875000 0.750000 +vt 0.875000 0.812500 +vt 0.875000 0.875000 +vt 0.875000 0.937500 +vt 0.875000 1.000000 +vt 0.937500 0.750000 +vt 0.937500 0.812500 +vt 0.937500 0.875000 +vt 0.937500 0.937500 +vt 0.937500 1.000000 +vt 1.000000 0.750000 +vt 1.000000 0.812500 +vt 1.000000 0.875000 +vt 1.000000 0.937500 +vt 1.000000 1.000000 +vt 0.500000 0.750000 +vt 0.562500 0.750000 +vt 0.562500 0.812500 +vt 0.500000 0.812500 +vt 0.562500 0.875000 +vt 0.500000 0.875000 +vt 0.562500 0.937500 +vt 0.500000 0.937500 +vt 0.562500 1.000000 +vt 0.500000 1.000000 +vt 0.625000 0.750000 +vt 0.625000 0.812500 +vt 0.625000 0.875000 +vt 0.625000 0.937500 +vt 0.625000 1.000000 +vt 0.750000 0.312500 +vt 0.812500 0.312500 +vt 0.750000 0.062500 +vt 0.812500 0.062500 +vt 0.812500 0.125000 +vt 0.750000 0.125000 +vt 0.812500 0.187500 +vt 0.750000 0.187500 +vt 0.812500 0.250000 +vt 0.750000 0.250000 +vt 0.875000 0.312500 +vt 0.875000 0.062500 +vt 0.875000 0.125000 +vt 0.875000 0.187500 +vt 0.875000 0.250000 +vt 0.937500 0.312500 +vt 0.937500 0.062500 +vt 0.937500 0.125000 +vt 0.937500 0.187500 +vt 0.937500 0.250000 +vt 1.000000 0.312500 +vt 1.000000 0.062500 +vt 1.000000 0.125000 +vt 1.000000 0.187500 +vt 1.000000 0.250000 +vt 0.562500 0.312500 +vt 0.562500 0.062500 +vt 0.562500 0.125000 +vt 0.562500 0.187500 +vt 0.562500 0.250000 +vt 0.625000 0.312500 +vt 0.625000 0.062500 +vt 0.625000 0.125000 +vt 0.625000 0.187500 +vt 0.625000 0.250000 +vt 0.687500 0.312500 +vt 0.687500 0.062500 +vt 0.687500 0.125000 +vt 0.687500 0.187500 +vt 0.687500 0.250000 +vt 0.250000 0.937500 +vt 0.312500 0.937500 +vt 0.312500 1.000000 +vt 0.250000 1.000000 +vt 0.312500 0.750000 +vt 0.250000 0.750000 +vt 0.312500 0.812500 +vt 0.250000 0.812500 +vt 0.312500 0.875000 +vt 0.250000 0.875000 +vt 0.375000 0.937500 +vt 0.375000 1.000000 +vt 0.375000 0.750000 +vt 0.375000 0.812500 +vt 0.375000 0.875000 +vt 0.437500 0.937500 +vt 0.437500 1.000000 +vt 0.437500 0.750000 +vt 0.437500 0.812500 +vt 0.437500 0.875000 +vt 0.000000 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt 0.000000 1.000000 +vt 0.062500 0.750000 +vt 0.000000 0.750000 +vt 0.062500 0.812500 +vt 0.000000 0.812500 +vt 0.062500 0.875000 +vt 0.000000 0.875000 +vt 0.125000 0.937500 +vt 0.125000 1.000000 +vt 0.125000 0.750000 +vt 0.125000 0.812500 +vt 0.125000 0.875000 +vt 0.187500 0.937500 +vt 0.187500 1.000000 +vt 0.187500 0.750000 +vt 0.187500 0.812500 +vt 0.187500 0.875000 +vn 0.000000 -1.000000 -0.004800 +vn 0.000000 -0.657400 0.753500 +vn -0.898300 -0.248500 0.362300 +vn -0.863600 -0.504100 -0.003400 +vn -0.661500 0.421500 -0.620200 +vn -0.746000 0.665900 0.000000 +vn 0.661500 0.421500 -0.620200 +vn 0.746000 0.665900 0.000000 +vn 0.898300 -0.248500 0.362300 +vn 0.863600 -0.504100 -0.003400 +vn 0.000000 0.000000 1.000000 +vn -0.925200 0.000000 0.379500 +vn -0.617100 0.000000 -0.786900 +vn 0.617100 0.000000 -0.786900 +vn 0.925200 0.000000 0.379500 +vn 0.000000 0.657400 0.753500 +vn -0.898300 0.248400 0.362300 +vn -0.661500 -0.421500 -0.620200 +vn 0.661500 -0.421500 -0.620200 +vn 0.898300 0.248400 0.362300 +vn 0.000000 1.000000 0.000000 +vn -0.866100 0.499800 0.000000 +vn -0.746000 -0.665900 0.000000 +vn 0.746000 -0.665900 0.000000 +vn 0.866100 0.499800 0.000000 +vn 0.000000 0.657400 -0.753500 +vn -0.898300 0.248400 -0.362400 +vn -0.661600 -0.421500 0.620200 +vn 0.661500 -0.421500 0.620200 +vn 0.898300 0.248400 -0.362300 +vn 0.000000 -0.000900 -1.000000 +vn -0.924600 -0.000600 -0.380700 +vn -0.617100 0.000000 0.786900 +vn 0.617100 0.000000 0.786900 +vn 0.924700 -0.000600 -0.380700 +vn 0.000000 -0.650300 -0.759600 +vn -0.895600 -0.254600 -0.364800 +vn -0.661600 0.421500 0.620200 +vn 0.661600 0.421500 0.620200 +vn 0.895600 -0.254600 -0.364800 +vn 0.004900 -1.000000 0.000000 +vn -0.729700 -0.683800 0.000000 +vn -0.324500 -0.256300 -0.910500 +vn 0.003300 -0.475500 -0.879700 +vn 0.578700 0.436200 -0.689100 +vn 0.000000 0.666600 -0.745400 +vn 0.578700 0.436200 0.689100 +vn 0.000000 0.666600 0.745400 +vn -0.324500 -0.256300 0.910500 +vn 0.003300 -0.475500 0.879700 +vn -1.000000 0.000000 0.000000 +vn -0.359600 0.000000 -0.933100 +vn 0.756400 0.000000 -0.654100 +vn 0.756400 0.000000 0.654100 +vn -0.359600 0.000000 0.933100 +vn -0.729700 0.683700 0.000000 +vn -0.324500 0.256300 -0.910500 +vn 0.578700 -0.436200 -0.689100 +vn 0.578700 -0.436200 0.689100 +vn -0.324500 0.256300 0.910500 +vn 0.000000 0.470900 -0.882200 +vn 0.000000 -0.666600 -0.745400 +vn 0.000000 -0.666600 0.745400 +vn 0.000000 0.470900 0.882200 +vn 0.729700 0.683700 0.000000 +vn 0.324500 0.256300 -0.910500 +vn -0.578700 -0.436200 -0.689100 +vn -0.578700 -0.436200 0.689100 +vn 0.324500 0.256300 0.910500 +vn 1.000000 -0.001100 0.000000 +vn 0.361000 -0.000700 -0.932600 +vn -0.756400 0.000000 -0.654100 +vn -0.756400 0.000000 0.654100 +vn 0.361000 -0.000700 0.932600 +vn 0.736100 -0.676800 0.000000 +vn 0.327100 -0.263100 -0.907600 +vn -0.578700 0.436200 -0.689100 +vn -0.578700 0.436200 0.689100 +vn 0.327100 -0.263100 0.907600 +vn -0.004900 -1.000000 0.000000 +vn 0.729700 -0.683800 0.000000 +vn 0.324500 -0.256300 0.910500 +vn -0.003300 -0.475400 0.879700 +vn 0.324500 -0.256300 -0.910500 +vn -0.003300 -0.475400 -0.879700 +vn 1.000000 0.000000 0.000000 +vn 0.359600 0.000000 0.933100 +vn 0.359600 0.000000 -0.933100 +vn -1.000000 -0.001100 0.000000 +vn -0.361000 -0.000700 0.932600 +vn -0.361000 -0.000700 -0.932600 +vn -0.736100 -0.676800 0.000000 +vn -0.327100 -0.263100 0.907600 +vn -0.327100 -0.263100 -0.907600 +vn 0.000000 -1.000000 0.004800 +vn 0.000000 -0.657400 -0.753500 +vn 0.898300 -0.248500 -0.362400 +vn 0.863600 -0.504100 0.003400 +vn -0.898300 -0.248500 -0.362400 +vn -0.863600 -0.504100 0.003400 +vn 0.000000 0.000000 -1.000000 +vn 0.925200 0.000000 -0.379500 +vn -0.925200 0.000000 -0.379500 +vn 0.898300 0.248500 -0.362400 +vn 0.661600 -0.421500 0.620200 +vn -0.898300 0.248500 -0.362400 +vn 0.898300 0.248500 0.362300 +vn -0.898300 0.248500 0.362300 +vn 0.000000 -0.000900 1.000000 +vn 0.924700 -0.000600 0.380700 +vn -0.924700 -0.000600 0.380700 +vn 0.000000 -0.650300 0.759600 +vn 0.895600 -0.254600 0.364700 +vn -0.895600 -0.254600 0.364700 +vn 0.729700 -0.683700 0.000000 +vn 0.729700 0.683800 0.000000 +vn -0.729700 0.683800 0.000000 +vn -0.898300 -0.248400 0.362300 +vn -0.863600 -0.504100 -0.003500 +vn 0.898300 -0.248400 0.362300 +vn 0.863600 -0.504100 -0.003500 +vn -0.661500 -0.421500 0.620200 +vn 0.924600 -0.000600 -0.380700 +vn -0.661500 0.421500 0.620200 +vn 0.661500 0.421500 0.620200 +s 1 +f 1/1/1 2/2/2 3/3/3 4/4/4 +f 4/4/4 3/3/3 5/5/5 6/6/6 +f 6/6/6 5/5/5 7/7/7 8/8/8 +f 8/8/8 7/7/7 9/9/9 10/10/10 +f 1/1/1 10/11/10 9/12/9 2/2/2 +f 2/2/2 11/13/11 12/14/12 3/3/3 +f 3/3/3 12/14/12 13/15/13 5/5/5 +f 5/5/5 13/15/13 14/16/14 7/7/7 +f 7/7/7 14/16/14 15/17/15 9/9/9 +f 9/12/9 15/18/15 11/13/11 2/2/2 +f 11/13/11 16/19/16 17/20/17 12/14/12 +f 12/14/12 17/20/17 18/21/18 13/15/13 +f 13/15/13 18/21/18 19/22/19 14/16/14 +f 14/16/14 19/22/19 20/23/20 15/17/15 +f 15/18/15 20/24/20 16/19/16 11/13/11 +f 16/19/16 21/25/21 22/26/22 17/20/17 +f 17/20/17 22/26/22 23/27/23 18/21/18 +f 18/21/18 23/27/23 24/28/24 19/22/19 +f 19/22/19 24/28/24 25/29/25 20/23/20 +f 20/24/20 25/30/25 21/25/21 16/19/16 +f 21/25/21 26/31/26 27/32/27 22/26/22 +f 22/26/22 27/32/27 28/33/28 23/27/23 +f 23/27/23 28/33/28 29/34/29 24/28/24 +f 24/28/24 29/34/29 30/35/30 25/29/25 +f 25/30/25 30/36/30 26/31/26 21/25/21 +f 26/37/26 31/38/31 32/39/32 27/40/27 +f 27/40/27 32/39/32 33/41/33 28/42/28 +f 28/42/28 33/41/33 34/43/34 29/44/29 +f 29/44/29 34/43/34 35/45/35 30/46/30 +f 30/47/30 35/48/35 31/38/31 26/37/26 +f 31/38/31 36/49/36 37/50/37 32/39/32 +f 32/39/32 37/50/37 38/51/38 33/41/33 +f 33/41/33 38/51/38 39/52/39 34/43/34 +f 34/43/34 39/52/39 40/53/40 35/45/35 +f 35/48/35 40/54/40 36/49/36 31/38/31 +f 36/49/36 1/1/1 4/4/4 37/50/37 +f 37/50/37 4/4/4 6/6/6 38/51/38 +f 38/51/38 6/6/6 8/8/8 39/52/39 +f 39/52/39 8/8/8 10/10/10 40/53/40 +f 1/1/1 36/49/36 40/54/40 10/11/10 +f 41/55/41 42/56/42 43/57/43 44/58/44 +f 44/59/44 43/60/43 45/61/45 46/62/46 +f 46/62/46 45/61/45 47/63/47 48/64/48 +f 48/64/48 47/63/47 49/65/49 50/66/50 +f 41/55/41 50/66/50 49/65/49 42/56/42 +f 42/56/42 51/67/51 52/68/52 43/57/43 +f 43/60/43 52/69/52 53/70/53 45/61/45 +f 45/61/45 53/70/53 54/71/54 47/63/47 +f 47/63/47 54/71/54 55/72/55 49/65/49 +f 49/65/49 55/72/55 51/67/51 42/56/42 +f 51/67/51 56/73/56 57/74/57 52/68/52 +f 52/69/52 57/75/57 58/76/58 53/70/53 +f 53/70/53 58/76/58 59/77/59 54/71/54 +f 54/71/54 59/77/59 60/78/60 55/72/55 +f 55/72/55 60/78/60 56/73/56 51/67/51 +f 56/73/56 61/79/21 62/80/61 57/74/57 +f 57/75/57 62/81/61 63/82/62 58/76/58 +f 58/76/58 63/82/62 64/83/63 59/77/59 +f 59/77/59 64/83/63 65/84/64 60/78/60 +f 60/78/60 65/84/64 61/79/21 56/73/56 +f 61/85/21 66/86/65 67/87/66 62/88/61 +f 62/35/61 67/89/66 68/90/67 63/91/62 +f 63/91/62 68/90/67 69/92/68 64/93/63 +f 64/93/63 69/92/68 70/94/69 65/95/64 +f 65/95/64 70/94/69 66/86/65 61/85/21 +f 66/86/65 71/96/70 72/97/71 67/87/66 +f 67/89/66 72/98/71 73/99/72 68/90/67 +f 68/90/67 73/99/72 74/100/73 69/92/68 +f 69/92/68 74/100/73 75/101/74 70/94/69 +f 70/94/69 75/101/74 71/96/70 66/86/65 +f 71/96/70 76/102/75 77/103/76 72/97/71 +f 72/98/71 77/104/76 78/105/77 73/99/72 +f 73/99/72 78/105/77 79/106/78 74/100/73 +f 74/100/73 79/106/78 80/107/79 75/101/74 +f 75/101/74 80/107/79 76/102/75 71/96/70 +f 76/102/75 41/55/41 44/58/44 77/103/76 +f 77/104/76 44/59/44 46/62/46 78/105/77 +f 78/105/77 46/62/46 48/64/48 79/106/78 +f 79/106/78 48/64/48 50/66/50 80/107/79 +f 41/55/41 76/102/75 80/107/79 50/66/50 +f 81/108/80 82/109/81 83/110/82 84/111/83 +f 84/9/83 83/17/82 85/112/78 86/113/48 +f 86/113/48 85/112/78 87/114/77 88/115/46 +f 88/115/46 87/114/77 89/116/84 90/117/85 +f 81/108/80 90/117/85 89/116/84 82/109/81 +f 82/109/81 91/118/86 92/119/87 83/110/82 +f 83/17/82 92/23/87 93/120/73 85/112/78 +f 85/112/78 93/120/73 94/121/72 87/114/77 +f 87/114/77 94/121/72 95/122/88 89/116/84 +f 89/116/84 95/122/88 91/118/86 82/109/81 +f 91/118/86 96/123/65 97/124/69 92/119/87 +f 92/23/87 97/29/69 98/125/68 93/120/73 +f 93/120/73 98/125/68 99/126/67 94/121/72 +f 94/121/72 99/126/67 100/127/66 95/122/88 +f 95/122/88 100/127/66 96/123/65 91/118/86 +f 96/123/65 101/85/21 102/88/64 97/124/69 +f 97/29/69 102/35/64 103/91/63 98/125/68 +f 98/125/68 103/91/63 104/93/62 99/126/67 +f 99/126/67 104/93/62 105/95/61 100/127/66 +f 100/127/66 105/95/61 101/85/21 96/123/65 +f 101/128/21 106/129/56 107/130/60 102/131/64 +f 102/46/64 107/45/60 108/132/59 103/133/63 +f 103/133/63 108/132/59 109/134/58 104/135/62 +f 104/135/62 109/134/58 110/136/57 105/137/61 +f 105/137/61 110/136/57 106/129/56 101/128/21 +f 106/129/56 111/138/89 112/139/90 107/130/60 +f 107/45/60 112/53/90 113/140/54 108/132/59 +f 108/132/59 113/140/54 114/141/53 109/134/58 +f 109/134/58 114/141/53 115/142/91 110/136/57 +f 110/136/57 115/142/91 111/138/89 106/129/56 +f 111/138/89 116/143/92 117/144/93 112/139/90 +f 112/53/90 117/10/93 118/145/47 113/140/54 +f 113/140/54 118/145/47 119/146/45 114/141/53 +f 114/141/53 119/146/45 120/147/94 115/142/91 +f 115/142/91 120/147/94 116/143/92 111/138/89 +f 116/143/92 81/108/80 84/111/83 117/144/93 +f 117/10/93 84/9/83 86/113/48 118/145/47 +f 118/145/47 86/113/48 88/115/46 119/146/45 +f 119/146/45 88/115/46 90/117/85 120/147/94 +f 81/108/80 116/143/92 120/147/94 90/117/85 +f 121/148/95 122/149/96 123/150/97 124/151/98 +f 124/151/98 123/150/97 125/152/39 126/153/8 +f 126/153/8 125/152/39 127/154/38 128/155/6 +f 128/155/6 127/154/38 129/156/99 130/157/100 +f 121/148/95 130/103/100 129/58/99 122/149/96 +f 122/149/96 131/158/101 132/159/102 123/150/97 +f 123/150/97 132/159/102 133/160/34 125/152/39 +f 125/152/39 133/160/34 134/161/33 127/154/38 +f 127/154/38 134/161/33 135/162/103 129/156/99 +f 129/58/99 135/57/103 131/158/101 122/149/96 +f 131/158/101 136/163/26 137/164/104 132/159/102 +f 132/159/102 137/164/104 138/165/105 133/160/34 +f 133/160/34 138/165/105 139/166/28 134/161/33 +f 134/161/33 139/166/28 140/167/106 135/162/103 +f 135/57/103 140/68/106 136/163/26 131/158/101 +f 136/163/26 141/168/21 142/169/25 137/164/104 +f 137/164/104 142/169/25 143/170/24 138/165/105 +f 138/165/105 143/170/24 144/171/23 139/166/28 +f 139/166/28 144/171/23 145/172/22 140/167/106 +f 140/68/106 145/74/22 141/168/21 136/163/26 +f 141/168/21 146/173/16 147/174/107 142/169/25 +f 142/169/25 147/174/107 148/175/19 143/170/24 +f 143/170/24 148/175/19 149/176/18 144/171/23 +f 144/171/23 149/176/18 150/177/108 145/172/22 +f 145/74/22 150/80/108 146/173/16 141/168/21 +f 146/178/16 151/179/109 152/180/110 147/181/107 +f 147/181/107 152/180/110 153/182/14 148/183/19 +f 148/183/19 153/182/14 154/184/13 149/185/18 +f 149/185/18 154/184/13 155/186/111 150/187/108 +f 150/88/108 155/87/111 151/179/109 146/178/16 +f 151/179/109 156/188/112 157/189/113 152/180/110 +f 152/180/110 157/189/113 158/190/7 153/182/14 +f 153/182/14 158/190/7 159/191/5 154/184/13 +f 154/184/13 159/191/5 160/192/114 155/186/111 +f 155/87/111 160/97/114 156/188/112 151/179/109 +f 156/188/112 121/148/95 124/151/98 157/189/113 +f 157/189/113 124/151/98 126/153/8 158/190/7 +f 158/190/7 126/153/8 128/155/6 159/191/5 +f 159/191/5 128/155/6 130/157/100 160/192/114 +f 121/148/95 156/188/112 160/97/114 130/103/100 +f 161/193/80 162/194/115 163/60/82 164/59/83 +f 164/195/83 163/196/82 165/197/78 166/198/48 +f 166/198/48 165/197/78 167/199/77 168/200/46 +f 168/200/46 167/199/77 169/201/84 170/202/85 +f 161/193/80 170/202/85 169/201/84 162/194/115 +f 162/194/115 171/203/86 172/69/87 163/60/82 +f 163/196/82 172/204/87 173/205/73 165/197/78 +f 165/197/78 173/205/73 174/206/72 167/199/77 +f 167/199/77 174/206/72 175/207/88 169/201/84 +f 169/201/84 175/207/88 171/203/86 162/194/115 +f 171/203/86 176/208/116 177/75/69 172/69/87 +f 172/204/87 177/209/69 178/210/68 173/205/73 +f 173/205/73 178/210/68 179/211/67 174/206/72 +f 174/206/72 179/211/67 180/212/66 175/207/88 +f 175/207/88 180/212/66 176/208/116 171/203/86 +f 176/208/116 181/213/21 182/81/64 177/75/69 +f 177/209/69 182/214/64 183/215/63 178/210/68 +f 178/210/68 183/215/63 184/216/62 179/211/67 +f 179/211/67 184/216/62 185/217/61 180/212/66 +f 180/212/66 185/217/61 181/213/21 176/208/116 +f 181/34/21 186/218/117 187/89/60 182/35/64 +f 182/36/64 187/219/60 188/220/59 183/31/63 +f 183/31/63 188/220/59 189/221/58 184/32/62 +f 184/32/62 189/221/58 190/222/57 185/33/61 +f 185/33/61 190/222/57 186/218/117 181/34/21 +f 186/218/117 191/223/89 192/98/90 187/89/60 +f 187/219/60 192/224/90 193/225/54 188/220/59 +f 188/220/59 193/225/54 194/226/53 189/221/58 +f 189/221/58 194/226/53 195/227/91 190/222/57 +f 190/222/57 195/227/91 191/223/89 186/218/117 +f 191/223/89 196/228/92 197/104/93 192/98/90 +f 192/224/90 197/229/93 198/230/47 193/225/54 +f 193/225/54 198/230/47 199/231/45 194/226/53 +f 194/226/53 199/231/45 200/232/94 195/227/91 +f 195/227/91 200/232/94 196/228/92 191/223/89 +f 196/228/92 161/193/80 164/59/83 197/104/93 +f 197/229/93 164/195/83 166/198/48 198/230/47 +f 198/230/47 166/198/48 168/200/46 199/231/45 +f 199/231/45 168/200/46 170/202/85 200/232/94 +f 161/193/80 196/228/92 200/232/94 170/202/85 +f 201/233/1 202/234/2 203/235/118 204/236/119 +f 204/111/119 203/110/118 205/237/5 206/238/6 +f 206/238/6 205/237/5 207/239/7 208/240/8 +f 208/240/8 207/239/7 209/241/120 210/242/121 +f 201/233/1 210/242/121 209/241/120 202/234/2 +f 202/234/2 211/243/11 212/244/12 203/235/118 +f 203/110/118 212/119/12 213/245/13 205/237/5 +f 205/237/5 213/245/13 214/246/14 207/239/7 +f 207/239/7 214/246/14 215/247/15 209/241/120 +f 209/241/120 215/247/15 211/243/11 202/234/2 +f 211/243/11 216/248/16 217/249/108 212/244/12 +f 212/119/12 217/124/108 218/250/18 213/245/13 +f 213/245/13 218/250/18 219/251/19 214/246/14 +f 214/246/14 219/251/19 220/252/107 215/247/15 +f 215/247/15 220/252/107 216/248/16 211/243/11 +f 216/248/16 221/185/21 222/187/22 217/249/108 +f 217/124/108 222/88/22 223/178/23 218/250/18 +f 218/250/18 223/178/23 224/181/24 219/251/19 +f 219/251/19 224/181/24 225/183/25 220/252/107 +f 220/252/107 225/183/25 221/185/21 216/248/16 +f 221/253/21 226/254/26 227/255/106 222/256/22 +f 222/131/22 227/130/106 228/257/122 223/258/23 +f 223/258/23 228/257/122 229/259/29 224/260/24 +f 224/260/24 229/259/29 230/261/104 225/262/25 +f 225/262/25 230/261/104 226/254/26 221/253/21 +f 226/254/26 231/263/31 232/264/32 227/255/106 +f 227/130/106 232/139/32 233/265/33 228/257/122 +f 228/257/122 233/265/33 234/266/34 229/259/29 +f 229/259/29 234/266/34 235/267/123 230/261/104 +f 230/261/104 235/267/123 231/263/31 226/254/26 +f 231/263/31 236/268/36 237/269/37 232/264/32 +f 232/139/32 237/144/37 238/270/124 233/265/33 +f 233/265/33 238/270/124 239/271/125 234/266/34 +f 234/266/34 239/271/125 240/272/40 235/267/123 +f 235/267/123 240/272/40 236/268/36 231/263/31 +f 236/268/36 201/233/1 204/236/119 237/269/37 +f 237/144/37 204/111/119 206/238/6 238/270/124 +f 238/270/124 206/238/6 208/240/8 239/271/125 +f 239/271/125 208/240/8 210/242/121 240/272/40 +f 201/233/1 236/268/36 240/272/40 210/242/121 diff --git a/basic_materials/plastics.lua b/basic_materials/plastics.lua new file mode 100644 index 0000000..e29af53 --- /dev/null +++ b/basic_materials/plastics.lua @@ -0,0 +1,56 @@ +-- Translation support +local S = minetest.get_translator("basic_materials") + +-- items + +minetest.register_craftitem("basic_materials:plastic_sheet", { + description = S("Plastic sheet"), + inventory_image = "basic_materials_plastic_sheet.png", +}) + +minetest.register_craftitem("basic_materials:plastic_strip", { + description = S("Plastic strips"), + groups = { strip = 1 }, + inventory_image = "basic_materials_plastic_strip.png", +}) + +minetest.register_craftitem("basic_materials:empty_spool", { + description = S("Empty wire spool"), + inventory_image = "basic_materials_empty_spool.png" +}) + +-- crafts + +minetest.register_craft({ + type = "cooking", + output = "basic_materials:plastic_sheet", + recipe = "basic_materials:paraffin", +}) + +minetest.register_craft({ + type = "fuel", + recipe = "basic_materials:plastic_sheet", + burntime = 30, +}) + +minetest.register_craft( { + output = "basic_materials:plastic_strip 9", + recipe = { + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } + }, +}) + +minetest.register_craft( { + output = "basic_materials:empty_spool 3", + recipe = { + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" }, + { "", "basic_materials:plastic_sheet", "" }, + { "basic_materials:plastic_sheet", "basic_materials:plastic_sheet", "basic_materials:plastic_sheet" } + }, +}) + +-- aliases + +minetest.register_alias("homedecor:plastic_sheeting", "basic_materials:plastic_sheet") +minetest.register_alias("homedecor:plastic_strips", "basic_materials:plastic_strip") +minetest.register_alias("homedecor:empty_spool", "basic_materials:empty_spool") diff --git a/basic_materials/textures/basic_materials_brass_block.png b/basic_materials/textures/basic_materials_brass_block.png new file mode 100644 index 0000000..c937800 Binary files /dev/null and b/basic_materials/textures/basic_materials_brass_block.png differ diff --git a/basic_materials/textures/basic_materials_brass_ingot.png b/basic_materials/textures/basic_materials_brass_ingot.png new file mode 100644 index 0000000..0bd030a Binary files /dev/null and b/basic_materials/textures/basic_materials_brass_ingot.png differ diff --git a/basic_materials/textures/basic_materials_cement_block.png b/basic_materials/textures/basic_materials_cement_block.png new file mode 100644 index 0000000..6d30f47 Binary files /dev/null and b/basic_materials/textures/basic_materials_cement_block.png differ diff --git a/basic_materials/textures/basic_materials_chain_brass.png b/basic_materials/textures/basic_materials_chain_brass.png new file mode 100644 index 0000000..e2fb20d Binary files /dev/null and b/basic_materials/textures/basic_materials_chain_brass.png differ diff --git a/basic_materials/textures/basic_materials_chain_brass_inv.png b/basic_materials/textures/basic_materials_chain_brass_inv.png new file mode 100644 index 0000000..8c2d554 Binary files /dev/null and b/basic_materials/textures/basic_materials_chain_brass_inv.png differ diff --git a/basic_materials/textures/basic_materials_chain_steel.png b/basic_materials/textures/basic_materials_chain_steel.png new file mode 100644 index 0000000..29af8db Binary files /dev/null and b/basic_materials/textures/basic_materials_chain_steel.png differ diff --git a/basic_materials/textures/basic_materials_chain_steel_inv.png b/basic_materials/textures/basic_materials_chain_steel_inv.png new file mode 100644 index 0000000..c552f7b Binary files /dev/null and b/basic_materials/textures/basic_materials_chain_steel_inv.png differ diff --git a/basic_materials/textures/basic_materials_chainlink_brass.png b/basic_materials/textures/basic_materials_chainlink_brass.png new file mode 100644 index 0000000..9a1ad87 Binary files /dev/null and b/basic_materials/textures/basic_materials_chainlink_brass.png differ diff --git a/basic_materials/textures/basic_materials_chainlink_steel.png b/basic_materials/textures/basic_materials_chainlink_steel.png new file mode 100644 index 0000000..d7132c3 Binary files /dev/null and b/basic_materials/textures/basic_materials_chainlink_steel.png differ diff --git a/basic_materials/textures/basic_materials_concrete_block.png b/basic_materials/textures/basic_materials_concrete_block.png new file mode 100644 index 0000000..5dd0d66 Binary files /dev/null and b/basic_materials/textures/basic_materials_concrete_block.png differ diff --git a/basic_materials/textures/basic_materials_copper_strip.png b/basic_materials/textures/basic_materials_copper_strip.png new file mode 100644 index 0000000..22e572a Binary files /dev/null and b/basic_materials/textures/basic_materials_copper_strip.png differ diff --git a/basic_materials/textures/basic_materials_copper_wire.png b/basic_materials/textures/basic_materials_copper_wire.png new file mode 100644 index 0000000..9df9f36 Binary files /dev/null and b/basic_materials/textures/basic_materials_copper_wire.png differ diff --git a/basic_materials/textures/basic_materials_empty_spool.png b/basic_materials/textures/basic_materials_empty_spool.png new file mode 100644 index 0000000..017a94f Binary files /dev/null and b/basic_materials/textures/basic_materials_empty_spool.png differ diff --git a/basic_materials/textures/basic_materials_energy_crystal.png b/basic_materials/textures/basic_materials_energy_crystal.png new file mode 100644 index 0000000..f1c28e8 Binary files /dev/null and b/basic_materials/textures/basic_materials_energy_crystal.png differ diff --git a/basic_materials/textures/basic_materials_gear_steel.png b/basic_materials/textures/basic_materials_gear_steel.png new file mode 100644 index 0000000..584f9a5 Binary files /dev/null and b/basic_materials/textures/basic_materials_gear_steel.png differ diff --git a/basic_materials/textures/basic_materials_gold_wire.png b/basic_materials/textures/basic_materials_gold_wire.png new file mode 100644 index 0000000..781de7b Binary files /dev/null and b/basic_materials/textures/basic_materials_gold_wire.png differ diff --git a/basic_materials/textures/basic_materials_heating_element.png b/basic_materials/textures/basic_materials_heating_element.png new file mode 100644 index 0000000..42e00b7 Binary files /dev/null and b/basic_materials/textures/basic_materials_heating_element.png differ diff --git a/basic_materials/textures/basic_materials_ic.png b/basic_materials/textures/basic_materials_ic.png new file mode 100644 index 0000000..4c88894 Binary files /dev/null and b/basic_materials/textures/basic_materials_ic.png differ diff --git a/basic_materials/textures/basic_materials_motor.png b/basic_materials/textures/basic_materials_motor.png new file mode 100644 index 0000000..f19ec0a Binary files /dev/null and b/basic_materials/textures/basic_materials_motor.png differ diff --git a/basic_materials/textures/basic_materials_oil_extract.png b/basic_materials/textures/basic_materials_oil_extract.png new file mode 100644 index 0000000..e34623d Binary files /dev/null and b/basic_materials/textures/basic_materials_oil_extract.png differ diff --git a/basic_materials/textures/basic_materials_padlock.png b/basic_materials/textures/basic_materials_padlock.png new file mode 100644 index 0000000..b05b7ef Binary files /dev/null and b/basic_materials/textures/basic_materials_padlock.png differ diff --git a/basic_materials/textures/basic_materials_paraffin.png b/basic_materials/textures/basic_materials_paraffin.png new file mode 100644 index 0000000..77d2bbd Binary files /dev/null and b/basic_materials/textures/basic_materials_paraffin.png differ diff --git a/basic_materials/textures/basic_materials_plastic_sheet.png b/basic_materials/textures/basic_materials_plastic_sheet.png new file mode 100644 index 0000000..034dcc2 Binary files /dev/null and b/basic_materials/textures/basic_materials_plastic_sheet.png differ diff --git a/basic_materials/textures/basic_materials_plastic_strip.png b/basic_materials/textures/basic_materials_plastic_strip.png new file mode 100644 index 0000000..1318dfc Binary files /dev/null and b/basic_materials/textures/basic_materials_plastic_strip.png differ diff --git a/basic_materials/textures/basic_materials_silicon.png b/basic_materials/textures/basic_materials_silicon.png new file mode 100644 index 0000000..847b366 Binary files /dev/null and b/basic_materials/textures/basic_materials_silicon.png differ diff --git a/basic_materials/textures/basic_materials_silver_wire.png b/basic_materials/textures/basic_materials_silver_wire.png new file mode 100644 index 0000000..a38a45e Binary files /dev/null and b/basic_materials/textures/basic_materials_silver_wire.png differ diff --git a/basic_materials/textures/basic_materials_steel_bar.png b/basic_materials/textures/basic_materials_steel_bar.png new file mode 100644 index 0000000..0673b6e Binary files /dev/null and b/basic_materials/textures/basic_materials_steel_bar.png differ diff --git a/basic_materials/textures/basic_materials_steel_strip.png b/basic_materials/textures/basic_materials_steel_strip.png new file mode 100644 index 0000000..6384dc8 Binary files /dev/null and b/basic_materials/textures/basic_materials_steel_strip.png differ diff --git a/basic_materials/textures/basic_materials_steel_wire.png b/basic_materials/textures/basic_materials_steel_wire.png new file mode 100644 index 0000000..0c96c8f Binary files /dev/null and b/basic_materials/textures/basic_materials_steel_wire.png differ diff --git a/basic_materials/textures/basic_materials_terracotta_base.png b/basic_materials/textures/basic_materials_terracotta_base.png new file mode 100644 index 0000000..9f04aad Binary files /dev/null and b/basic_materials/textures/basic_materials_terracotta_base.png differ diff --git a/basic_materials/textures/basic_materials_wet_cement.png b/basic_materials/textures/basic_materials_wet_cement.png new file mode 100644 index 0000000..6a7fbf1 Binary files /dev/null and b/basic_materials/textures/basic_materials_wet_cement.png differ diff --git a/ta4_addons/README.md b/ta4_addons/README.md index 87db92d..6a89f98 100644 --- a/ta4_addons/README.md +++ b/ta4_addons/README.md @@ -8,8 +8,29 @@ Currently, the following devices are implemented: ## License -Copyright (C) 2020 Joachim Stolberg -Copyright (C) 2020 Thomas-S +Copyright (C) 2020-2021 Joachim Stolberg +Copyright (C) 2020-2021 Thomas-S + +### Code +Licensed under the GNU AGPL version 3 or later. See `LICENSE.txt`. + +The only exception is the file `markdown2lua.py` (by Joachim Stolberg), which is licensed under the GNU GPL version 3 or later. +See `LICENSE_GPL.txt`. +It is taken from the [ta4_jetpack](https://github.com/joe7575/ta4_jetpack) mod. + +### Textures + +`ta4_addons_touchscreen.png`: +Based on [techage_display.png](https://github.com/joe7575/techage/blob/master/textures/techage_display.png) by Joachim Stolberg, published under the CC BY-SA 3.0 license. +Modifications were made by Thomas-S. + +`ta4_addons_touchscreen_inventory.png`, `ta4_addons_matrix_screen_inventory.png`, `ta4_addons_appl_matrix_screen.png`: +Based on [techage_display_inventory.png](https://github.com/joe7575/techage/blob/master/textures/techage_display_inventory.png) by Joachim Stolberg, published under the CC BY-SA 3.0 license. +Modifications were made by Thomas-S. + +Everything else: +CC BY-SA 3.0 by Thomas-S + ## Example Program for the Lua Controller @@ -55,23 +76,3 @@ if num == tostring(TOUCHSCREEN_NUM) and msg.next then end ``` -### Code -Licensed under the GNU AGPL version 3 or later. See `LICENSE.txt`. - -The only exception is the file `markdown2lua.py` (by Joachim Stolberg), which is licensed under the GNU GPL version 3 or later. -See `LICENSE_GPL.txt`. -It is taken from the [ta4_jetpack](https://github.com/joe7575/ta4_jetpack) mod. - -### Textures - -`ta4_addons_touchscreen.png`: -Based on [techage_display.png](https://github.com/joe7575/techage/blob/master/textures/techage_display.png) by Joachim Stolberg, published under the CC BY-SA 3.0 license. -Modifications were made by Thomas-S. - -`ta4_addons_touchscreen_inventory.png`: -Based on [techage_display_inventory.png](https://github.com/joe7575/techage/blob/master/textures/techage_display_inventory.png) by Joachim Stolberg, published under the CC BY-SA 3.0 license. -Modifications were made by Thomas-S. - -Everything else: -CC BY-SA 3.0 by Thomas-S - diff --git a/ta4_addons/generate_pixels.py b/ta4_addons/generate_pixels.py new file mode 100644 index 0000000..76af5fc --- /dev/null +++ b/ta4_addons/generate_pixels.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from PIL import Image + +colors = [ + "000000", "000055", "0000aa", "0000ff", "550000", "550055", "5500aa", "5500ff", + "aa0000", "aa0055", "aa00aa", "aa00ff", "ff0000", "ff0055", "ff00aa", "ff00ff", + "005500", "005555", "0055aa", "0055ff", "555500", "555555", "5555aa", "5555ff", + "aa5500", "aa5555", "aa55aa", "aa55ff", "ff5500", "ff5555", "ff55aa", "ff55ff", + "00aa00", "00aa55", "00aaaa", "00aaff", "55aa00", "55aa55", "55aaaa", "55aaff", + "aaaa00", "aaaa55", "aaaaaa", "aaaaff", "ffaa00", "ffaa55", "ffaaaa", "ffaaff", + "00ff00", "00ff55", "00ffaa", "00ffff", "55ff00", "55ff55", "55ffaa", "55ffff", + "aaff00", "aaff55", "aaffaa", "aaffff", "ffff00", "ffff55", "ffffaa", "ffffff", +] + +for idx,color in enumerate(colors): + img = Image.new('RGB', (1,1), color="#"+color) + img.save("textures/px"+str(idx+1)+".png") + diff --git a/ta4_addons/init.lua b/ta4_addons/init.lua index b47936c..8e3c2b9 100644 --- a/ta4_addons/init.lua +++ b/ta4_addons/init.lua @@ -3,8 +3,8 @@ TA4 Addons ========== - Copyright (C) 2020 Joachim Stolberg - Copyright (C) 2020 Thomas S. + Copyright (C) 2020-2021 Joachim Stolberg + Copyright (C) 2020-2021 Thomas S. GPL v3 See LICENSE.txt for more information @@ -22,9 +22,11 @@ ta4_addons.S = minetest.get_translator("ta4_addons") local MP = minetest.get_modpath("ta4_addons") dofile(MP.."/touchscreen/main.lua") -- Touchscreen +dofile(MP.."/matrix_screen/main.lua") -- Matrix Screen dofile(MP.."/manual_DE.lua") -- Techage Manual DE dofile(MP.."/manual_EN.lua") -- Techage Manual EN techage.add_manual_items({ta4_addons_touchscreen = "ta4_addons_touchscreen_inventory.png"}) +techage.add_manual_items({ta4_addons_matrix_screen = "ta4_addons_matrix_screen_inventory.png"}) diff --git a/ta4_addons/manual_DE.lua b/ta4_addons/manual_DE.lua index 4373bed..2e861ed 100644 --- a/ta4_addons/manual_DE.lua +++ b/ta4_addons/manual_DE.lua @@ -2,6 +2,7 @@ techage.add_to_manual('DE', { "1,TA4 Addons", "2,Touchscreen", "3,Unterstützte Elemente und ihre Eigenschaften", + "2,Matrix Screen", }, { "Aktuell sind folgende Erweiterungen für TA4 verfügbar:\n".. "\n".. @@ -56,12 +57,26 @@ techage.add_to_manual('DE', { "\n".. "Für weitere Informationen über die Bedeutung dieser Elemente sei die Datei lua_api.txt des Minetest-Projekts empfohlen.\n".. "\n", + "\n".. + "\n".. + "Der Matrix Screen ist eine 16x16px-Anzeige.\n".. + "Es stehen verschiedene Paletten mit je 64 Farben zur Verfügung.\n".. + "\n".. + "Zum Programmieren der Anzeige wird ein Base64-codierter String als Payload des Befehls \"pixels\" gesendet.\n".. + "Dieser String muss 256 Zeichen umfassen\\, wobei jedes Zeichen einem Pixel entspricht (zeilenweise von links oben nach rechts unten).\n".. + "\n".. + "Zum einfachen Erstellen solcher Strings sei der TA4 Matrix Screen Programmer empfohlen.\n".. + "\n".. + "Die verwendete Farbpalette kann über den Befehl \"palette\" geändert werden.\n".. + "\n", }, { "", "ta4_addons_touchscreen", "ta4_addons_touchscreen", + "ta4_addons_matrix_screen", }, { "", "", "", + "", }) diff --git a/ta4_addons/manual_DE.md b/ta4_addons/manual_DE.md index b70613a..aed800f 100644 --- a/ta4_addons/manual_DE.md +++ b/ta4_addons/manual_DE.md @@ -54,4 +54,18 @@ image_button_exit: x, y, w, h, texture_name, name, label box: x, y, w, h, color checkbox: x, y, name, label, selected -Für weitere Informationen über die Bedeutung dieser Elemente sei die Datei lua_api.txt des Minetest-Projekts empfohlen. \ No newline at end of file +Für weitere Informationen über die Bedeutung dieser Elemente sei die Datei lua_api.txt des Minetest-Projekts empfohlen. + +## Matrix Screen + +[ta4_addons_matrix_screen|image] + +Der Matrix Screen ist eine 16x16px-Anzeige. +Es stehen verschiedene Paletten mit je 64 Farben zur Verfügung. + +Zum Programmieren der Anzeige wird ein Base64-codierter String als Payload des Befehls "pixels" gesendet. +Dieser String muss 256 Zeichen umfassen, wobei jedes Zeichen einem Pixel entspricht (zeilenweise von links oben nach rechts unten). + +Zum einfachen Erstellen solcher Strings sei der TA4 Matrix Screen Programmer empfohlen. + +Die verwendete Farbpalette kann über den Befehl "palette" geändert werden. diff --git a/ta4_addons/manual_EN.lua b/ta4_addons/manual_EN.lua index 5c8a7b1..1f343d3 100644 --- a/ta4_addons/manual_EN.lua +++ b/ta4_addons/manual_EN.lua @@ -2,6 +2,7 @@ techage.add_to_manual('EN', { "1,TA4 Addons", "2,Touchscreen", "3,Supported Elements and their properties", + "2,Matrix Screen", }, { "Currently\\, the following extensions for TA4 are available:\n".. "\n".. @@ -56,12 +57,26 @@ techage.add_to_manual('EN', { "\n".. "For further information of the meaning of these elements\\, please consult Minetest's lua_api.txt.\n".. "\n", + "\n".. + "\n".. + "The matrix screen is a 16x16px display.\n".. + "Different palettes with 64 colors each are available.\n".. + "\n".. + "To program the display\\, you can send a base64 encoded string as a payload for the \"pixels\" command.\n".. + "This string has to be 256 characters long. Each character corresponds to a pixel\\, line by line from the upper left-hand corner to the lower right-hand corner. \n".. + "\n".. + "It is recommended to use the TA4 Matrix Screen Programmer in order to create such strings easily.\n".. + "\n".. + "The color palette can be changed with the \"palette\" command.\n".. + "\n", }, { "", "ta4_addons_touchscreen", "ta4_addons_touchscreen", + "ta4_addons_matrix_screen", }, { "", "", "", + "", }) diff --git a/ta4_addons/manual_EN.md b/ta4_addons/manual_EN.md index b4d6c71..6bd656c 100644 --- a/ta4_addons/manual_EN.md +++ b/ta4_addons/manual_EN.md @@ -54,4 +54,18 @@ image_button_exit: x, y, w, h, texture_name, name, label box: x, y, w, h, color checkbox: x, y, name, label, selected -For further information of the meaning of these elements, please consult Minetest's lua_api.txt. \ No newline at end of file +For further information of the meaning of these elements, please consult Minetest's lua_api.txt. + +## Matrix Screen + +[ta4_addons_matrix_screen|image] + +The matrix screen is a 16x16px display. +Different palettes with 64 colors each are available. + +To program the display, you can send a base64 encoded string as a payload for the "pixels" command. +This string has to be 256 characters long. Each character corresponds to a pixel, line by line from the upper left-hand corner to the lower right-hand corner. + +It is recommended to use the TA4 Matrix Screen Programmer in order to create such strings easily. + +The color palette can be changed with the "palette" command. diff --git a/ta4_addons/matrix_screen/main.lua b/ta4_addons/matrix_screen/main.lua new file mode 100644 index 0000000..b25fdc7 --- /dev/null +++ b/ta4_addons/matrix_screen/main.lua @@ -0,0 +1,462 @@ +--[[ + + TA4 Addons + ========== + + Copyright (C) 2020-2021 Joachim Stolberg + Copyright (C) 2020-2021 Thomas S. + + AGPL v3 + See LICENSE.txt for more information + + Matrix Screen + +]]-- + +local S = ta4_addons.S +local M = minetest.get_meta +local N = techage.get_nvm + +local letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" +local letters_to_idx = {} +for idx = 1,64 do + letters_to_idx[letters:sub(idx, idx)] = idx +end + +local function letter_to_idx(letter) + return letters_to_idx[letter] or 1 +end + +local palettes = { + "rgb6bit",-- "resurrect64", "aap64", "sweet_canyon_extended", "endesga64" +} + +local palettes_to_idx = {} + +for k,v in ipairs(palettes) do + palettes_to_idx[v] = k +end + +local rgb6bit_palette = { + "000000", "000055", "0000aa", "0000ff", "550000", "550055", "5500aa", "5500ff", + "aa0000", "aa0055", "aa00aa", "aa00ff", "ff0000", "ff0055", "ff00aa", "ff00ff", + "005500", "005555", "0055aa", "0055ff", "555500", "555555", "5555aa", "5555ff", + "aa5500", "aa5555", "aa55aa", "aa55ff", "ff5500", "ff5555", "ff55aa", "ff55ff", + "00aa00", "00aa55", "00aaaa", "00aaff", "55aa00", "55aa55", "55aaaa", "55aaff", + "aaaa00", "aaaa55", "aaaaaa", "aaaaff", "ffaa00", "ffaa55", "ffaaaa", "ffaaff", + "00ff00", "00ff55", "00ffaa", "00ffff", "55ff00", "55ff55", "55ffaa", "55ffff", + "aaff00", "aaff55", "aaffaa", "aaffff", "ffff00", "ffff55", "ffffaa", "ffffff", +} + +-- Source: https://lospec.com/palette-list/resurrect-64 +local resurrect64_palette = { + "2e222f", "3e3546", "625565", "966c6c", "ab947a", "694f62", "7f708a", "9babb2", + "c7dcd0", "ffffff", "6e2727", "b33831", "ea4f36", "f57d4a", "ae2334", "e83b3b", + "fb6b1d", "f79617", "f9c22b", "7a3045", "9e4539", "cd683d", "e6904e", "fbb954", + "4c3e24", "676633", "a2a947", "d5e04b", "fbff86", "165a4c", "239063", "1ebc73", + "91db69", "cddf6c", "313638", "374e4a", "547e64", "92a984", "b2ba90", "0b5e65", + "0b8a8f", "0eaf9b", "30e1b9", "8ff8e2", "323353", "484a77", "4d65b4", "4d9be6", + "8fd3ff", "45293f", "6b3e75", "905ea9", "a884f3", "eaaded", "753c54", "a24b6f", + "cf657f", "ed8099", "831c5d", "c32454", "f04f78", "f68181", "fca790", "fdcbb0", +} + +-- Source: https://lospec.com/palette-list/aap-64 +local aap64_palette = { + "060608", "141013", "3b1725", "73172d", "b4202a", "df3e23", "fa6a0a", "f9a31b", + "ffd541", "fffc40", "d6f264", "9cdb43", "59c135", "14a02e", "1a7a3e", "24523b", + "122020", "143464", "285cc4", "249fde", "20d6c7", "a6fcdb", "ffffff", "fef3c0", + "fad6b8", "f5a097", "e86a73", "bc4a9b", "793a80", "403353", "242234", "221c1a", + "322b28", "71413b", "bb7547", "dba463", "f4d29c", "dae0ea", "b3b9d1", "8b93af", + "6d758d", "4a5462", "333941", "422433", "5b3138", "8e5252", "ba756a", "e9b5a3", + "e3e6ff", "b9bffb", "849be4", "588dbe", "477d85", "23674e", "328464", "5daf8d", + "92dcba", "cdf7e2", "e4d2aa", "c7b08b", "a08662", "796755", "5a4e44", "423934", +} + +-- Source: https://lospec.com/palette-list/sweet-canyon-extended-64 +local sweet_canyon_extended_palette = { + "0f0e11", "2d2c33", "40404a", "51545c", "6b7179", "7c8389", "a8b2b6", "d5d5d5", + "eeebe0", "f1dbb1", "eec99f", "e1a17e", "cc9562", "ab7b49", "9a643a", "86482f", + "783a29", "6a3328", "541d29", "42192c", "512240", "782349", "8b2e5d", "a93e89", + "d062c8", "ec94ea", "f2bdfc", "eaebff", "a2fafa", "64e7e7", "54cfd8", "2fb6c3", + "2c89af", "25739d", "2a5684", "214574", "1f2966", "101445", "3c0d3b", "66164c", + "901f3d", "bb3030", "dc473c", "ec6a45", "fb9b41", "f0c04c", "f4d66e", "fffb76", + "ccf17a", "97d948", "6fba3b", "229443", "1d7e45", "116548", "0c4f3f", "0a3639", + "251746", "48246d", "69189c", "9f20c0", "e527d2", "ff51cf", "ff7ada", "ff9edb", +} + +-- Source: https://lospec.com/palette-list/endesga-64 +local endesga64_palette = { + "ff0040", "131313", "1b1b1b", "272727", "3d3d3d", "5d5d5d", "858585", "b4b4b4", + "ffffff", "c7cfdd", "92a1b9", "657392", "424c6e", "2a2f4e", "1a1932", "0e071b", + "1c121c", "391f21", "5d2c28", "8a4836", "bf6f4a", "e69c69", "f6ca9f", "f9e6cf", + "edab50", "e07438", "c64524", "8e251d", "ff5000", "ed7614", "ffa214", "ffc825", + "ffeb57", "d3fc7e", "99e65f", "5ac54f", "33984b", "1e6f50", "134c4c", "0c2e44", + "00396d", "0069aa", "0098dc", "00cdf9", "0cf1ff", "94fdff", "fdd2ed", "f389f5", + "db3ffd", "7a09fa", "3003d9", "0c0293", "03193f", "3b1443", "622461", "93388f", + "ca52c9", "c85086", "f68187", "f5555d", "ea323c", "c42430", "891e2b", "571c27", +} + +local function rgb6bit(idx) + return rgb6bit_palette[idx] +end + +local function resurrect64(idx) + return resurrect64_palette[idx] +end + +local function aap64(idx) + return aap64_palette[idx] +end + +local function sweet_canyon_extended(idx) + return sweet_canyon_extended_palette[idx] +end + +local function endesga64(idx) + return endesga64_palette[idx] +end + +local function get_palette(palette_name) + --if palette_name == "resurrect64" then + -- return resurrect64 + --elseif palette_name == "aap64" then + -- return aap64 + --elseif palette_name == "sweet_canyon_extended" then + -- return sweet_canyon_extended + --elseif palette_name == "endesga64" then + -- return endesga64 + --end + return rgb6bit +end + +local function string_to_indices(input_string) + input_string = input_string:gsub("%s", "") -- Ignore space characters + input_string = input_string:sub(1, 256) -- Limit to 256 chars at max + input_string = input_string..string.rep("A", 256-#input_string) -- Fill up to reach 256 chars + local result = {} + for i = 1,#input_string do + result[i] = letter_to_idx(input_string:sub(i, i)) + end + return result +end + +local function string_to_colors(input_string, palette_name) + local palette_func = get_palette(palette_name) + local indices = string_to_indices(input_string) + local result = {} + for i = 1,#indices do + result[i] = palette_func(indices[i]) + end + return result +end + +local function generate_texture_from_color_list(colors) + local texture = {"[combine:16x16"} + local x, y = 0, 0 + for _,color in ipairs(colors) do + texture[#texture+1] = ":" + texture[#texture+1] = x + texture[#texture+1] = "," + texture[#texture+1] = y + texture[#texture+1] = "=px.png\\^[colorize\\:#" + texture[#texture+1] = color + x = x + 1 + if x >= 16 then + x = 0 + y = y + 1 + end + end + texture[#texture+1] = "^[resize:128x128^ta4_addons_matrix_screen_overlay.png" + return table.concat(texture, "") +end + +local function generate_texture_from_indices(indices) + local texture = {"[combine:16x16:0,0=px_bg.png"} + local x, y = 0, 0 + for _,index in ipairs(indices) do + if index ~=1 then + texture[#texture+1] = ":" + texture[#texture+1] = x + texture[#texture+1] = "," + texture[#texture+1] = y + texture[#texture+1] = "=px" + texture[#texture+1] = index + texture[#texture+1] = ".png" + end + x = x + 1 + if x >= 16 then + x = 0 + y = y + 1 + end + end + texture[#texture+1] = "^[resize:128x128^ta4_addons_matrix_screen_overlay.png" + return table.concat(texture, "") +end + +local function string_to_table(input_string) + local indices = string_to_indices(input_string) + local t = {} + local x, y = 0, 0 + for i = 1,#indices do + t[y] = t[y] or {} + t[y][x] = indices[i] + x = x + 1 + if x >= 16 then + x = 0 + y = y + 1 + end + end + return t +end + +ta4_addons.base64_to_texture = function(color_string, palette) + --return generate_texture_from_color_list(string_to_colors(color_string, palette)) + return generate_texture_from_indices(string_to_indices(color_string)) +end + +local function update_matrix_display(pos, objref) + pos = vector.round(pos) + local nvm = N(pos) + objref:set_properties({ + textures = { ta4_addons.base64_to_texture(nvm.color_string or "", nvm.palette) }, + }) +end + +minetest.register_node("ta4_addons:matrix_screen", { + description = S("TA4 Matrix Screen"), + inventory_image = "ta4_addons_matrix_screen_inventory.png", + tiles = {"ta4_addons_matrix_screen.png"}, + drawtype = "nodebox", + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "wallmounted", + node_box = techage.display.lcd_box, + selection_box = techage.display.lcd_box, + light_source = 6, + + display_entities = { + ["techage:display_entity"] = { + depth = 0.42, + on_display_update = update_matrix_display + }, + }, + + after_place_node = function(pos, placer) + local number = techage.add_node(pos, "ta4_addons:matrix_screen") + local meta = M(pos) + meta:set_string("node_number", number) + meta:set_string("infotext", S("Matrix Screen no: ")..number) + local nvm = techage.get_nvm(pos) + nvm.color_string = "AABBCCDDEEFFGGHHAABBCCDDEEFFGGHH" + .. "IIJJKKLLMMNNOOPPIIJJKKLLMMNNOOPP" + .. "QQRRSSTTUUVVWWXXQQRRSSTTUUVVWWXX" + .. "YYZZaabbccddeeffYYZZaabbccddeeff" + .. "gghhiijjkkllmmnngghhiijjkkllmmnn" + .. "ooppqqrrssttuuvvooppqqrrssttuuvv" + .. "wwxxyyzz00112233wwxxyyzz00112233" + .. "445566778899++//445566778899++//" + lcdlib.update_entities(pos) + minetest.get_node_timer(pos):start(2) + end, + + after_dig_node = function(pos, oldnode, oldmetadata) + techage.remove_node(pos, oldnode, oldmetadata) + end, + + on_timer = techage.display.on_timer, + on_place = lcdlib.on_place, + on_construct = lcdlib.on_construct, + on_destruct = lcdlib.on_destruct, + on_rotate = lcdlib.on_rotate, + groups = {cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_glass_defaults(), +}) + +minetest.register_craft({ + output = "ta4_addons:matrix_screen", + recipe = { + {"dye:red", "dye:green", "dye:blue"}, + {"default:copper_ingot", "techage:ta4_display", "default:copper_ingot"}, + {"", "default:mese_crystal_fragment", ""}, + }, +}) + +techage.register_node({"ta4_addons:matrix_screen"}, { + on_recv_message = function(pos, src, topic, payload) + local mem = techage.get_mem(pos) + mem.ticks = mem.ticks or 0 + + if mem.ticks == 0 then + mem.ticks = 1 + end + + if topic == "pixels" then + N(pos).color_string = tostring(payload) + elseif topic == "palette" then + N(pos).palette = tostring(payload) + end + end, +}) + +local function generate_px_button(x, y, i, palette_func, name) + return "image_button["..x..","..y..";.5,.5;px.png^[colorize:#"..palette_func(i)..";"..name..";"..letters:sub(i,i).."]" +end + +local function get_px_val(nvm, x, y) + return ((nvm.px or {})[y] or {})[x] or 1 +end + +local function generate_base64(nvm) + local result = "" + for y=0,15 do + for x=0,15 do + local i = get_px_val(nvm, x, y) + result = result..letters:sub(i,i) + end + result = result.." " + end + return result:sub(1,-2) +end + +local function update_fs(pos) + local nvm = N(pos) + local palette = nvm.palette or "rgb6bit" + local palette_func = get_palette(palette) + local current_idx = nvm.current_idx or 1 + local fs = "formspec_version[4]size[18,12]" + fs = fs.."label[0.5,.75;Palette:]" + fs = fs.."dropdown[2,.5;3,.5;palette;"..table.concat(palettes, ",")..";"..(palettes_to_idx[palette] or 1).."]" + local x = .5 + local y = 1.5 + for i = 1,64 do + fs = fs..generate_px_button(x, y, i, palette_func, "color_idx_"..i) + x = x + .6 + if x > 2.5 then + x = .5 + y = y + .6 + end + end + for y_px = 0,15 do + for x_px = 0,15 do + fs = fs..generate_px_button(3.5+x_px*.6, 1.5+y_px*.6, get_px_val(nvm, x_px, y_px), palette_func, "px_"..x_px.."_"..y_px) + end + end + fs = fs.."label[13.5,.75;Current Color:]" + fs = fs..generate_px_button(17, .5, current_idx, palette_func, "current_color") + fs = fs.."style_type[textarea;font=mono]" + fs = fs.."textarea[13.5,4.5;4,5;base64;Base64 string:;"..generate_base64(nvm).."]" + fs = fs.."button[16.5,9.5;1,.5;read_base64;Read]" + fs = fs.."field[13.5,10.5;3,1;target;Target Techage Number:;"..minetest.formspec_escape(nvm.target or "").."]" + fs = fs.."button[16.5,10.5;1,1;send_cmnd;Send]" + M(pos):set_string("formspec", fs) +end + +minetest.register_node("ta4_addons:matrix_screen_programmer", { + description = S("TA4 Matrix Screen Programmer"), + tiles = { + -- up, down, right, left, back, front + "techage_filling_ta4.png^techage_frame_ta4_top.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4.png", + "techage_filling_ta4.png^techage_frame_ta4.png^ta4_addons_appl_matrix_screen.png", + }, + drawtype = "normal", + paramtype = "light", + paramtype2 = "facedir", + on_construct = function(pos) + update_fs(pos) + M(pos):set_string("infotext", S("TA4 Matrix Screen Programmer")) + end, + after_place_node = function(pos, placer) + local number = techage.add_node(pos, "ta4_addons:matrix_screen_programmer") + local meta = M(pos) + meta:set_string("node_number", number) + meta:set_string("infotext", S("Matrix Screen Programmer ")..number) + end, + after_dig_node = function(pos, oldnode, oldmetadata) + techage.remove_node(pos, oldnode, oldmetadata) + end, + groups = {cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_metal_defaults(), + on_receive_fields = function (pos, formname, fields, sender) + local player_name = sender:get_player_name() + if minetest.is_protected(pos, player_name) then + return + end + local nvm = N(pos) + for i=1,64 do + if fields["color_idx_"..i] then + nvm.current_idx = i + end + end + for y=0,15 do + for x=0,15 do + if fields["px_"..x.."_"..y] then + nvm.px = nvm.px or {} + nvm.px[y] = nvm.px[y] or {} + nvm.px[y][x] = nvm.current_idx + end + end + end + if fields.read_base64 and fields.base64 then + nvm.px = string_to_table(fields.base64) + end + if fields.send_cmnd and fields.target and techage.check_numbers(fields.target, player_name) then + nvm.target = fields.target + local own_number = M(pos):get_string("node_number") + if not own_number or own_number == "" then + own_number = "0" + end + techage.send_multi(own_number, fields.target, "palette", nvm.palette or "rgb6bit") + techage.send_multi(own_number, fields.target, "pixels", generate_base64(nvm)) + end + if fields.palette then + nvm.palette = fields.palette + end + update_fs(pos) + end +}) + +techage.register_node({"ta4_addons:matrix_screen_programmer"}, { + on_recv_message = function(pos, src, topic, payload) + local nvm = N(pos) + if topic == "on" then + local own_number = M(pos):get_string("node_number") + techage.send_multi(own_number, nvm.target, "pixels", generate_base64(nvm)) + techage.send_multi(own_number, nvm.target, "palette", nvm.palette or "rgb6bit") + end + end, +}) + +minetest.register_craft({ + output = "ta4_addons:matrix_screen_programmer", + recipe = { + {"default:steel_ingot", "techage:ta4_ramchip", "default:steel_ingot"}, + {"", "ta4_addons:matrix_screen", ""}, + {"default:steel_ingot", "techage:ta4_wlanchip", "default:steel_ingot"}, + }, +}) + +if techage.repair_number then + minetest.register_lbm({ + label = "Fix lost techage numbers for matrix screens", + name = "ta4_addons:repair_matrix_screen_numbers", + nodenames = {"ta4_addons:matrix_screen", "ta4_addons:matrix_screen_programmer"}, + action = function(pos, node) + techage.repair_number(pos) + end + }) +end + +minetest.register_lbm({ + label = "Fix lost timer for matrix screens", + name = "ta4_addons:repair_matrix_screen_timer", + nodenames = {"ta4_addons:matrix_screen"}, + action = function(pos, node) + minetest.get_node_timer(pos):start(2) + end +}) \ No newline at end of file diff --git a/ta4_addons/textures/px.png b/ta4_addons/textures/px.png new file mode 100644 index 0000000..d057ee3 Binary files /dev/null and b/ta4_addons/textures/px.png differ diff --git a/ta4_addons/textures/px1.png b/ta4_addons/textures/px1.png new file mode 100644 index 0000000..19b3f6a Binary files /dev/null and b/ta4_addons/textures/px1.png differ diff --git a/ta4_addons/textures/px10.png b/ta4_addons/textures/px10.png new file mode 100644 index 0000000..836752a Binary files /dev/null and b/ta4_addons/textures/px10.png differ diff --git a/ta4_addons/textures/px11.png b/ta4_addons/textures/px11.png new file mode 100644 index 0000000..25b2325 Binary files /dev/null and b/ta4_addons/textures/px11.png differ diff --git a/ta4_addons/textures/px12.png b/ta4_addons/textures/px12.png new file mode 100644 index 0000000..83a1832 Binary files /dev/null and b/ta4_addons/textures/px12.png differ diff --git a/ta4_addons/textures/px13.png b/ta4_addons/textures/px13.png new file mode 100644 index 0000000..62a5f8f Binary files /dev/null and b/ta4_addons/textures/px13.png differ diff --git a/ta4_addons/textures/px14.png b/ta4_addons/textures/px14.png new file mode 100644 index 0000000..8ac3712 Binary files /dev/null and b/ta4_addons/textures/px14.png differ diff --git a/ta4_addons/textures/px15.png b/ta4_addons/textures/px15.png new file mode 100644 index 0000000..6570303 Binary files /dev/null and b/ta4_addons/textures/px15.png differ diff --git a/ta4_addons/textures/px16.png b/ta4_addons/textures/px16.png new file mode 100644 index 0000000..f6cb70b Binary files /dev/null and b/ta4_addons/textures/px16.png differ diff --git a/ta4_addons/textures/px17.png b/ta4_addons/textures/px17.png new file mode 100644 index 0000000..9235ae3 Binary files /dev/null and b/ta4_addons/textures/px17.png differ diff --git a/ta4_addons/textures/px18.png b/ta4_addons/textures/px18.png new file mode 100644 index 0000000..5983ad2 Binary files /dev/null and b/ta4_addons/textures/px18.png differ diff --git a/ta4_addons/textures/px19.png b/ta4_addons/textures/px19.png new file mode 100644 index 0000000..4e301f8 Binary files /dev/null and b/ta4_addons/textures/px19.png differ diff --git a/ta4_addons/textures/px2.png b/ta4_addons/textures/px2.png new file mode 100644 index 0000000..c6ea63b Binary files /dev/null and b/ta4_addons/textures/px2.png differ diff --git a/ta4_addons/textures/px20.png b/ta4_addons/textures/px20.png new file mode 100644 index 0000000..91b10ac Binary files /dev/null and b/ta4_addons/textures/px20.png differ diff --git a/ta4_addons/textures/px21.png b/ta4_addons/textures/px21.png new file mode 100644 index 0000000..f8cd875 Binary files /dev/null and b/ta4_addons/textures/px21.png differ diff --git a/ta4_addons/textures/px22.png b/ta4_addons/textures/px22.png new file mode 100644 index 0000000..74e7365 Binary files /dev/null and b/ta4_addons/textures/px22.png differ diff --git a/ta4_addons/textures/px23.png b/ta4_addons/textures/px23.png new file mode 100644 index 0000000..697cfa4 Binary files /dev/null and b/ta4_addons/textures/px23.png differ diff --git a/ta4_addons/textures/px24.png b/ta4_addons/textures/px24.png new file mode 100644 index 0000000..482d299 Binary files /dev/null and b/ta4_addons/textures/px24.png differ diff --git a/ta4_addons/textures/px25.png b/ta4_addons/textures/px25.png new file mode 100644 index 0000000..583c769 Binary files /dev/null and b/ta4_addons/textures/px25.png differ diff --git a/ta4_addons/textures/px26.png b/ta4_addons/textures/px26.png new file mode 100644 index 0000000..14801a6 Binary files /dev/null and b/ta4_addons/textures/px26.png differ diff --git a/ta4_addons/textures/px27.png b/ta4_addons/textures/px27.png new file mode 100644 index 0000000..7e39815 Binary files /dev/null and b/ta4_addons/textures/px27.png differ diff --git a/ta4_addons/textures/px28.png b/ta4_addons/textures/px28.png new file mode 100644 index 0000000..6ecb893 Binary files /dev/null and b/ta4_addons/textures/px28.png differ diff --git a/ta4_addons/textures/px29.png b/ta4_addons/textures/px29.png new file mode 100644 index 0000000..f841b9b Binary files /dev/null and b/ta4_addons/textures/px29.png differ diff --git a/ta4_addons/textures/px3.png b/ta4_addons/textures/px3.png new file mode 100644 index 0000000..d325ef7 Binary files /dev/null and b/ta4_addons/textures/px3.png differ diff --git a/ta4_addons/textures/px30.png b/ta4_addons/textures/px30.png new file mode 100644 index 0000000..461394c Binary files /dev/null and b/ta4_addons/textures/px30.png differ diff --git a/ta4_addons/textures/px31.png b/ta4_addons/textures/px31.png new file mode 100644 index 0000000..7976a07 Binary files /dev/null and b/ta4_addons/textures/px31.png differ diff --git a/ta4_addons/textures/px32.png b/ta4_addons/textures/px32.png new file mode 100644 index 0000000..3d279b7 Binary files /dev/null and b/ta4_addons/textures/px32.png differ diff --git a/ta4_addons/textures/px33.png b/ta4_addons/textures/px33.png new file mode 100644 index 0000000..c31f012 Binary files /dev/null and b/ta4_addons/textures/px33.png differ diff --git a/ta4_addons/textures/px34.png b/ta4_addons/textures/px34.png new file mode 100644 index 0000000..bd6e4b8 Binary files /dev/null and b/ta4_addons/textures/px34.png differ diff --git a/ta4_addons/textures/px35.png b/ta4_addons/textures/px35.png new file mode 100644 index 0000000..2a34105 Binary files /dev/null and b/ta4_addons/textures/px35.png differ diff --git a/ta4_addons/textures/px36.png b/ta4_addons/textures/px36.png new file mode 100644 index 0000000..4a1ebbc Binary files /dev/null and b/ta4_addons/textures/px36.png differ diff --git a/ta4_addons/textures/px37.png b/ta4_addons/textures/px37.png new file mode 100644 index 0000000..934016e Binary files /dev/null and b/ta4_addons/textures/px37.png differ diff --git a/ta4_addons/textures/px38.png b/ta4_addons/textures/px38.png new file mode 100644 index 0000000..64ec437 Binary files /dev/null and b/ta4_addons/textures/px38.png differ diff --git a/ta4_addons/textures/px39.png b/ta4_addons/textures/px39.png new file mode 100644 index 0000000..3f319ec Binary files /dev/null and b/ta4_addons/textures/px39.png differ diff --git a/ta4_addons/textures/px4.png b/ta4_addons/textures/px4.png new file mode 100644 index 0000000..548a5b9 Binary files /dev/null and b/ta4_addons/textures/px4.png differ diff --git a/ta4_addons/textures/px40.png b/ta4_addons/textures/px40.png new file mode 100644 index 0000000..dad0224 Binary files /dev/null and b/ta4_addons/textures/px40.png differ diff --git a/ta4_addons/textures/px41.png b/ta4_addons/textures/px41.png new file mode 100644 index 0000000..cff5622 Binary files /dev/null and b/ta4_addons/textures/px41.png differ diff --git a/ta4_addons/textures/px42.png b/ta4_addons/textures/px42.png new file mode 100644 index 0000000..aadd5a5 Binary files /dev/null and b/ta4_addons/textures/px42.png differ diff --git a/ta4_addons/textures/px43.png b/ta4_addons/textures/px43.png new file mode 100644 index 0000000..bc6e629 Binary files /dev/null and b/ta4_addons/textures/px43.png differ diff --git a/ta4_addons/textures/px44.png b/ta4_addons/textures/px44.png new file mode 100644 index 0000000..a81e8b2 Binary files /dev/null and b/ta4_addons/textures/px44.png differ diff --git a/ta4_addons/textures/px45.png b/ta4_addons/textures/px45.png new file mode 100644 index 0000000..f3aee2f Binary files /dev/null and b/ta4_addons/textures/px45.png differ diff --git a/ta4_addons/textures/px46.png b/ta4_addons/textures/px46.png new file mode 100644 index 0000000..a3c53ac Binary files /dev/null and b/ta4_addons/textures/px46.png differ diff --git a/ta4_addons/textures/px47.png b/ta4_addons/textures/px47.png new file mode 100644 index 0000000..2880e98 Binary files /dev/null and b/ta4_addons/textures/px47.png differ diff --git a/ta4_addons/textures/px48.png b/ta4_addons/textures/px48.png new file mode 100644 index 0000000..835ec73 Binary files /dev/null and b/ta4_addons/textures/px48.png differ diff --git a/ta4_addons/textures/px49.png b/ta4_addons/textures/px49.png new file mode 100644 index 0000000..e970424 Binary files /dev/null and b/ta4_addons/textures/px49.png differ diff --git a/ta4_addons/textures/px5.png b/ta4_addons/textures/px5.png new file mode 100644 index 0000000..46d8f34 Binary files /dev/null and b/ta4_addons/textures/px5.png differ diff --git a/ta4_addons/textures/px50.png b/ta4_addons/textures/px50.png new file mode 100644 index 0000000..2a385f9 Binary files /dev/null and b/ta4_addons/textures/px50.png differ diff --git a/ta4_addons/textures/px51.png b/ta4_addons/textures/px51.png new file mode 100644 index 0000000..72d70d1 Binary files /dev/null and b/ta4_addons/textures/px51.png differ diff --git a/ta4_addons/textures/px52.png b/ta4_addons/textures/px52.png new file mode 100644 index 0000000..f2bf6d6 Binary files /dev/null and b/ta4_addons/textures/px52.png differ diff --git a/ta4_addons/textures/px53.png b/ta4_addons/textures/px53.png new file mode 100644 index 0000000..bfc0e1c Binary files /dev/null and b/ta4_addons/textures/px53.png differ diff --git a/ta4_addons/textures/px54.png b/ta4_addons/textures/px54.png new file mode 100644 index 0000000..7ecb742 Binary files /dev/null and b/ta4_addons/textures/px54.png differ diff --git a/ta4_addons/textures/px55.png b/ta4_addons/textures/px55.png new file mode 100644 index 0000000..164d9e2 Binary files /dev/null and b/ta4_addons/textures/px55.png differ diff --git a/ta4_addons/textures/px56.png b/ta4_addons/textures/px56.png new file mode 100644 index 0000000..8fc4b14 Binary files /dev/null and b/ta4_addons/textures/px56.png differ diff --git a/ta4_addons/textures/px57.png b/ta4_addons/textures/px57.png new file mode 100644 index 0000000..a0c2abb Binary files /dev/null and b/ta4_addons/textures/px57.png differ diff --git a/ta4_addons/textures/px58.png b/ta4_addons/textures/px58.png new file mode 100644 index 0000000..c7c55b1 Binary files /dev/null and b/ta4_addons/textures/px58.png differ diff --git a/ta4_addons/textures/px59.png b/ta4_addons/textures/px59.png new file mode 100644 index 0000000..ae66950 Binary files /dev/null and b/ta4_addons/textures/px59.png differ diff --git a/ta4_addons/textures/px6.png b/ta4_addons/textures/px6.png new file mode 100644 index 0000000..fa55860 Binary files /dev/null and b/ta4_addons/textures/px6.png differ diff --git a/ta4_addons/textures/px60.png b/ta4_addons/textures/px60.png new file mode 100644 index 0000000..726b328 Binary files /dev/null and b/ta4_addons/textures/px60.png differ diff --git a/ta4_addons/textures/px61.png b/ta4_addons/textures/px61.png new file mode 100644 index 0000000..bab6c7f Binary files /dev/null and b/ta4_addons/textures/px61.png differ diff --git a/ta4_addons/textures/px62.png b/ta4_addons/textures/px62.png new file mode 100644 index 0000000..0a0a7b5 Binary files /dev/null and b/ta4_addons/textures/px62.png differ diff --git a/ta4_addons/textures/px63.png b/ta4_addons/textures/px63.png new file mode 100644 index 0000000..0cc7701 Binary files /dev/null and b/ta4_addons/textures/px63.png differ diff --git a/ta4_addons/textures/px64.png b/ta4_addons/textures/px64.png new file mode 100644 index 0000000..94381b4 Binary files /dev/null and b/ta4_addons/textures/px64.png differ diff --git a/ta4_addons/textures/px7.png b/ta4_addons/textures/px7.png new file mode 100644 index 0000000..495f997 Binary files /dev/null and b/ta4_addons/textures/px7.png differ diff --git a/ta4_addons/textures/px8.png b/ta4_addons/textures/px8.png new file mode 100644 index 0000000..543e9bb Binary files /dev/null and b/ta4_addons/textures/px8.png differ diff --git a/ta4_addons/textures/px9.png b/ta4_addons/textures/px9.png new file mode 100644 index 0000000..fd908c1 Binary files /dev/null and b/ta4_addons/textures/px9.png differ diff --git a/ta4_addons/textures/px_bg.png b/ta4_addons/textures/px_bg.png new file mode 100644 index 0000000..1a80c40 Binary files /dev/null and b/ta4_addons/textures/px_bg.png differ diff --git a/ta4_addons/textures/ta4_addons_appl_matrix_screen.png b/ta4_addons/textures/ta4_addons_appl_matrix_screen.png new file mode 100644 index 0000000..6f2fc3d Binary files /dev/null and b/ta4_addons/textures/ta4_addons_appl_matrix_screen.png differ diff --git a/ta4_addons/textures/ta4_addons_matrix_screen.png b/ta4_addons/textures/ta4_addons_matrix_screen.png new file mode 100644 index 0000000..e5575cc Binary files /dev/null and b/ta4_addons/textures/ta4_addons_matrix_screen.png differ diff --git a/ta4_addons/textures/ta4_addons_matrix_screen_inventory.png b/ta4_addons/textures/ta4_addons_matrix_screen_inventory.png new file mode 100644 index 0000000..6010178 Binary files /dev/null and b/ta4_addons/textures/ta4_addons_matrix_screen_inventory.png differ diff --git a/ta4_addons/textures/ta4_addons_matrix_screen_overlay.png b/ta4_addons/textures/ta4_addons_matrix_screen_overlay.png new file mode 100644 index 0000000..11752c2 Binary files /dev/null and b/ta4_addons/textures/ta4_addons_matrix_screen_overlay.png differ diff --git a/ta4_addons/touchscreen/main.lua b/ta4_addons/touchscreen/main.lua index 6674d8a..5524c49 100644 --- a/ta4_addons/touchscreen/main.lua +++ b/ta4_addons/touchscreen/main.lua @@ -3,8 +3,8 @@ TA4 Addons ========== - Copyright (C) 2020 Joachim Stolberg - Copyright (C) 2020 Thomas S. + Copyright (C) 2020-2021 Joachim Stolberg + Copyright (C) 2020-2021 Thomas S. AGPL v3 See LICENSE.txt for more information @@ -18,329 +18,329 @@ local M = minetest.get_meta local N = techage.get_nvm local function get_value(element, key, default) - return minetest.formspec_escape(element.get(key) or default) + return minetest.formspec_escape(element.get(key) or default) end local function parse_payload(payload) - local element_type = payload.get("type") - if type(element_type) ~= "string" then - return - end - element_type = string.lower(element_type) - if element_type == "button" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 2) - local h = get_value(payload, "h", 1) - local name = get_value(payload, "name", "button") - local label = get_value(payload, "label", "Button") - return "button["..x..","..y..";"..w..","..h..";"..name..";"..label.."]" - elseif element_type == "label" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local label = get_value(payload, "label", "Label") - return "label["..x..","..y..";"..label.."]" - elseif element_type == "image" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 1) - local h = get_value(payload, "h", 1) - local texture_name = get_value(payload, "texture_name", "default_apple.png") - return "image["..x..","..y..";"..w..","..h..";"..texture_name.."]" - elseif element_type == "animated_image" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 1) - local h = get_value(payload, "h", 1) - local name = get_value(payload, "name", "animated_image") - local texture_name = get_value(payload, "texture_name", "default_apple.png") - local frame_count = get_value(payload, "frame_count", 1) - local frame_duration = get_value(payload, "frame_duration", 1000) - local frame_start = get_value(payload, "frame_start", 1) - return "animated_image["..x..","..y..";"..w..","..h..";"..name..";"..texture_name..";"..frame_count..";"..frame_duration..";"..frame_start.."]" - elseif element_type == "item_image" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 1) - local h = get_value(payload, "h", 1) - local item_name = get_value(payload, "item_name", "default:apple") - return "item_image["..x..","..y..";"..w..","..h..";"..item_name.."]" - elseif element_type == "pwdfield" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 2) - local h = get_value(payload, "h", 1) - local name = get_value(payload, "name", "pwdfield") - local label = get_value(payload, "label", "Password") - return "pwdfield["..x..","..y..";"..w..","..h..";"..name..";"..label.."]" - elseif element_type == "field" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 2) - local h = get_value(payload, "h", 1) - local name = get_value(payload, "name", "field") - local label = get_value(payload, "label", "Input") - local default = get_value(payload, "default", ""):gsub("%${", "$ {") -- To prevent reading metadata - return "field["..x..","..y..";"..w..","..h..";"..name..";"..label..";"..default.."]" - elseif element_type == "field_close_on_enter" then - local name = get_value(payload, "name", "field") - local close_on_enter = get_value(payload, "close_on_enter", "false") - return "field_close_on_enter["..name..";"..close_on_enter"]" - elseif element_type == "textarea" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 2) - local h = get_value(payload, "h", 1) - local name = get_value(payload, "name", "") - local label = get_value(payload, "label", "Textarea") - local default = get_value(payload, "default", ""):gsub("%${", "$ {") -- To prevent reading metadata - return "textarea["..x..","..y..";"..w..","..h..";"..name..";"..label..";"..default.."]" - elseif element_type == "image_button" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 1) - local h = get_value(payload, "h", 1) - local texture_name = get_value(payload, "texture_name", "default_apple.png") - local name = get_value(payload, "name", "image_button") - local label = get_value(payload, "label", "") - return "image_button["..x..","..y..";"..w..","..h..";"..texture_name..";"..name..";"..label.."]" - elseif element_type == "item_image_button" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 1) - local h = get_value(payload, "h", 1) - local item_name = get_value(payload, "item_name", "default:apple") - local name = get_value(payload, "name", "item_image_button") - local label = get_value(payload, "label", "") - return "item_image_button["..x..","..y..";"..w..","..h..";"..item_name..";"..name..";"..label.."]" - elseif element_type == "button_exit" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 2) - local h = get_value(payload, "h", 1) - local name = get_value(payload, "name", "button_exit") - local label = get_value(payload, "label", "Exit Button") - return "button_exit["..x..","..y..";"..w..","..h..";"..name..";"..label.."]" - elseif element_type == "image_button_exit" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 1) - local h = get_value(payload, "h", 1) - local texture_name = get_value(payload, "texture_name", "creative_clear_icon.png") - local name = get_value(payload, "name", "image_button") - local label = get_value(payload, "label", "") - return "image_button_exit["..x..","..y..";"..w..","..h..";"..texture_name..";"..name..";"..label.."]" - elseif element_type == "box" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local w = get_value(payload, "w", 2) - local h = get_value(payload, "h", 1) - local color = get_value(payload, "color", "") - return "box["..x..","..y..";"..w..","..h..";"..color.."]" - elseif element_type == "checkbox" then - local x = get_value(payload, "x", 1) - local y = get_value(payload, "y", 1) - local name = get_value(payload, "name", "checkbox") - local label = get_value(payload, "label", "") - local selected = get_value(payload, "selected", "false") - return "checkbox["..x..","..y..";"..name..";"..label..";"..selected.."]" - end + local element_type = payload.get("type") + if type(element_type) ~= "string" then + return + end + element_type = string.lower(element_type) + if element_type == "button" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 2) + local h = get_value(payload, "h", 1) + local name = get_value(payload, "name", "button") + local label = get_value(payload, "label", "Button") + return "button["..x..","..y..";"..w..","..h..";"..name..";"..label.."]" + elseif element_type == "label" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local label = get_value(payload, "label", "Label") + return "label["..x..","..y..";"..label.."]" + elseif element_type == "image" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 1) + local h = get_value(payload, "h", 1) + local texture_name = get_value(payload, "texture_name", "default_apple.png") + return "image["..x..","..y..";"..w..","..h..";"..texture_name.."]" + elseif element_type == "animated_image" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 1) + local h = get_value(payload, "h", 1) + local name = get_value(payload, "name", "animated_image") + local texture_name = get_value(payload, "texture_name", "default_apple.png") + local frame_count = get_value(payload, "frame_count", 1) + local frame_duration = get_value(payload, "frame_duration", 1000) + local frame_start = get_value(payload, "frame_start", 1) + return "animated_image["..x..","..y..";"..w..","..h..";"..name..";"..texture_name..";"..frame_count..";"..frame_duration..";"..frame_start.."]" + elseif element_type == "item_image" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 1) + local h = get_value(payload, "h", 1) + local item_name = get_value(payload, "item_name", "default:apple") + return "item_image["..x..","..y..";"..w..","..h..";"..item_name.."]" + elseif element_type == "pwdfield" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 2) + local h = get_value(payload, "h", 1) + local name = get_value(payload, "name", "pwdfield") + local label = get_value(payload, "label", "Password") + return "pwdfield["..x..","..y..";"..w..","..h..";"..name..";"..label.."]" + elseif element_type == "field" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 2) + local h = get_value(payload, "h", 1) + local name = get_value(payload, "name", "field") + local label = get_value(payload, "label", "Input") + local default = get_value(payload, "default", ""):gsub("%${", "$ {") -- To prevent reading metadata + return "field["..x..","..y..";"..w..","..h..";"..name..";"..label..";"..default.."]" + elseif element_type == "field_close_on_enter" then + local name = get_value(payload, "name", "field") + local close_on_enter = get_value(payload, "close_on_enter", "false") + return "field_close_on_enter["..name..";"..close_on_enter"]" + elseif element_type == "textarea" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 2) + local h = get_value(payload, "h", 1) + local name = get_value(payload, "name", "") + local label = get_value(payload, "label", "Textarea") + local default = get_value(payload, "default", ""):gsub("%${", "$ {") -- To prevent reading metadata + return "textarea["..x..","..y..";"..w..","..h..";"..name..";"..label..";"..default.."]" + elseif element_type == "image_button" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 1) + local h = get_value(payload, "h", 1) + local texture_name = get_value(payload, "texture_name", "default_apple.png") + local name = get_value(payload, "name", "image_button") + local label = get_value(payload, "label", "") + return "image_button["..x..","..y..";"..w..","..h..";"..texture_name..";"..name..";"..label.."]" + elseif element_type == "item_image_button" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 1) + local h = get_value(payload, "h", 1) + local item_name = get_value(payload, "item_name", "default:apple") + local name = get_value(payload, "name", "item_image_button") + local label = get_value(payload, "label", "") + return "item_image_button["..x..","..y..";"..w..","..h..";"..item_name..";"..name..";"..label.."]" + elseif element_type == "button_exit" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 2) + local h = get_value(payload, "h", 1) + local name = get_value(payload, "name", "button_exit") + local label = get_value(payload, "label", "Exit Button") + return "button_exit["..x..","..y..";"..w..","..h..";"..name..";"..label.."]" + elseif element_type == "image_button_exit" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 1) + local h = get_value(payload, "h", 1) + local texture_name = get_value(payload, "texture_name", "creative_clear_icon.png") + local name = get_value(payload, "name", "image_button") + local label = get_value(payload, "label", "") + return "image_button_exit["..x..","..y..";"..w..","..h..";"..texture_name..";"..name..";"..label.."]" + elseif element_type == "box" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local w = get_value(payload, "w", 2) + local h = get_value(payload, "h", 1) + local color = get_value(payload, "color", "") + return "box["..x..","..y..";"..w..","..h..";"..color.."]" + elseif element_type == "checkbox" then + local x = get_value(payload, "x", 1) + local y = get_value(payload, "y", 1) + local name = get_value(payload, "name", "checkbox") + local label = get_value(payload, "label", "") + local selected = get_value(payload, "selected", "false") + return "checkbox["..x..","..y..";"..name..";"..label..";"..selected.."]" + end end local function next_id(pos) - local nvm = N(pos) - local id = (nvm.element_id or 0) + 1 - nvm.element_id = id - return id + local nvm = N(pos) + local id = (nvm.element_id or 0) + 1 + nvm.element_id = id + return id end local function reset_id(pos) - N(pos).element_id = 0 + N(pos).element_id = 0 end local function get_elements(pos) - local nvm = N(pos) - nvm.elements = nvm.elements or {} - return nvm.elements + local nvm = N(pos) + nvm.elements = nvm.elements or {} + return nvm.elements end local function valid_payload(payload) - if not payload then return false end - if not type(payload) == "table" then return false end - if not payload.get then return false end - if not payload.next then return false end - return true + if not payload then return false end + if not type(payload) == "table" then return false end + if not payload.get then return false end + if not payload.next then return false end + return true end local function update_fs(pos) - local meta = M(pos) - local fs = "formspec_version[3]" - fs = fs .. "size[10,10]" - local elements = get_elements(pos) - for _,ele in ipairs(elements) do - fs = fs .. ele - end - meta:set_string("formspec", fs) + local meta = M(pos) + local fs = "formspec_version[3]" + fs = fs .. "size[10,10]" + local elements = get_elements(pos) + for _,ele in ipairs(elements) do + fs = fs .. ele + end + meta:set_string("formspec", fs) end local function add_content(pos, payload) - if not valid_payload(payload) then - return - end - local element = parse_payload(payload) - if not element then - return - end - local elements = get_elements(pos) - local id = next_id(pos) - elements[id] = element - update_fs(pos) - return id + if not valid_payload(payload) then + return + end + local element = parse_payload(payload) + if not element then + return + end + local elements = get_elements(pos) + local id = next_id(pos) + elements[id] = element + update_fs(pos) + return id end local function update_content(pos, payload) - if not valid_payload(payload) then - return false - end - local id = payload.get("id") - local elements = get_elements(pos) - if not id or not elements[id] then - return false - end - local element = parse_payload(payload) - if not element then - return false - end - elements[id] = element - update_fs(pos) - return true + if not valid_payload(payload) then + return false + end + local id = payload.get("id") + local elements = get_elements(pos) + if not id or not elements[id] then + return false + end + local element = parse_payload(payload) + if not element then + return false + end + elements[id] = element + update_fs(pos) + return true end local function remove_content(pos, payload) - if valid_payload(payload) then - local id = payload.get("id") - if id then - local elements = get_elements(pos) - if not elements[id] then - return false - end - elements[id] = nil - update_fs(pos) - return true - else - return false - end - end - local nvm = techage.get_nvm(pos) - nvm.elements = {} - nvm.element_id = nil - update_fs(pos) - return true + if valid_payload(payload) then + local id = payload.get("id") + if id then + local elements = get_elements(pos) + if not elements[id] then + return false + end + elements[id] = nil + update_fs(pos) + return true + else + return false + end + end + local nvm = techage.get_nvm(pos) + nvm.elements = {} + nvm.element_id = nil + update_fs(pos) + return true end minetest.register_node("ta4_addons:touchscreen", { - description = S("TA4 Display"), - inventory_image = "ta4_addons_touchscreen_inventory.png", - tiles = {"ta4_addons_touchscreen.png"}, - drawtype = "nodebox", - paramtype = "light", - sunlight_propagates = true, - paramtype2 = "wallmounted", - node_box = techage.display.lcd_box, - selection_box = techage.display.lcd_box, - light_source = 6, + description = S("TA4 Display"), + inventory_image = "ta4_addons_touchscreen_inventory.png", + tiles = {"ta4_addons_touchscreen.png"}, + drawtype = "nodebox", + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "wallmounted", + node_box = techage.display.lcd_box, + selection_box = techage.display.lcd_box, + light_source = 6, - display_entities = { - ["techage:display_entity"] = { - depth = 0.42, - on_display_update = techage.display.display_update - }, - }, + display_entities = { + ["techage:display_entity"] = { + depth = 0.42, + on_display_update = techage.display.display_update + }, + }, - after_place_node = function(pos, placer) - local number = techage.add_node(pos, "ta4_addons:touchscreen") - local meta = M(pos) - meta:set_string("node_number", number) - meta:set_string("infotext", S("Touchscreen no: ")..number) - update_fs(pos) - local nvm = techage.get_nvm(pos) - nvm.text = {"My", "Techage","TA4", "Touchscreen", "No: "..number} - lcdlib.update_entities(pos) - minetest.get_node_timer(pos):start(1) - end, + after_place_node = function(pos, placer) + local number = techage.add_node(pos, "ta4_addons:touchscreen") + local meta = M(pos) + meta:set_string("node_number", number) + meta:set_string("infotext", S("Touchscreen no: ")..number) + update_fs(pos) + local nvm = techage.get_nvm(pos) + nvm.text = {"My", "Techage","TA4", "Touchscreen", "No: "..number} + lcdlib.update_entities(pos) + minetest.get_node_timer(pos):start(1) + end, - after_dig_node = function(pos, oldnode, oldmetadata) - remove_content(pos) - techage.remove_node(pos, oldnode, oldmetadata) - end, - - on_rightclick = function(pos, node, clicker) - local meta = M(pos) - local ctrl = meta:get_string("ctrl") - if ctrl then - local own_num = meta:get_string("node_number") or "" - techage.send_single(own_num, ctrl, "msg", safer_lua.Store("_touchscreen_opened_by", clicker:get_player_name())) - end - end, + after_dig_node = function(pos, oldnode, oldmetadata) + remove_content(pos) + techage.remove_node(pos, oldnode, oldmetadata) + end, - on_receive_fields = function(pos, formname, fields, sender) - local meta = M(pos) - local player_name = sender:get_player_name() - if meta:get_string("public") ~= "true" and minetest.is_protected(pos, player_name) then - return - end - local fields_store = safer_lua.Store() - for k,v in pairs(fields) do - fields_store.set(k, v) - end - fields_store.set("_sent_by", player_name) - local ctrl = meta:get_string("ctrl") - if ctrl then - local own_num = meta:get_string("node_number") or "" - techage.send_single(own_num, ctrl, "msg", fields_store) - end - end, + on_rightclick = function(pos, node, clicker) + local meta = M(pos) + local ctrl = meta:get_string("ctrl") + if ctrl then + local own_num = meta:get_string("node_number") or "" + techage.send_single(own_num, ctrl, "msg", safer_lua.Store("_touchscreen_opened_by", clicker:get_player_name())) + end + end, - on_timer = techage.display.on_timer, - on_place = lcdlib.on_place, - on_construct = lcdlib.on_construct, - on_destruct = lcdlib.on_destruct, - on_rotate = lcdlib.on_rotate, - groups = {cracky=2, crumbly=2}, - is_ground_content = false, - sounds = default.node_sound_glass_defaults(), + on_receive_fields = function(pos, formname, fields, sender) + local meta = M(pos) + local player_name = sender:get_player_name() + if meta:get_string("public") ~= "true" and minetest.is_protected(pos, player_name) then + return + end + local fields_store = safer_lua.Store() + for k,v in pairs(fields) do + fields_store.set(k, v) + end + fields_store.set("_sent_by", player_name) + local ctrl = meta:get_string("ctrl") + if ctrl then + local own_num = meta:get_string("node_number") or "" + techage.send_single(own_num, ctrl, "msg", fields_store) + end + end, + + on_timer = techage.display.on_timer, + on_place = lcdlib.on_place, + on_construct = lcdlib.on_construct, + on_destruct = lcdlib.on_destruct, + on_rotate = lcdlib.on_rotate, + groups = {cracky=2, crumbly=2}, + is_ground_content = false, + sounds = default.node_sound_glass_defaults(), }) minetest.register_craft({ - output = "ta4_addons:touchscreen", - recipe = { - {"", "dye:blue", ""}, - {"default:copper_ingot", "techage:ta4_display", "default:copper_ingot"}, - {"", "default:mese_crystal_fragment", ""}, - }, + output = "ta4_addons:touchscreen", + recipe = { + {"", "dye:blue", ""}, + {"default:copper_ingot", "techage:ta4_display", "default:copper_ingot"}, + {"", "default:mese_crystal_fragment", ""}, + }, }) techage.register_node({"ta4_addons:touchscreen"}, { - on_recv_message = function(pos, src, topic, payload) - if topic == "add" then -- add one line and scroll if necessary - techage.display.add_line(pos, payload, 1) - elseif topic == "set" then -- overwrite the given row - techage.display.write_row(pos, payload, 1) - elseif topic == "clear" then -- clear the screen - techage.display.clear_screen(pos, 1) - elseif topic == "add_content" then - M(pos):set_string("ctrl", src) - return add_content(pos, payload) - elseif topic == "update_content" then - M(pos):set_string("ctrl", src) - return update_content(pos, payload) - elseif topic == "remove_content" then - M(pos):set_string("ctrl", src) - return remove_content(pos, payload) - elseif topic == "private" then - M(pos):set_string("public", "false") - elseif topic == "public" then - M(pos):set_string("public", "true") - end - end, + on_recv_message = function(pos, src, topic, payload) + if topic == "add" then -- add one line and scroll if necessary + techage.display.add_line(pos, payload, 1) + elseif topic == "set" then -- overwrite the given row + techage.display.write_row(pos, payload, 1) + elseif topic == "clear" then -- clear the screen + techage.display.clear_screen(pos, 1) + elseif topic == "add_content" then + M(pos):set_string("ctrl", src) + return add_content(pos, payload) + elseif topic == "update_content" then + M(pos):set_string("ctrl", src) + return update_content(pos, payload) + elseif topic == "remove_content" then + M(pos):set_string("ctrl", src) + return remove_content(pos, payload) + elseif topic == "private" then + M(pos):set_string("public", "false") + elseif topic == "public" then + M(pos):set_string("public", "true") + end + end, }) \ No newline at end of file diff --git a/unified_inventory/.github/workflows/check-release.yml b/unified_inventory/.github/workflows/check-release.yml new file mode 100644 index 0000000..47313ff --- /dev/null +++ b/unified_inventory/.github/workflows/check-release.yml @@ -0,0 +1,11 @@ +on: [push, pull_request] +name: Check & Release +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: lint + uses: Roang-zero1/factorio-mod-luacheck@master + with: + luacheckrc_url: https://raw.githubusercontent.com/minetest-mods/unified_inventory/master/.luacheckrc diff --git a/unified_inventory/.luacheckrc b/unified_inventory/.luacheckrc index 9fb6a7c..e6fec97 100644 --- a/unified_inventory/.luacheckrc +++ b/unified_inventory/.luacheckrc @@ -14,6 +14,7 @@ read_globals = { "ItemStack", "datastorage", "hb", + "doors", } files["callbacks.lua"].ignore = { "player", "draw_lite_mode" } diff --git a/unified_inventory/README.md b/unified_inventory/README.md index 8c917ec..5d23f79 100644 --- a/unified_inventory/README.md +++ b/unified_inventory/README.md @@ -15,7 +15,8 @@ Unified Inventory replaces the default survival and creative inventory. * Recipe search function by ingredients * Up to four bags with up to 24 slots each * Home function to teleport - * Trash slot + * Trash slot and refill slot for creative + * Waypoints to keep track of important locations * Lite mode: reduces the item browser width * `minetest.conf` setting `unified_inventory_lite = true` * Mod API for modders: see [mod_api.txt](doc/mod_api.txt) @@ -24,7 +25,11 @@ Unified Inventory replaces the default survival and creative inventory. ## Requirements - * Minetest 5.0.0+ + * Minetest 5.4.0+ + * Mod `default` for category filters (contained in Minetest Game) + * Mod `farming` for craftable bags (contained in Minetest Game) + * For waypoint migration: `datastorage` + # Licenses @@ -96,4 +101,4 @@ Other files from Wikimedia Commons: RealBadAngel: (CC-BY-4.0) - * Everything else. \ No newline at end of file + * Everything else. diff --git a/unified_inventory/api.lua b/unified_inventory/api.lua index 81dd8f3..8cc5532 100644 --- a/unified_inventory/api.lua +++ b/unified_inventory/api.lua @@ -1,5 +1,6 @@ local S = minetest.get_translator("unified_inventory") local F = minetest.formspec_escape +local ui = unified_inventory -- Create detached creative inventory after loading all mods minetest.after(0.01, function() @@ -8,12 +9,12 @@ minetest.after(0.01, function() if not rev_aliases[target] then rev_aliases[target] = {} end table.insert(rev_aliases[target], source) end - unified_inventory.items_list = {} + ui.items_list = {} for name, def in pairs(minetest.registered_items) do if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then - table.insert(unified_inventory.items_list, name) + table.insert(ui.items_list, name) local all_names = rev_aliases[name] or {} table.insert(all_names, name) for _, player_name in ipairs(all_names) do @@ -26,30 +27,30 @@ minetest.after(0.01, function() for _,chk in pairs(recipe.items) do local groupchk = string.find(chk, "group:") if (not groupchk and not minetest.registered_items[chk]) - or (groupchk and not unified_inventory.get_group_item(string.gsub(chk, "group:", "")).item) + or (groupchk and not ui.get_group_item(string.gsub(chk, "group:", "")).item) or minetest.get_item_group(chk, "not_in_craft_guide") ~= 0 then unknowns = true end end if not unknowns then - unified_inventory.register_craft(recipe) + ui.register_craft(recipe) end end end end end end - table.sort(unified_inventory.items_list) - unified_inventory.items_list_size = #unified_inventory.items_list - print("Unified Inventory. inventory size: "..unified_inventory.items_list_size) - for _, name in ipairs(unified_inventory.items_list) do + table.sort(ui.items_list) + ui.items_list_size = #ui.items_list + print("Unified Inventory. inventory size: "..ui.items_list_size) + for _, name in ipairs(ui.items_list) do local def = minetest.registered_items[name] -- Simple drops if type(def.drop) == "string" then local dstack = ItemStack(def.drop) if not dstack:is_empty() and dstack:get_name() ~= name then - unified_inventory.register_craft({ + ui.register_craft({ type = "digging", items = {name}, output = def.drop, @@ -115,7 +116,7 @@ minetest.after(0.01, function() end end for itemstring, count in pairs(drop_guaranteed) do - unified_inventory.register_craft({ + ui.register_craft({ type = "digging", items = {name}, output = itemstring .. " " .. count, @@ -123,7 +124,7 @@ minetest.after(0.01, function() }) end for itemstring, count in pairs(drop_maybe) do - unified_inventory.register_craft({ + ui.register_craft({ type = "digging_chance", items = {name}, output = itemstring .. " " .. count, @@ -132,33 +133,37 @@ minetest.after(0.01, function() end end end - for _, recipes in pairs(unified_inventory.crafts_for.recipe) do + for _, recipes in pairs(ui.crafts_for.recipe) do for _, recipe in ipairs(recipes) do local ingredient_items = {} for _, spec in pairs(recipe.items) do - local matches_spec = unified_inventory.canonical_item_spec_matcher(spec) - for _, name in ipairs(unified_inventory.items_list) do + local matches_spec = ui.canonical_item_spec_matcher(spec) + for _, name in ipairs(ui.items_list) do if matches_spec(name) then ingredient_items[name] = true end end end for name, _ in pairs(ingredient_items) do - if unified_inventory.crafts_for.usage[name] == nil then - unified_inventory.crafts_for.usage[name] = {} + if ui.crafts_for.usage[name] == nil then + ui.crafts_for.usage[name] = {} end - table.insert(unified_inventory.crafts_for.usage[name], recipe) + table.insert(ui.crafts_for.usage[name], recipe) end end end + + for _, callback in ipairs(ui.initialized_callbacks) do + callback() + end end) -- load_home local function load_home() - local input = io.open(unified_inventory.home_filename, "r") + local input = io.open(ui.home_filename, "r") if not input then - unified_inventory.home_pos = {} + ui.home_pos = {} return end while true do @@ -167,25 +172,31 @@ local function load_home() local y = input:read("*n") local z = input:read("*n") local name = input:read("*l") - unified_inventory.home_pos[name:sub(2)] = {x = x, y = y, z = z} + ui.home_pos[name:sub(2)] = {x = x, y = y, z = z} end io.close(input) end load_home() -function unified_inventory.set_home(player, pos) +function ui.set_home(player, pos) local player_name = player:get_player_name() - unified_inventory.home_pos[player_name] = vector.round(pos) + ui.home_pos[player_name] = vector.round(pos) + -- save the home data from the table to the file - local output = io.open(unified_inventory.home_filename, "w") - for k, v in pairs(unified_inventory.home_pos) do + local output = io.open(ui.home_filename, "w") + if not output then + minetest.log("warning", "[unified_inventory] Failed to save file: " + .. ui.home_filename) + return + end + for k, v in pairs(ui.home_pos) do output:write(v.x.." "..v.y.." "..v.z.." "..k.."\n") end io.close(output) end -function unified_inventory.go_home(player) - local pos = unified_inventory.home_pos[player:get_player_name()] +function ui.go_home(player) + local pos = ui.home_pos[player:get_player_name()] if pos then player:set_pos(pos) return true @@ -194,7 +205,7 @@ function unified_inventory.go_home(player) end -- register_craft -function unified_inventory.register_craft(options) +function ui.register_craft(options) if not options.output then return end @@ -205,10 +216,15 @@ function unified_inventory.register_craft(options) if options.type == "normal" and options.width == 0 then options = { type = "shapeless", items = options.items, output = options.output, width = 0 } end - if not unified_inventory.crafts_for.recipe[itemstack:get_name()] then - unified_inventory.crafts_for.recipe[itemstack:get_name()] = {} + local item_name = itemstack:get_name() + if not ui.crafts_for.recipe[item_name] then + ui.crafts_for.recipe[item_name] = {} + end + table.insert(ui.crafts_for.recipe[item_name],options) + + for _, callback in ipairs(ui.craft_registered_callbacks) do + callback(item_name, options) end - table.insert(unified_inventory.crafts_for.recipe[itemstack:get_name()],options) end @@ -219,7 +235,7 @@ local craft_type_defaults = { } -function unified_inventory.craft_type_defaults(name, options) +function ui.craft_type_defaults(name, options) if not options.description then options.description = name end @@ -228,13 +244,13 @@ function unified_inventory.craft_type_defaults(name, options) end -function unified_inventory.register_craft_type(name, options) - unified_inventory.registered_craft_types[name] = - unified_inventory.craft_type_defaults(name, options) +function ui.register_craft_type(name, options) + ui.registered_craft_types[name] = + ui.craft_type_defaults(name, options) end -unified_inventory.register_craft_type("normal", { +ui.register_craft_type("normal", { description = F(S("Crafting")), icon = "ui_craftgrid_icon.png", width = 3, @@ -250,7 +266,7 @@ unified_inventory.register_craft_type("normal", { }) -unified_inventory.register_craft_type("shapeless", { +ui.register_craft_type("shapeless", { description = F(S("Mixing")), icon = "ui_craftgrid_icon.png", width = 3, @@ -265,7 +281,7 @@ unified_inventory.register_craft_type("shapeless", { }) -unified_inventory.register_craft_type("cooking", { +ui.register_craft_type("cooking", { description = F(S("Cooking")), icon = "default_furnace_front.png", width = 1, @@ -273,37 +289,86 @@ unified_inventory.register_craft_type("cooking", { }) -unified_inventory.register_craft_type("digging", { +ui.register_craft_type("digging", { description = F(S("Digging")), icon = "default_tool_steelpick.png", width = 1, height = 1, }) -unified_inventory.register_craft_type("digging_chance", { +ui.register_craft_type("digging_chance", { description = "Digging (by chance)", icon = "default_tool_steelpick.png^[transformFY.png", width = 1, height = 1, }) -function unified_inventory.register_page(name, def) - unified_inventory.pages[name] = def +function ui.register_page(name, def) + ui.pages[name] = def end -function unified_inventory.register_button(name, def) +function ui.register_button(name, def) if not def.action then def.action = function(player) - unified_inventory.set_inventory_formspec(player, name) + ui.set_inventory_formspec(player, name) end end def.name = name - table.insert(unified_inventory.buttons, def) + table.insert(ui.buttons, def) end +function ui.register_on_initialized(callback) + if type(callback) ~= "function" then + error(("Initialized callback must be a function, %s given."):format(type(callback))) + end + table.insert(ui.initialized_callbacks, callback) +end -function unified_inventory.is_creative(playername) +function ui.register_on_craft_registered(callback) + if type(callback) ~= "function" then + error(("Craft registered callback must be a function, %s given."):format(type(callback))) + end + table.insert(ui.craft_registered_callbacks, callback) +end + +function ui.get_recipe_list(output) + return ui.crafts_for.recipe[output] +end + +function ui.get_registered_outputs() + local outputs = {} + for item_name, _ in pairs(ui.crafts_for.recipe) do + table.insert(outputs, item_name) + end + return outputs +end + +function ui.is_creative(playername) return minetest.check_player_privs(playername, {creative=true}) or minetest.settings:get_bool("creative_mode") end + +function ui.single_slot(xpos, ypos, bright) + return string.format("background9[%f,%f;%f,%f;ui_single_slot%s.png;false;16]", + xpos, ypos, ui.imgscale, ui.imgscale, (bright and "_bright" or "") ) +end + +function ui.make_trash_slot(xpos, ypos) + return + ui.single_slot(xpos, ypos).. + "image["..xpos..","..ypos..";1.25,1.25;ui_trash_slot_icon.png]".. + "list[detached:trash;main;"..(xpos + ui.list_img_offset)..","..(ypos + ui.list_img_offset)..";1,1;]" +end + +function ui.make_inv_img_grid(xpos, ypos, width, height, bright) + local tiled = {} + local n=1 + for y = 0, (height - 1) do + for x = 0, (width -1) do + tiled[n] = ui.single_slot(xpos + (ui.imgscale * x), ypos + (ui.imgscale * y), bright) + n = n + 1 + end + end + return table.concat(tiled) +end diff --git a/unified_inventory/bags.lua b/unified_inventory/bags.lua index 1bb2b5c..14ac875 100644 --- a/unified_inventory/bags.lua +++ b/unified_inventory/bags.lua @@ -7,29 +7,32 @@ License: GPLv3 local S = minetest.get_translator("unified_inventory") local F = minetest.formspec_escape -local bags_inv_bg_prefix = "image[-0.1,1.0;10.05," +local ui = unified_inventory -unified_inventory.register_page("bags", { +ui.register_page("bags", { get_formspec = function(player) local player_name = player:get_player_name() return { formspec = table.concat({ - string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4"), - bags_inv_bg_prefix.."1.175;ui_bags_header.png]", - "label[0,0;" .. F(S("Bags")) .. "]", - "button[0,2.2;2,0.5;bag1;" .. F(S("Bag @1", 1)) .. "]", - "button[2,2.2;2,0.5;bag2;" .. F(S("Bag @1", 2)) .. "]", - "button[4,2.2;2,0.5;bag3;" .. F(S("Bag @1", 3)) .. "]", - "button[6,2.2;2,0.5;bag4;" .. F(S("Bag @1", 4)) .. "]", + ui.style_full.standard_inv_bg, + ui.single_slot(0.925, 1.5), + ui.single_slot(3.425, 1.5), + ui.single_slot(5.925, 1.5), + ui.single_slot(8.425, 1.5), + "label["..ui.style_full.form_header_x..","..ui.style_full.form_header_y..";" .. F(S("Bags")) .. "]", + "button[0.6125,2.75;1.875,0.75;bag1;" .. F(S("Bag @1", 1)) .. "]", + "button[3.1125,2.75;1.875,0.75;bag2;" .. F(S("Bag @1", 2)) .. "]", + "button[5.6125,2.75;1.875,0.75;bag3;" .. F(S("Bag @1", 3)) .. "]", + "button[8.1125,2.75;1.875,0.75;bag4;" .. F(S("Bag @1", 4)) .. "]", "listcolors[#00000000;#00000000]", - "list[detached:" .. F(player_name) .. "_bags;bag1;0.5,1.1;1,1;]", - "list[detached:" .. F(player_name) .. "_bags;bag2;2.5,1.1;1,1;]", - "list[detached:" .. F(player_name) .. "_bags;bag3;4.5,1.1;1,1;]", - "list[detached:" .. F(player_name) .. "_bags;bag4;6.5,1.1;1,1;]" + "list[detached:" .. F(player_name) .. "_bags;bag1;1.075,1.65;1,1;]", + "list[detached:" .. F(player_name) .. "_bags;bag2;3.575,1.65;1,1;]", + "list[detached:" .. F(player_name) .. "_bags;bag3;6.075,1.65;1,1;]", + "list[detached:" .. F(player_name) .. "_bags;bag4;8.575,1.65;1,1;]" }) } end, }) -unified_inventory.register_button("bags", { +ui.register_button("bags", { type = "image", image = "ui_bags_icon.png", tooltip = S("Bags"), @@ -44,33 +47,31 @@ local function get_player_bag_stack(player, i) end for bag_i = 1, 4 do - unified_inventory.register_page("bag" .. bag_i, { + ui.register_page("bag" .. bag_i, { get_formspec = function(player) local stack = get_player_bag_stack(player, bag_i) local image = stack:get_definition().inventory_image - local fs = { - string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4"), - "image[7,0;1,1;" .. image .. "]", - "label[0,0;" .. F(S("Bag @1", bag_i)) .. "]", - "listcolors[#00000000;#00000000]", - "list[current_player;bag" .. bag_i .. "contents;0,1.1;8,3;]", - "listring[current_name;bag" .. bag_i .. "contents]", - "listring[current_player;main]", - } local slots = stack:get_definition().groups.bagslots - if slots == 8 then - fs[#fs + 1] = bags_inv_bg_prefix.."1.175;ui_bags_inv_small.png]" - elseif slots == 16 then - fs[#fs + 1] = bags_inv_bg_prefix.."2.35;ui_bags_inv_medium.png]" - elseif slots == 24 then - fs[#fs + 1] = bags_inv_bg_prefix.."3.525;ui_bags_inv_large.png]" - end + + local formspec = { + ui.style_full.standard_inv_bg, + ui.make_inv_img_grid(0.3, 1.5, 8, slots/8), + "image[9.2,0.4;1,1;" .. image .. "]", + "label[0.3,0.65;" .. F(S("Bag @1", bag_i)) .. "]", + "listcolors[#00000000;#00000000]", + "listring[current_player;main]", + string.format("list[current_player;bag%icontents;%f,%f;8,3;]", + bag_i, 0.3 + ui.list_img_offset, 1.5 + ui.list_img_offset), + "listring[current_name;bag" .. bag_i .. "contents]", + } + local n = #formspec + 1 + local player_name = player:get_player_name() -- For if statement. - if unified_inventory.trash_enabled - or unified_inventory.is_creative(player_name) - or minetest.get_player_privs(player_name).give then - fs[#fs + 1] = "image[5.91,-0.06;1.21,1.15;ui_bags_trash.png]" - .. "list[detached:trash;main;6,0.1;1,1;]" + if ui.trash_enabled + or ui.is_creative(player_name) + or minetest.get_player_privs(player_name).give then + formspec[n] = ui.make_trash_slot(7.8, 0.25) + n = n + 1 end local inv = player:get_inventory() for i = 1, 4 do @@ -87,11 +88,12 @@ for bag_i = 1, 4 do end local img = def.inventory_image local label = F(S("Bag @1", i)) .. "\n" .. used .. "/" .. size - fs[#fs + 1] = string.format("image_button[%i,0;1,1;%s;bag%i;%s]", - i + 1, img, i, label) + formspec[n] = string.format("image_button[%f,0.4;1,1;%s;bag%i;%s]", + (i + 1.35)*1.25, img, i, label) + n = n + 1 end end - return { formspec = table.concat(fs) } + return { formspec = table.concat(formspec) } end, }) end @@ -106,7 +108,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if not stack:get_definition().groups.bagslots then return end - unified_inventory.set_inventory_formspec(player, "bag" .. i) + ui.set_inventory_formspec(player, "bag" .. i) return end end diff --git a/unified_inventory/callbacks.lua b/unified_inventory/callbacks.lua index bc90237..5874a0f 100644 --- a/unified_inventory/callbacks.lua +++ b/unified_inventory/callbacks.lua @@ -19,11 +19,12 @@ minetest.register_on_joinplayer(function(player) unified_inventory.active_search_direction[player_name] = "nochange" unified_inventory.apply_filter(player, "", "nochange") unified_inventory.current_searchbox[player_name] = "" + unified_inventory.current_category[player_name] = "all" + unified_inventory.current_category_scroll[player_name] = 0 unified_inventory.alternate[player_name] = 1 unified_inventory.current_item[player_name] = nil unified_inventory.current_craft_direction[player_name] = "recipe" - unified_inventory.set_inventory_formspec(player, - unified_inventory.default) + unified_inventory.set_inventory_formspec(player, unified_inventory.default) -- Refill slot local refill = minetest.create_detached_inventory(player_name.."refill", { @@ -69,6 +70,41 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) unified_inventory.current_searchbox[player_name] = fields.searchbox end + + local clicked_category + for name, value in pairs(fields) do + local category_name = string.match(name, "^category_(.+)$") + if category_name then + clicked_category = category_name + break + end + end + + if clicked_category + and clicked_category ~= unified_inventory.current_category[player_name] then + unified_inventory.current_category[player_name] = clicked_category + unified_inventory.apply_filter(player, unified_inventory.current_searchbox[player_name], "nochange") + unified_inventory.set_inventory_formspec(player, + unified_inventory.current_page[player_name]) + end + + if fields.next_category then + local scroll = math.min(#unified_inventory.category_list-ui_peruser.pagecols, unified_inventory.current_category_scroll[player_name] + 1) + if scroll ~= unified_inventory.current_category_scroll[player_name] then + unified_inventory.current_category_scroll[player_name] = scroll + unified_inventory.set_inventory_formspec(player, + unified_inventory.current_page[player_name]) + end + end + if fields.prev_category then + local scroll = math.max(0, unified_inventory.current_category_scroll[player_name] - 1) + if scroll ~= unified_inventory.current_category_scroll[player_name] then + unified_inventory.current_category_scroll[player_name] = scroll + unified_inventory.set_inventory_formspec(player, + unified_inventory.current_page[player_name]) + end + end + for i, def in pairs(unified_inventory.buttons) do if fields[def.name] then def.action(player) @@ -121,11 +157,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) -- Check clicked item image button local clicked_item for name, value in pairs(fields) do - local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$") + local new_dir, mangled_item = string.match(name, "^[0-9]*_?item_button_([a-z]+)_(.*)$") if new_dir and mangled_item then clicked_item = unified_inventory.demangle_for_formspec(mangled_item) if string.sub(clicked_item, 1, 6) == "group:" then -- Change search filter to this group + unified_inventory.current_category[player_name] = "all" apply_new_filter(player, clicked_item, new_dir) return end diff --git a/unified_inventory/category.lua b/unified_inventory/category.lua new file mode 100644 index 0000000..d0fee5e --- /dev/null +++ b/unified_inventory/category.lua @@ -0,0 +1,150 @@ +local S = minetest.get_translator("unified_inventory") + +unified_inventory.registered_categories = {} +unified_inventory.registered_category_items = {} +unified_inventory.category_list = {} + +local function char_to_sort_index(char_code) + if char_code <= 32 then + -- Command codes, no thanks + return 0 + end + if char_code <= 64 then + -- Sorts numbers, and some punctuation, after letters + return char_code + end + if char_code >= 158 then + -- Out of sortable range + return 0 + end + if char_code > 122 then + -- Avoids overlap with {, |, } and ~ + return char_code - 58 + end + if char_code > 96 then + -- Normalises lowercase with uppercase + return char_code - 96 + end + return char_code - 64 +end + +local function string_to_sort_index(str) + local max_chars = 5 + local power = 100 + local index = 0 + for i=1,math.min(#str, max_chars) do + index = index + (char_to_sort_index(string.byte(str, i))/(power^i)) + end + return index +end + +function update_category_list() + local category_list = {} + table.insert(category_list, { + name = "all", + label = S("All Items"), + symbol = "ui_category_all.png", + index = -2, + }) + table.insert(category_list, { + name = "uncategorized", + label = S("Misc. Items"), + symbol = "ui_category_none.png", + index = -1, + }) + for category, def in pairs(unified_inventory.registered_categories) do + table.insert(category_list, { + name = category, + label = def.label or category, + symbol = def.symbol, + index = def.index or -- sortby defined order + string_to_sort_index(category) -- or do a rudimentary alphabetical sort + }) + end + table.sort(category_list, function (a,b) + return a.index < b.index + end) + unified_inventory.category_list = category_list +end + +local function ensure_category_exists(category_name) + if not unified_inventory.registered_categories[category_name] then + unified_inventory.registered_categories[category_name] = { + symbol = "unknown_item.png", + label = category_name + } + end + if not unified_inventory.registered_category_items[category_name] then + unified_inventory.registered_category_items[category_name] = {} + end +end + +function unified_inventory.register_category(category_name, config) + ensure_category_exists(category_name) + config = config or {} + if config.symbol then + unified_inventory.set_category_symbol(category_name, config.symbol) + end + if config.label then + unified_inventory.set_category_label(category_name, config.label) + end + if config.index then + unified_inventory.set_category_index(category_name, config.index) + end + if config.items then + unified_inventory.add_category_items(category_name, config.items) + end + update_category_list() +end +function unified_inventory.set_category_symbol(category_name, symbol) + ensure_category_exists(category_name) + unified_inventory.registered_categories[category_name].symbol = symbol + update_category_list() +end +function unified_inventory.set_category_label(category_name, label) + ensure_category_exists(category_name) + unified_inventory.registered_categories[category_name].label = label + update_category_list() +end +function unified_inventory.set_category_index(category_name, index) + ensure_category_exists(category_name) + unified_inventory.registered_categories[category_name].index = index + update_category_list() +end +function unified_inventory.add_category_item(category_name, item) + ensure_category_exists(category_name) + unified_inventory.registered_category_items[category_name][item] = true +end +function unified_inventory.add_category_items(category_name, items) + for _,item in ipairs(items) do + unified_inventory.add_category_item(category_name, item) + end +end + +function unified_inventory.remove_category_item(category_name, item) + unified_inventory.registered_category_items[category_name][item] = nil +end +function unified_inventory.remove_category(category_name) + unified_inventory.registered_categories[category_name] = nil + unified_inventory.registered_category_items[category_name] = nil + update_category_list() +end + +function unified_inventory.find_category(item) + -- Returns the first category the item exists in + -- Best for checking if an item has any category at all + for category, items in pairs(unified_inventory.registered_category_items) do + if items[item] then return category end + end +end +function unified_inventory.find_categories(item) + -- Returns all the categories the item exists in + -- Best for listing all categories + local categories = {} + for category, items in pairs(unified_inventory.registered_category_items) do + if items[item] then + table.insert(categories, category) + end + end + return categories +end diff --git a/unified_inventory/default-categories.lua b/unified_inventory/default-categories.lua new file mode 100644 index 0000000..57d3e88 --- /dev/null +++ b/unified_inventory/default-categories.lua @@ -0,0 +1,704 @@ +local S = minetest.get_translator("unified_inventory") + +unified_inventory.register_category('plants', { + symbol = "flowers:tulip", + label = S("Plant Life") +}) +unified_inventory.register_category('building', { + symbol = "default:brick", + label = S("Building Materials") +}) +unified_inventory.register_category('tools', { + symbol = "default:pick_diamond", + label = S("Tools") +}) +unified_inventory.register_category('minerals', { + symbol = "default:iron_lump", + label = S("Minerals and Metals") +}) +unified_inventory.register_category('environment', { + symbol = "default:dirt_with_grass", + label = S("Environment and Worldgen") +}) +unified_inventory.register_category('lighting', { + symbol = "default:torch", + label = S("Lighting") +}) + + +if unified_inventory.automatic_categorization then + minetest.register_on_mods_loaded(function() + + -- Add biome nodes to environment category + for _,def in pairs(minetest.registered_biomes) do + local env_nodes = { + def.node_riverbed, def.node_top, def.node_filler, def.node_dust, + } + for i,node in pairs(env_nodes) do + if node then + unified_inventory.add_category_item('environment', node) + end + end + end + + -- Add minable ores to minerals and everything else (pockets of stone & sand variations) to environment + for _,item in pairs(minetest.registered_ores) do + if item.ore_type == "scatter" then + local drop = minetest.registered_nodes[item.ore].drop + if drop and drop ~= "" then + unified_inventory.add_category_item('minerals', item.ore) + unified_inventory.add_category_item('minerals', drop) + else + unified_inventory.add_category_item('environment', item.ore) + end + else + unified_inventory.add_category_item('environment', item.ore) + end + end + + -- Add items by item definition + for name, def in pairs(minetest.registered_items) do + local group = def.groups or {} + if not group.not_in_creative_inventory then + if group.stair or + group.slab or + group.wall or + group.fence then + unified_inventory.add_category_item('building', name) + elseif group.flora or + group.flower or + group.seed or + group.leaves or + group.sapling or + group.tree then + unified_inventory.add_category_item('plants', name) + elseif def.type == 'tool' then + unified_inventory.add_category_item('tools', name) + elseif def.liquidtype == 'source' then + unified_inventory.add_category_item('environment', name) + elseif def.light_source and def.light_source > 0 then + unified_inventory.add_category_item('lighting', name) + elseif group.door or + minetest.global_exists("doors") and ( + doors.registered_doors and doors.registered_doors[name..'_a'] or + doors.registered_trapdoors and doors.registered_trapdoors[name] + ) then + unified_inventory.add_category_item('building', name) + end + end + end + end) +end + +-- [[ +unified_inventory.add_category_items('plants', { + "default:dry_grass_5", + "default:acacia_sapling", + "default:blueberry_bush_sapling", + "default:grass_2", + "default:pine_bush_stem", + "default:leaves", + "default:pine_needles", + "default:cactus", + "default:junglegrass", + "default:pine_sapling", + "default:sapling", + "default:bush_stem", + "default:dry_grass_2", + "default:fern_1", + "default:grass_3", + "default:marram_grass_1", + "default:pine_tree", + "default:dry_grass_3", + "default:dry_shrub", + "default:grass_4", + "default:marram_grass_2", + "default:jungleleaves", + "default:apple", + "default:tree", + "default:aspen_tree", + "default:bush_sapling", + "default:grass_5", + "default:blueberry_bush_leaves_with_berries", + "default:acacia_bush_sapling", + "default:grass_1", + "default:aspen_leaves", + "default:marram_grass_3", + "default:large_cactus_seedling", + "default:junglesapling", + "default:dry_grass_4", + "default:acacia_bush_stem", + "default:papyrus", + "default:pine_bush_needles", + "default:bush_leaves", + "default:fern_3", + "default:aspen_sapling", + "default:acacia_tree", + "default:apple_mark", + "default:acacia_leaves", + "default:jungletree", + "default:dry_grass_1", + "default:acacia_bush_leaves", + "default:emergent_jungle_sapling", + "default:fern_2", + "default:blueberries", + "default:sand_with_kelp", + "default:blueberry_bush_leaves", + "default:pine_bush_sapling", + + "farming:cotton", + "farming:cotton_1", + "farming:cotton_2", + "farming:cotton_3", + "farming:cotton_4", + "farming:cotton_5", + "farming:cotton_6", + "farming:cotton_7", + "farming:cotton_8", + "farming:cotton_wild", + "farming:seed_cotton", + "farming:seed_wheat", + "farming:straw", + "farming:wheat", + "farming:wheat_1", + "farming:wheat_2", + "farming:wheat_3", + "farming:wheat_4", + "farming:wheat_5", + "farming:wheat_6", + "farming:wheat_7", + "farming:wheat_8", + + "flowers:chrysanthemum_green", + "flowers:dandelion_white", + "flowers:dandelion_yellow", + "flowers:geranium", + "flowers:mushroom_brown", + "flowers:mushroom_red", + "flowers:rose", + "flowers:tulip", + "flowers:tulip_black", + "flowers:viola", + "flowers:waterlily", + "flowers:waterlily_waving", +}) + +unified_inventory.add_category_items('tools', { + "default:sword_diamond", + "default:axe_diamond", + "default:shovel_diamond", + "default:axe_steel", + "default:shovel_mese", + "default:sword_wood", + "default:pick_bronze", + "default:axe_stone", + "default:sword_stone", + "default:pick_stone", + "default:shovel_stone", + "default:sword_mese", + "default:shovel_bronze", + "default:sword_bronze", + "default:axe_bronze", + "default:shovel_steel", + "default:sword_steel", + "default:axe_mese", + "default:shovel_wood", + "default:pick_mese", + "default:axe_wood", + "default:pick_diamond", + "default:pick_wood", + "default:pick_steel", + + "farming:hoe_bronze", + "farming:hoe_diamond", + "farming:hoe_mese", + "farming:hoe_steel", + "farming:hoe_stone", + "farming:hoe_wood", + + "fire:flint_and_steel", + "map:mapping_kit", + "screwdriver:screwdriver", + + "fireflies:bug_net", + "bucket:bucket_empty", + + "binoculars:binoculars", + "default:skeleton_key", +}) + +unified_inventory.add_category_items('minerals', { + "default:stone_with_copper", + "default:stone_with_gold", + "default:stone_with_iron", + "default:copper_ingot", + "default:copper_lump", + "default:gold_lump", + "default:diamondblock", + "default:stone_with_diamond", + "default:stone_with_mese", + "default:steel_ingot", + "default:gold_ingot", + "default:iron_lump", + "default:tinblock", + "default:tin_lump", + "default:stone_with_tin", + "default:mese_crystal", + "default:diamond", + "default:bronze_ingot", + "default:mese", + "default:mese_crystal_fragment", + "default:copperblock", + "default:stone_with_coal", + "default:steelblock", + "default:tin_ingot", + "default:coalblock", + "default:coal_lump", + "default:bronzeblock", + "default:goldblock", + + "stairs:slab_bronzeblock", + "stairs:slab_copperblock", + "stairs:slab_steelblock", + "stairs:slab_tinblock", + "stairs:stair_bronzeblock", + "stairs:stair_copperblock", + "stairs:stair_inner_bronzeblock", + "stairs:stair_inner_copperblock", + "stairs:stair_inner_steelblock", + "stairs:stair_inner_tinblock", + "stairs:stair_outer_bronzeblock", + "stairs:stair_outer_copperblock", + "stairs:stair_outer_steelblock", + "stairs:stair_outer_tinblock", + "stairs:stair_steelblock", + "stairs:stair_tinblock", +}) + +unified_inventory.add_category_items('building', { + "default:fence_rail_aspen_wood", + "default:fence_rail_acacia_wood", + "default:fence_junglewood", + "default:fence_rail_junglewood", + "default:fence_aspen_wood", + "default:fence_pine_wood", + "default:fence_rail_wood", + "default:fence_rail_pine_wood", + "default:fence_acacia_wood", + "default:junglewood", + "default:acacia_wood", + "default:aspen_wood", + "default:fence_wood", + "default:pine_wood", + "default:silver_sandstone", + "default:desert_sandstone", + "default:sandstone_block", + "default:desert_sandstone_brick", + "default:stone_block", + "default:stonebrick", + "default:obsidian_glass", + "default:desert_sandstone_block", + "default:silver_sandstone_brick", + "default:brick", + "default:obsidianbrick", + "default:sandstonebrick", + "default:sandstone", + "default:desert_stone_block", + "default:silver_sandstone_block", + "default:wood", + "default:obsidian_block", + "default:glass", + "default:clay_brick", + "default:desert_stonebrick", + "default:desert_cobble", + "default:cobble", + "default:mossycobble", + + "doors:door_glass", + "doors:door_glass_a", + "doors:door_glass_b", + "doors:door_glass_c", + "doors:door_glass_d", + "doors:door_obsidian_glass", + "doors:door_obsidian_glass_a", + "doors:door_obsidian_glass_b", + "doors:door_obsidian_glass_c", + "doors:door_obsidian_glass_d", + "doors:door_steel", + "doors:door_steel_a", + "doors:door_steel_b", + "doors:door_steel_c", + "doors:door_steel_d", + "doors:door_wood", + "doors:door_wood_a", + "doors:door_wood_b", + "doors:door_wood_c", + "doors:door_wood_d", + "doors:gate_acacia_wood_closed", + "doors:gate_acacia_wood_open", + "doors:gate_aspen_wood_closed", + "doors:gate_aspen_wood_open", + "doors:gate_junglewood_closed", + "doors:gate_junglewood_open", + "doors:gate_pine_wood_closed", + "doors:gate_pine_wood_open", + "doors:gate_wood_closed", + "doors:gate_wood_open", + "doors:hidden", + "doors:trapdoor", + "doors:trapdoor_open", + "doors:trapdoor_steel", + "doors:trapdoor_steel_open", + + "stairs:slab_bronzeblock", + "stairs:slab_copperblock", + "stairs:slab_steelblock", + "stairs:slab_tinblock", + "stairs:stair_bronzeblock", + "stairs:stair_copperblock", + "stairs:stair_inner_bronzeblock", + "stairs:stair_inner_copperblock", + "stairs:stair_inner_steelblock", + "stairs:stair_inner_tinblock", + "stairs:stair_outer_bronzeblock", + "stairs:stair_outer_copperblock", + "stairs:stair_outer_steelblock", + "stairs:stair_outer_tinblock", + "stairs:stair_steelblock", + "stairs:stair_tinblock", + + "stairs:slab_acacia_wood", + "stairs:slab_aspen_wood", + "stairs:slab_brick", + "stairs:slab_cobble", + "stairs:slab_desert_cobble", + "stairs:slab_desert_sandstone", + "stairs:slab_desert_sandstone_block", + "stairs:slab_desert_sandstone_brick", + "stairs:slab_desert_stone", + "stairs:slab_desert_stone_block", + "stairs:slab_desert_stonebrick", + "stairs:slab_glass", + "stairs:slab_goldblock", + "stairs:slab_ice", + "stairs:slab_junglewood", + "stairs:slab_mossycobble", + "stairs:slab_obsidian", + "stairs:slab_obsidian_block", + "stairs:slab_obsidian_glass", + "stairs:slab_obsidianbrick", + "stairs:slab_pine_wood", + "stairs:slab_sandstone", + "stairs:slab_sandstone_block", + "stairs:slab_sandstonebrick", + "stairs:slab_silver_sandstone", + "stairs:slab_silver_sandstone_block", + "stairs:slab_silver_sandstone_brick", + "stairs:slab_snowblock", + "stairs:slab_stone", + "stairs:slab_stone_block", + "stairs:slab_stonebrick", + "stairs:slab_straw", + "stairs:slab_wood", + "stairs:stair_acacia_wood", + "stairs:stair_aspen_wood", + "stairs:stair_brick", + "stairs:stair_cobble", + "stairs:stair_desert_cobble", + "stairs:stair_desert_sandstone", + "stairs:stair_desert_sandstone_block", + "stairs:stair_desert_sandstone_brick", + "stairs:stair_desert_stone", + "stairs:stair_desert_stone_block", + "stairs:stair_desert_stonebrick", + "stairs:stair_glass", + "stairs:stair_goldblock", + "stairs:stair_ice", + "stairs:stair_inner_acacia_wood", + "stairs:stair_inner_aspen_wood", + "stairs:stair_inner_brick", + "stairs:stair_inner_cobble", + "stairs:stair_inner_desert_cobble", + "stairs:stair_inner_desert_sandstone", + "stairs:stair_inner_desert_sandstone_block", + "stairs:stair_inner_desert_sandstone_brick", + "stairs:stair_inner_desert_stone", + "stairs:stair_inner_desert_stone_block", + "stairs:stair_inner_desert_stonebrick", + "stairs:stair_inner_glass", + "stairs:stair_inner_goldblock", + "stairs:stair_inner_ice", + "stairs:stair_inner_junglewood", + "stairs:stair_inner_mossycobble", + "stairs:stair_inner_obsidian", + "stairs:stair_inner_obsidian_block", + "stairs:stair_inner_obsidian_glass", + "stairs:stair_inner_obsidianbrick", + "stairs:stair_inner_pine_wood", + "stairs:stair_inner_sandstone", + "stairs:stair_inner_sandstone_block", + "stairs:stair_inner_sandstonebrick", + "stairs:stair_inner_silver_sandstone", + "stairs:stair_inner_silver_sandstone_block", + "stairs:stair_inner_silver_sandstone_brick", + "stairs:stair_inner_snowblock", + "stairs:stair_inner_stone", + "stairs:stair_inner_stone_block", + "stairs:stair_inner_stonebrick", + "stairs:stair_inner_straw", + "stairs:stair_inner_wood", + "stairs:stair_junglewood", + "stairs:stair_mossycobble", + "stairs:stair_obsidian", + "stairs:stair_obsidian_block", + "stairs:stair_obsidian_glass", + "stairs:stair_obsidianbrick", + "stairs:stair_outer_acacia_wood", + "stairs:stair_outer_aspen_wood", + "stairs:stair_outer_brick", + "stairs:stair_outer_cobble", + "stairs:stair_outer_desert_cobble", + "stairs:stair_outer_desert_sandstone", + "stairs:stair_outer_desert_sandstone_block", + "stairs:stair_outer_desert_sandstone_brick", + "stairs:stair_outer_desert_stone", + "stairs:stair_outer_desert_stone_block", + "stairs:stair_outer_desert_stonebrick", + "stairs:stair_outer_glass", + "stairs:stair_outer_goldblock", + "stairs:stair_outer_ice", + "stairs:stair_outer_junglewood", + "stairs:stair_outer_mossycobble", + "stairs:stair_outer_obsidian", + "stairs:stair_outer_obsidian_block", + "stairs:stair_outer_obsidian_glass", + "stairs:stair_outer_obsidianbrick", + "stairs:stair_outer_pine_wood", + "stairs:stair_outer_sandstone", + "stairs:stair_outer_sandstone_block", + "stairs:stair_outer_sandstonebrick", + "stairs:stair_outer_silver_sandstone", + "stairs:stair_outer_silver_sandstone_block", + "stairs:stair_outer_silver_sandstone_brick", + "stairs:stair_outer_snowblock", + "stairs:stair_outer_stone", + "stairs:stair_outer_stone_block", + "stairs:stair_outer_stonebrick", + "stairs:stair_outer_straw", + "stairs:stair_outer_wood", + "stairs:stair_pine_wood", + "stairs:stair_sandstone", + "stairs:stair_sandstone_block", + "stairs:stair_sandstonebrick", + "stairs:stair_silver_sandstone", + "stairs:stair_silver_sandstone_block", + "stairs:stair_silver_sandstone_brick", + "stairs:stair_snowblock", + "stairs:stair_stone", + "stairs:stair_stone_block", + "stairs:stair_stonebrick", + "stairs:stair_straw", + "stairs:stair_wood", + + "xpanes:bar", + "xpanes:bar_flat", + "xpanes:door_steel_bar", + "xpanes:door_steel_bar_a", + "xpanes:door_steel_bar_b", + "xpanes:door_steel_bar_c", + "xpanes:door_steel_bar_d", + "xpanes:obsidian_pane", + "xpanes:obsidian_pane_flat", + "xpanes:pane", + "xpanes:pane_flat", + "xpanes:trapdoor_steel_bar", + "xpanes:trapdoor_steel_bar_open", + + "walls:cobble", + "walls:desertcobble", + "walls:mossycobble", +}) + +unified_inventory.add_category_items('environment', { + "air", + "default:cave_ice", + "default:dirt_with_rainforest_litter", + "default:gravel", + "default:dry_dirt_with_dry_grass", + "default:permafrost", + "default:desert_stone", + "default:ice", + "default:dry_dirt", + "default:obsidian", + "default:sand", + "default:river_water_source", + "default:dirt_with_snow", + "default:dirt_with_grass", + "default:water_flowing", + "default:dirt", + "default:desert_sand", + "default:permafrost_with_moss", + "default:dirt_with_coniferous_litter", + "default:water_source", + "default:dirt_with_dry_grass", + "default:river_water_flowing", + "default:stone", + "default:snow", + "default:lava_flowing", + "default:lava_source", + "default:permafrost_with_stones", + "default:dirt_with_grass_footsteps", + "default:silver_sand", + "default:snowblock", + "default:clay", + + "farming:desert_sand_soil", + "farming:desert_sand_soil_wet", + "farming:dry_soil", + "farming:dry_soil_wet", + "farming:soil", + "farming:soil_wet", +}) + +unified_inventory.add_category_items('lighting', { + "default:mese_post_light_junglewood", + "default:torch_ceiling", + "default:meselamp", + "default:torch", + "default:mese_post_light_acacia_wood", + "default:mese_post_light", + "default:torch_wall", + "default:mese_post_light_pine_wood", + "default:mese_post_light_aspen_wood" +}) +--]] + + +--[[ UNCATEGORISED + + "farming:string", + + "beds:bed_bottom", + "beds:bed_top", + "beds:fancy_bed_bottom", + "beds:fancy_bed_top", + "boats:boat", + "bones:bones", + + "bucket:bucket_lava", + "bucket:bucket_river_water", + "bucket:bucket_water", + + "butterflies:butterfly_red", + "butterflies:butterfly_violet", + "butterflies:butterfly_white", + "butterflies:hidden_butterfly_red", + "butterflies:hidden_butterfly_violet", + "butterflies:hidden_butterfly_white", + + "carts:brakerail", + "carts:cart", + "carts:powerrail", + "carts:rail", + + "default:book", + "default:book_written", + "default:bookshelf", + "default:chest", + "default:chest_locked", + "default:chest_locked_open", + "default:chest_open", + "default:clay_lump", + "default:cloud", + "default:coral_brown", + "default:coral_cyan", + "default:coral_green", + "default:coral_orange", + "default:coral_pink", + "default:coral_skeleton", + "default:flint", + "default:furnace", + "default:furnace_active", + "default:key", + "default:ladder_steel", + "default:ladder_wood", + "default:obsidian_shard", + "default:paper", + "default:sign_wall_steel", + "default:sign_wall_wood", + "default:stick", + + "fire:basic_flame", + "fire:permanent_flame", + "fireflies:firefly", + "fireflies:firefly_bottle", + "fireflies:hidden_firefly", + + "ignore", + "unknown", + + "tnt:boom", + "tnt:gunpowder", + "tnt:gunpowder_burning", + "tnt:tnt", + "tnt:tnt_burning", + "tnt:tnt_stick", + + "vessels:drinking_glass", + "vessels:glass_bottle", + "vessels:glass_fragments", + "vessels:shelf", + "vessels:steel_bottle", + + "dye:black", + "dye:blue", + "dye:brown", + "dye:cyan", + "dye:dark_green", + "dye:dark_grey", + "dye:green", + "dye:grey", + "dye:magenta", + "dye:orange", + "dye:pink", + "dye:red", + "dye:violet", + "dye:white", + "dye:yellow", + + "wool:black", + "wool:blue", + "wool:brown", + "wool:cyan", + "wool:dark_green", + "wool:dark_grey", + "wool:green", + "wool:grey", + "wool:magenta", + "wool:orange", + "wool:pink", + "wool:red", + "wool:violet", + "wool:white", + "wool:yellow", + + "unified_inventory:bag_large", + "unified_inventory:bag_medium", + "unified_inventory:bag_small", +--]] + +--[[ LIST UNCATEGORIZED AFTER LOAD +minetest.register_on_mods_loaded(function() + minetest.after(1, function ( ) + local l = {} + for name,_ in pairs(minetest.registered_items) do + if not unified_inventory.find_category(name) then + -- minetest.log("error", minetest.serialize(minetest.registered_items[name])) + table.insert(l, name) + end + end + table.sort(l) + minetest.log(table.concat(l, '",'.."\n"..'"')) + end) +end) +--]] \ No newline at end of file diff --git a/unified_inventory/doc/mod_api.txt b/unified_inventory/doc/mod_api.txt index c0be129..ef87697 100644 --- a/unified_inventory/doc/mod_api.txt +++ b/unified_inventory/doc/mod_api.txt @@ -3,6 +3,14 @@ unified_inventory API This file provides information about the API of unified_inventory. +API revisions within unified_inventory can be checked using: + + (unified_inventory.version or 1) + +**Revision history** + +* Version `1`: Classic formspec layout (no real_coordinates) +* Version `2`: Force formspec version 4 (includes real_coordinates) Misc functions -------------- @@ -12,6 +20,64 @@ Grouped by use-case, afterwards sorted alphabetically. * Checks whether creative is enabled or the player has `creative` +Callbacks +--------- + +Register a callback that will be run whenever a craft is registered via unified_inventory.register_craft: + + unified_inventory.register_on_craft_registered( + function (item_name, options) + -- item_name (string): name of the output item, equivalent to `ItemStack:get_name()` + -- options (table): definition table of crafts registered by `unified_inventory.register_craft` + end + ) + +Register a callback that will be run after all mods have loaded and after the unified_inventory mod has initialised all its internal structures: + + unified_inventory.register_on_initialized(callback) + -- The callback is passed no arguments + + +Accessing Data +-------------- + +These methods should be used instead of accessing the unified_inventory data structures directly - this will ensure your code survives any potential restructuring of the mod. + +Get a list of recipes for a particular output item: + + unified_inventory.get_recipe_list(output_item) + + Returns a list of tables, each holding a recipe definition, like: + { + { + type = "normal", + items = { "default:stick", "default:stick", "default:stick", "default:stick" }, + output = "default:wood", + width = 2 + }, + { + type = "shapeless", + items = { "default:tree" }, + output = "default:wood 4", + width = 0 + }, + ... + } + +Get a list of all the output items crafts have been registered for: + + unified_inventory.get_registered_outputs() + + Returns a list of item names, like: + { + "default:stone", + "default:chest", + "default:brick", + "doors:door_wood", + ... + } + + Pages ----- @@ -93,3 +159,72 @@ Register a non-standard craft recipe: -- ^ Same as `minetest.register_recipe` }) + +Categories +---------- + +Register a new category: + The config table (second argument) is optional, and all its members are optional + See the unified_inventory.set_category_* functions for more details on the members of the config table + + unified_inventory.register_category("category_name", { + symbol = "mod_name:item_name" or "texture.png", + label = "Human Readable Label", + index = 5, + items = { + "mod_name:item_name", + "another_mod:different_item" + } + }) + +Add / override the symbol for a category: + The category does not need to exist first + The symbol can be an item name or a texture image + If unset this will default to "default:stick" + + unified_inventory.set_category_symbol("category_name", "mod_name:item_name" or "texture.png") + +Add / override the human readable label for a category: + If unset this will default to the category name + + unified_inventory.set_category_label("category_name", "Human Readable Label") + +Add / override the sorting index of the category: + Must be a number, can also be negative (-5) or fractional (2.345) + This determines the position the category appears in the list of categories + The "all" meta-category has index -2, the "misc"/"uncategorized" meta-category has index -1, use a negative number smaller than these to make a category appear before these in the list + By default categories are sorted alphabetically with an index between 0.0101(AA) and 0.2626(ZZ) + + unified_inventory.set_category_index("category_name", 5) + +Add a single item to a category: + + unified_inventory.add_category_item("category_name", "mod_name:item_name") + +Add multiple items to a category: + + unified_inventory.add_category_items("category_name", { + "mod_name:item_name", + "another_mod:different_item" + }) + +Remove an item from a category: + + unified_inventory.remove_category_item("category_name", "mod_name:item_name") + +Remove a category entirely: + + unified_inventory.remove_category("category_name") + +Finding existing items in categories: + This will find the first category an item exists in + It should be used for checking if an item is catgorised + Returns "category_name" or nil + + unified_inventory.find_category("mod_name:item_name") + + + This will find all the categories an item exists in + Returns a number indexed table (list) of category names + + unified_inventory.find_categories("mod_name:item_name") diff --git a/unified_inventory/init.lua b/unified_inventory/init.lua index 7be101c..98ee2e5 100644 --- a/unified_inventory/init.lua +++ b/unified_inventory/init.lua @@ -1,4 +1,4 @@ --- Unified Inventory for Minetest >= 0.4.16 +-- Unified Inventory local modpath = minetest.get_modpath(minetest.get_current_modname()) local worldpath = minetest.get_worldpath() @@ -10,6 +10,8 @@ unified_inventory = { alternate = {}, current_page = {}, current_searchbox = {}, + current_category = {}, + current_category_scroll = {}, current_index = {}, current_item = {}, current_craft_direction = {}, @@ -22,6 +24,8 @@ unified_inventory = { filtered_items_list = {}, pages = {}, buttons = {}, + initialized_callbacks = {}, + craft_registered_callbacks = {}, -- Homepos stuff home_pos = {}, @@ -33,23 +37,111 @@ unified_inventory = { -- "Lite" mode lite_mode = minetest.settings:get_bool("unified_inventory_lite"), + -- Items automatically added to categories based on item definitions + automatic_categorization = (minetest.settings:get_bool("unified_inventory_automatic_categorization") ~= false), + -- Trash enabled trash_enabled = (minetest.settings:get_bool("unified_inventory_trash") ~= false), + imgscale = 1.25, + list_img_offset = 0.13, + standard_background = "background9[0,0;1,1;ui_formbg_9_sliced.png;true;16]", - pagecols = 8, - pagerows = 10, - page_y = 0, - formspec_y = 1, - main_button_x = 0, - main_button_y = 9, - craft_result_x = 0.3, - craft_result_y = 0.5, - form_header_y = 0, - standard_background = "background[-0.2,-0.2;1,1;ui_form_bg.png;true]", -- the 'true' scales to fill, overrides the 1,1 - standard_inv = "list[current_player;main;0,YYY;8,4;]", -- the YYY's are placeholders which get - standard_inv_bg = "image[-0.1,YYY;10.05,4.70;ui_main_inventory.png]", -- replaced later by string.gsub() + version = 3 } +local ui = unified_inventory + +-- These tables establish position and layout for the two UI styles. +-- UI doesn't use formspec_[xy] anymore, but other mods may need them. + +ui.style_full = { + formspec_x = 1, + formspec_y = 1, + formw = 17.75, + formh = 12.25, + pagecols = 8, + pagerows = 9, + page_x = 10.75, + page_y = 2.30, + craft_x = 2.8, + craft_y = 1.15, + craftresult_x = 7.8, + craft_arrow_x = 6.55, + craft_guide_x = 3.3, + craft_guide_y = 1.15, + craft_guide_arrow_x = 7.05, + craft_guide_result_x = 8.3, + craft_guide_resultstr_x = 0.3, + craft_guide_resultstr_y = 0.6, + give_btn_x = 0.25, + main_button_x = 0.4, + main_button_y = 11.0, + page_buttons_x = 11.60, + page_buttons_y = 10.15, + searchwidth = 3.4, + form_header_x = 0.4, + form_header_y = 0.4, + btn_spc = 0.85, + btn_size = 0.75, + std_inv_x = 0.3, + std_inv_y = 5.75, +} + +ui.style_lite = { + formspec_x = 0.6, + formspec_y = 0.6, + formw = 14, + formh = 9.75, + pagecols = 4, + pagerows = 5, + page_x = 10.5, + page_y = 2.15, + craft_x = 2.6, + craft_y = 0.75, + craftresult_x = 5.75, + craft_arrow_x = 6.35, + craft_guide_x = 3.1, + craft_guide_y = 0.75, + craft_guide_arrow_x = 7.05, + craft_guide_result_x = 8.3, + craft_guide_resultstr_x = 0.15, + craft_guide_resultstr_y = 0.35, + give_btn_x = 0.15, + main_button_x = 10.5, + main_button_y = 8.15, + page_buttons_x = 10.5, + page_buttons_y = 6.15, + searchwidth = 1.6, + form_header_x = 0.2, + form_header_y = 0.2, + btn_spc = 0.8, + btn_size = 0.7, + std_inv_x = 0.1, + std_inv_y = 4.6, +} + +dofile(modpath.."/api.lua") + +for _, style in ipairs({ui.style_full, ui.style_lite}) do + style.items_per_page = style.pagecols * style.pagerows + style.standard_inv = string.format("list[current_player;main;%f,%f;8,4;]", + style.std_inv_x + ui.list_img_offset, style.std_inv_y + ui.list_img_offset) + + style.standard_inv_bg = ui.make_inv_img_grid(style.std_inv_x, style.std_inv_y, 8, 1, true).. + ui.make_inv_img_grid(style.std_inv_x, style.std_inv_y + ui.imgscale, 8, 3) + + style.craft_grid = table.concat({ + ui.make_inv_img_grid(style.craft_x, style.craft_y, 3, 3), + ui.single_slot(style.craft_x + ui.imgscale*4, style.craft_y), -- the craft result slot + string.format("image[%f,%f;%f,%f;ui_crafting_arrow.png]", + style.craft_arrow_x, style.craft_y, ui.imgscale, ui.imgscale), + string.format("list[current_player;craft;%f,%f;3,3;]", + style.craft_x + ui.list_img_offset, style.craft_y + ui.list_img_offset), + string.format("list[current_player;craftpreview;%f,%f;1,1;]", + style.craftresult_x + ui.list_img_offset, style.craft_y + ui.list_img_offset) + }) +end + -- Disable default creative inventory local creative = rawget(_G, "creative") or rawget(_G, "creative_inventory") if creative then @@ -65,7 +157,8 @@ if sfinv then end dofile(modpath.."/group.lua") -dofile(modpath.."/api.lua") +dofile(modpath.."/category.lua") +dofile(modpath.."/default-categories.lua") dofile(modpath.."/internal.lua") dofile(modpath.."/callbacks.lua") dofile(modpath.."/match_craft.lua") @@ -76,7 +169,4 @@ if minetest.settings:get_bool("unified_inventory_bags") ~= false then end dofile(modpath.."/item_names.lua") - -if minetest.get_modpath("datastorage") then - dofile(modpath.."/waypoints.lua") -end +dofile(modpath.."/waypoints.lua") diff --git a/unified_inventory/internal.lua b/unified_inventory/internal.lua index 78cba2a..b49906e 100644 --- a/unified_inventory/internal.lua +++ b/unified_inventory/internal.lua @@ -1,5 +1,6 @@ local S = minetest.get_translator("unified_inventory") local F = minetest.formspec_escape +local ui = unified_inventory -- This pair of encoding functions is used where variable text must go in -- button names, where the text might contain formspec metacharacters. @@ -9,269 +10,310 @@ local F = minetest.formspec_escape -- This is a game engine bug, and in the anticipation that it might be -- fixed some day we don't want to rely on it. So for safety we apply -- an encoding that avoids all formspec metacharacters. -function unified_inventory.mangle_for_formspec(str) + +function ui.mangle_for_formspec(str) return string.gsub(str, "([^A-Za-z0-9])", function (c) return string.format("_%d_", string.byte(c)) end) end -function unified_inventory.demangle_for_formspec(str) +function ui.demangle_for_formspec(str) return string.gsub(str, "_([0-9]+)_", function (v) return string.char(v) end) end -function unified_inventory.get_per_player_formspec(player_name) - local lite = unified_inventory.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true}) - local ui = {} - ui.pagecols = unified_inventory.pagecols - ui.pagerows = unified_inventory.pagerows - ui.page_y = unified_inventory.page_y - ui.formspec_y = unified_inventory.formspec_y - ui.main_button_x = unified_inventory.main_button_x - ui.main_button_y = unified_inventory.main_button_y - ui.craft_result_x = unified_inventory.craft_result_x - ui.craft_result_y = unified_inventory.craft_result_y - ui.form_header_y = unified_inventory.form_header_y +function ui.get_per_player_formspec(player_name) + local draw_lite_mode = ui.lite_mode and not minetest.check_player_privs(player_name, {ui_full=true}) - if lite then - ui.pagecols = 4 - ui.pagerows = 6 - ui.page_y = 0.25 - ui.formspec_y = 0.47 - ui.main_button_x = 8.2 - ui.main_button_y = 6.5 - ui.craft_result_x = 2.8 - ui.craft_result_y = 3.4 - ui.form_header_y = -0.1 - end - - ui.items_per_page = ui.pagecols * ui.pagerows - return ui, lite + local style = table.copy(draw_lite_mode and ui.style_lite or ui.style_full) + style.is_lite_mode = draw_lite_mode + return style end -function unified_inventory.get_formspec(player, page) +local function formspec_button(ui_peruser, name, image, offset, pos, scale, label) + local element = 'image_button' + if minetest.registered_items[image] then + element = 'item_image_button' + elseif image:find(":", 1, true) then + image = "unknown_item.png" + end + local spc = (1-scale)*ui_peruser.btn_size/2 + local size = ui_peruser.btn_size*scale + return string.format("%s[%f,%f;%f,%f;%s;%s;]", element, + (offset.x or offset[1]) + ( ui_peruser.btn_spc * (pos.x or pos[1]) ) + spc, + (offset.y or offset[2]) + ( ui_peruser.btn_spc * (pos.y or pos[2]) ) + spc, + size, size, image, name) .. + string.format("tooltip[%s;%s]", name, F(label or name)) +end + +local function formspec_add_filters(player, formspec, style) + local button_row = 0 + local button_col = 0 + local n = #formspec + 1 + + -- Main buttons + + local filtered_inv_buttons = {} + + for i, def in pairs(ui.buttons) do + if not (style.is_lite_mode and def.hide_lite) then + table.insert(filtered_inv_buttons, def) + end + end + + for i, def in pairs(filtered_inv_buttons) do + if style.is_lite_mode and i > 4 then + button_row = 1 + button_col = 1 + end + + if def.type == "image" then + local pos_x = style.main_button_x + style.btn_spc * (i - 1) - button_col * style.btn_spc * 4 + local pos_y = style.main_button_y + button_row * style.btn_spc + if (def.condition == nil or def.condition(player) == true) then + formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s;]", + pos_x, pos_y, style.btn_size, style.btn_size, + F(def.image), + F(def.name)) + formspec[n+1] = "tooltip["..F(def.name)..";"..(def.tooltip or "").."]" + n = n+2 + else + formspec[n] = string.format("image[%f,%f;%f,%f;%s^[colorize:#808080:alpha]", + pos_x, pos_y, style.btn_size, style.btn_size, + def.image) + n = n+1 + end + end + end +end + +local function formspec_add_categories(player, formspec, ui_peruser) + local player_name = player:get_player_name() + local n = #formspec + 1 + + local categories_pos = { + ui_peruser.page_x, + ui_peruser.page_y-ui_peruser.btn_spc-0.5 + } + local categories_scroll_pos = { + ui_peruser.page_x, + ui_peruser.form_header_y - (ui_peruser.is_lite_mode and 0 or 0.2) + } + + formspec[n] = string.format("background9[%f,%f;%f,%f;%s;false;3]", + ui_peruser.page_x-0.1, categories_scroll_pos[2], + (ui_peruser.btn_spc * ui_peruser.pagecols) + 0.13, 1.4 + (ui_peruser.is_lite_mode and 0 or 0.2), + "ui_smallbg_9_sliced.png") + n = n + 1 + + formspec[n] = string.format("label[%f,%f;%s]", + ui_peruser.page_x, + ui_peruser.form_header_y + (ui_peruser.is_lite_mode and 0.3 or 0.2), F(S("Category:"))) + n = n + 1 + + local scroll_offset = 0 + local category_count = #ui.category_list + if category_count > ui_peruser.pagecols then + scroll_offset = ui.current_category_scroll[player_name] + end + + for index, category in ipairs(ui.category_list) do + local column = index - scroll_offset + if column > 0 and column <= ui_peruser.pagecols then + local scale = 0.8 + if ui.current_category[player_name] == category.name then + scale = 1 + end + formspec[n] = formspec_button(ui_peruser, "category_"..category.name, category.symbol, categories_pos, {column-1, 0}, scale, category.label) + n = n + 1 + end + end + if category_count > ui_peruser.pagecols and scroll_offset > 0 then + -- prev + formspec[n] = formspec_button(ui_peruser, "prev_category", "ui_left_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 2, 0}, 0.8, S("Scroll categories left")) + n = n + 1 + end + if category_count > ui_peruser.pagecols and category_count - scroll_offset > ui_peruser.pagecols then + -- next + formspec[n] = formspec_button(ui_peruser, "next_category", "ui_right_icon.png", categories_scroll_pos, {ui_peruser.pagecols - 1, 0}, 0.8, S("Scroll categories right")) + end +end + +local function formspec_add_search_box(player, formspec, ui_peruser) + local player_name = player:get_player_name() + local n = #formspec + 1 + + formspec[n] = "field_close_on_enter[searchbox;false]" + + formspec[n+1] = string.format("field[%f,%f;%f,%f;searchbox;;%s]", + ui_peruser.page_buttons_x, ui_peruser.page_buttons_y, + ui_peruser.searchwidth - 0.1, ui_peruser.btn_size, + F(ui.current_searchbox[player_name])) + formspec[n+2] = string.format("image_button[%f,%f;%f,%f;ui_search_icon.png;searchbutton;]", + ui_peruser.page_buttons_x + ui_peruser.searchwidth, ui_peruser.page_buttons_y, + ui_peruser.btn_size,ui_peruser.btn_size) + formspec[n+3] = "tooltip[searchbutton;" ..F(S("Search")) .. "]" + formspec[n+4] = string.format("image_button[%f,%f;%f,%f;ui_reset_icon.png;searchresetbutton;]", + ui_peruser.page_buttons_x + ui_peruser.searchwidth + ui_peruser.btn_spc, + ui_peruser.page_buttons_y, + ui_peruser.btn_size, ui_peruser.btn_size) + formspec[n+5] = "tooltip[searchresetbutton;"..F(S("Reset search and display everything")).."]" + + if ui.activefilter[player_name] ~= "" then + formspec[n+6] = string.format("label[%f,%f;%s: %s]", + ui_peruser.page_x, ui_peruser.page_y - 0.25, + F(S("Filter")), F(ui.activefilter[player_name])) + end +end + +local function formspec_add_item_browser(player, formspec, ui_peruser) + local player_name = player:get_player_name() + local n = #formspec + 1 + + -- Controls to flip items pages + + local btnlist = { + { "ui_skip_backward_icon.png", "start_list", S("First page") }, + { "ui_doubleleft_icon.png", "rewind3", S("Back three pages") }, + { "ui_left_icon.png", "rewind1", S("Back one page") }, + { "ui_right_icon.png", "forward1", S("Forward one page") }, + { "ui_doubleright_icon.png", "forward3", S("Forward three pages") }, + { "ui_skip_forward_icon.png", "end_list", S("Last page") }, + } + + if ui_peruser.is_lite_mode then + btnlist[2] = nil + btnlist[5] = nil + end + + local bn = 0 + for _, b in pairs(btnlist) do + formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s;]", + ui_peruser.page_buttons_x + ui_peruser.btn_spc*bn, + ui_peruser.page_buttons_y + ui_peruser.btn_spc, + ui_peruser.btn_size, ui_peruser.btn_size, + b[1],b[2]) + formspec[n+1] = "tooltip["..b[2]..";"..F(b[3]).."]" + bn = bn + 1 + n = n + 2 + end + + -- Items list + if #ui.filtered_items_list[player_name] == 0 then + local no_matches = S("No matching items") + if ui_peruser.is_lite_mode then + no_matches = S("No matches.") + end + + formspec[n] = "label["..ui_peruser.page_x..","..(ui_peruser.page_y+0.15)..";" .. F(no_matches) .. "]" + return + end + + local dir = ui.active_search_direction[player_name] + local list_index = ui.current_index[player_name] + local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1) + local pagemax = math.floor( + (#ui.filtered_items_list[player_name] - 1) + / (ui_peruser.items_per_page) + 1) + for y = 0, ui_peruser.pagerows - 1 do + for x = 0, ui_peruser.pagecols - 1 do + local name = ui.filtered_items_list[player_name][list_index] + local item = minetest.registered_items[name] + if item then + -- Clicked on current item: Flip crafting direction + if name == ui.current_item[player_name] then + local cdir = ui.current_craft_direction[player_name] + if cdir == "recipe" then + dir = "usage" + elseif cdir == "usage" then + dir = "recipe" + end + else + -- Default: use active search direction by default + dir = ui.active_search_direction[player_name] + end + + local button_name = "item_button_" .. dir .. "_" + .. ui.mangle_for_formspec(name) + formspec[n] = ("item_image_button[%f,%f;%f,%f;%s;%s;]"):format( + ui_peruser.page_x + x * ui_peruser.btn_spc, + ui_peruser.page_y + y * ui_peruser.btn_spc, + ui_peruser.btn_size, ui_peruser.btn_size, + name, button_name + ) + formspec[n + 1] = ("tooltip[%s;%s]"):format( + button_name, minetest.formspec_escape(item.description) + ) + n = n + 2 + list_index = list_index + 1 + end + end + end + formspec[n] = string.format("label[%f,%f;%s: %s]", + ui_peruser.page_buttons_x + ui_peruser.btn_spc * (ui_peruser.is_lite_mode and 1 or 2), + ui_peruser.page_buttons_y + 0.1 + ui_peruser.btn_spc * 2, + F(S("Page")), S("@1 of @2",page2,pagemax)) +end + +function ui.get_formspec(player, page) if not player then return "" end local player_name = player:get_player_name() - local ui_peruser,draw_lite_mode = unified_inventory.get_per_player_formspec(player_name) + local ui_peruser = ui.get_per_player_formspec(player_name) - unified_inventory.current_page[player_name] = page - local pagedef = unified_inventory.pages[page] + ui.current_page[player_name] = page + local pagedef = ui.pages[page] if not pagedef then return "" -- Invalid page name end - local formspec = { - "size[14,10]", + local fs = { + "formspec_version[4]", + "size["..ui_peruser.formw..","..ui_peruser.formh.."]", pagedef.formspec_prepend and "" or "no_prepend[]", - unified_inventory.standard_background -- Background + ui.standard_background } - local n = 4 - if draw_lite_mode then - formspec[1] = "size[11,7.7]" - formspec[3] = unified_inventory.standard_background - end - - if unified_inventory.is_creative(player_name) - and page == "craft" then - formspec[n] = "background[0,"..(ui_peruser.formspec_y + 2)..";1,1;ui_single_slot.png]" - n = n+1 - end - - local perplayer_formspec = unified_inventory.get_per_player_formspec(player_name) + local perplayer_formspec = ui.get_per_player_formspec(player_name) local fsdata = pagedef.get_formspec(player, perplayer_formspec) - formspec[n] = fsdata.formspec - n = n+1 + fs[#fs + 1] = fsdata.formspec - local button_row = 0 - local button_col = 0 - - -- Main buttons - - local filtered_inv_buttons = {} - - for i, def in pairs(unified_inventory.buttons) do - if not (draw_lite_mode and def.hide_lite) then - table.insert(filtered_inv_buttons, def) - end - end - - for i, def in pairs(filtered_inv_buttons) do - - if draw_lite_mode and i > 4 then - button_row = 1 - button_col = 1 - end - - if def.type == "image" then - if (def.condition == nil or def.condition(player) == true) then - formspec[n] = "image_button[" - formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (i - 1) - button_col * 0.65 * 4) - formspec[n+2] = ","..(ui_peruser.main_button_y + button_row * 0.7)..";0.8,0.8;" - formspec[n+3] = F(def.image)..";" - formspec[n+4] = F(def.name)..";]" - formspec[n+5] = "tooltip["..F(def.name) - formspec[n+6] = ";"..(def.tooltip or "").."]" - n = n+7 - else - formspec[n] = "image[" - formspec[n+1] = ( ui_peruser.main_button_x + 0.65 * (i - 1) - button_col * 0.65 * 4) - formspec[n+2] = ","..(ui_peruser.main_button_y + button_row * 0.7)..";0.8,0.8;" - formspec[n+3] = F(def.image).."^[colorize:#808080:alpha]" - n = n+4 - - end - end - end + formspec_add_filters(player, fs, ui_peruser) if fsdata.draw_inventory ~= false then -- Player inventory - formspec[n] = "listcolors[#00000000;#00000000]" - formspec[n+1] = string.gsub(unified_inventory.standard_inv, "YYY", ui_peruser.formspec_y + 3.5) - n = n+2 + fs[#fs + 1] = "listcolors[#00000000;#00000000]" + fs[#fs + 1] = ui_peruser.standard_inv end if fsdata.draw_item_list == false then - return table.concat(formspec, "") + return table.concat(fs, "") end - -- Controls to flip items pages - local start_x = 9.2 + formspec_add_categories(player, fs, ui_peruser) + formspec_add_search_box(player, fs, ui_peruser) + formspec_add_item_browser(player, fs, ui_peruser) - if not draw_lite_mode then - formspec[n] = - "image_button[" .. (start_x + 0.6 * 0) - .. ",9;.8,.8;ui_skip_backward_icon.png;start_list;]" - .. "tooltip[start_list;" .. F(S("First page")) .. "]" - - .. "image_button[" .. (start_x + 0.6 * 1) - .. ",9;.8,.8;ui_doubleleft_icon.png;rewind3;]" - .. "tooltip[rewind3;" .. F(S("Back three pages")) .. "]" - .. "image_button[" .. (start_x + 0.6 * 2) - .. ",9;.8,.8;ui_left_icon.png;rewind1;]" - .. "tooltip[rewind1;" .. F(S("Back one page")) .. "]" - - .. "image_button[" .. (start_x + 0.6 * 3) - .. ",9;.8,.8;ui_right_icon.png;forward1;]" - .. "tooltip[forward1;" .. F(S("Forward one page")) .. "]" - .. "image_button[" .. (start_x + 0.6 * 4) - .. ",9;.8,.8;ui_doubleright_icon.png;forward3;]" - .. "tooltip[forward3;" .. F(S("Forward three pages")) .. "]" - - .. "image_button[" .. (start_x + 0.6 * 5) - .. ",9;.8,.8;ui_skip_forward_icon.png;end_list;]" - .. "tooltip[end_list;" .. F(S("Last page")) .. "]" - else - formspec[n] = - "image_button[" .. (8.2 + 0.65 * 0) - .. ",5.8;.8,.8;ui_skip_backward_icon.png;start_list;]" - .. "tooltip[start_list;" .. F(S("First page")) .. "]" - .. "image_button[" .. (8.2 + 0.65 * 1) - .. ",5.8;.8,.8;ui_left_icon.png;rewind1;]" - .. "tooltip[rewind1;" .. F(S("Back one page")) .. "]" - .. "image_button[" .. (8.2 + 0.65 * 2) - .. ",5.8;.8,.8;ui_right_icon.png;forward1;]" - .. "tooltip[forward1;" .. F(S("Forward one page")) .. "]" - .. "image_button[" .. (8.2 + 0.65 * 3) - .. ",5.8;.8,.8;ui_skip_forward_icon.png;end_list;]" - .. "tooltip[end_list;" .. F(S("Last page")) .. "]" - end - n = n+1 - - -- Search box - formspec[n] = "field_close_on_enter[searchbox;false]" - n = n+1 - - if not draw_lite_mode then - formspec[n] = "field[9.5,8.325;3,1;searchbox;;" - .. F(unified_inventory.current_searchbox[player_name]) .. "]" - formspec[n+1] = "image_button[12.2,8.1;.8,.8;ui_search_icon.png;searchbutton;]" - .. "tooltip[searchbutton;" ..F(S("Search")) .. "]" - formspec[n+2] = "image_button[12.9,8.1;.8,.8;ui_reset_icon.png;searchresetbutton;]" - .. "tooltip[searchbutton;" ..F(S("Search")) .. "]" - .. "tooltip[searchresetbutton;" ..F(S("Reset search and display everything")) .. "]" - else - formspec[n] = "field[8.5,5.225;2.2,1;searchbox;;" - .. F(unified_inventory.current_searchbox[player_name]) .. "]" - formspec[n+1] = "image_button[10.3,5;.8,.8;ui_search_icon.png;searchbutton;]" - .. "tooltip[searchbutton;" ..F(S("Search")) .. "]" - formspec[n+2] = "image_button[11,5;.8,.8;ui_reset_icon.png;searchresetbutton;]" - .. "tooltip[searchbutton;" ..F(S("Search")) .. "]" - .. "tooltip[searchresetbutton;" ..F(S("Reset search and display everything")) .. "]" - end - n = n+3 - - local no_matches = S("No matching items") - if draw_lite_mode then - no_matches = S("No matches.") - end - - -- Items list - if #unified_inventory.filtered_items_list[player_name] == 0 then - formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";" .. F(no_matches) .. "]" - else - local dir = unified_inventory.active_search_direction[player_name] - local list_index = unified_inventory.current_index[player_name] - local page2 = math.floor(list_index / (ui_peruser.items_per_page) + 1) - local pagemax = math.floor( - (#unified_inventory.filtered_items_list[player_name] - 1) - / (ui_peruser.items_per_page) + 1) - for y = 0, ui_peruser.pagerows - 1 do - for x = 0, ui_peruser.pagecols - 1 do - local name = unified_inventory.filtered_items_list[player_name][list_index] - local item = minetest.registered_items[name] - if item then - -- Clicked on current item: Flip crafting direction - if name == unified_inventory.current_item[player_name] then - local cdir = unified_inventory.current_craft_direction[player_name] - if cdir == "recipe" then - dir = "usage" - elseif cdir == "usage" then - dir = "recipe" - end - else - -- Default: use active search direction by default - dir = unified_inventory.active_search_direction[player_name] - end - - local button_name = "item_button_" .. dir .. "_" - .. unified_inventory.mangle_for_formspec(name) - formspec[n] = ("item_image_button[%f,%f;.81,.81;%s;%s;]"):format( - 8.2 + x * 0.7, ui_peruser.formspec_y + ui_peruser.page_y + y * 0.7, - name, button_name - ) - formspec[n + 1] = ("tooltip[%s;%s \\[%s\\]]"):format( - button_name, minetest.formspec_escape(item.description), - item.mod_origin or "??" - ) - n = n + 2 - list_index = list_index + 1 - end - end - end - formspec[n] = "label[8.2,"..ui_peruser.form_header_y..";"..F(S("Page")) .. ": " - .. S("@1 of @2",page2,pagemax).."]" - end - n= n+1 - - if unified_inventory.activefilter[player_name] ~= "" then - formspec[n] = "label[8.2,"..(ui_peruser.form_header_y + 0.4)..";" .. F(S("Filter")) .. ":]" - formspec[n+1] = "label[9.1,"..(ui_peruser.form_header_y + 0.4)..";"..F(unified_inventory.activefilter[player_name]).."]" - end - return table.concat(formspec, "") + return table.concat(fs) end -function unified_inventory.set_inventory_formspec(player, page) +function ui.set_inventory_formspec(player, page) if player then - player:set_inventory_formspec(unified_inventory.get_formspec(player, page)) + player:set_inventory_formspec(ui.get_formspec(player, page)) end end +local function valid_def(def) + return (not def.groups.not_in_creative_inventory + or def.groups.not_in_creative_inventory == 0) + and def.description + and def.description ~= "" +end + --apply filter to the inventory list (create filtered copy of full one) -function unified_inventory.apply_filter(player, filter, search_dir) +function ui.apply_filter(player, filter, search_dir) if not player then return false end @@ -290,7 +332,9 @@ function unified_inventory.apply_filter(player, filter, search_dir) return true end else - local lang = minetest.get_player_information(player_name).lang_code + local player_info = minetest.get_player_information(player_name) + local lang = player_info and player_info.lang_code or "" + ffilter = function(name, def) local lname = string.lower(name) local ldesc = string.lower(def.description) @@ -300,78 +344,37 @@ function unified_inventory.apply_filter(player, filter, search_dir) or llocaldesc and string.find(llocaldesc, lfilter, 1, true) end end - unified_inventory.filtered_items_list[player_name]={} - for name, def in pairs(minetest.registered_items) do - if (not def.groups.not_in_creative_inventory - or def.groups.not_in_creative_inventory == 0) - and def.description - and def.description ~= "" - and ffilter(name, def) then - table.insert(unified_inventory.filtered_items_list[player_name], name) + ui.filtered_items_list[player_name]={} + local category = ui.current_category[player_name] or 'all' + if category == 'all' then + for name, def in pairs(minetest.registered_items) do + if valid_def(def) + and ffilter(name, def) then + table.insert(ui.filtered_items_list[player_name], name) + end end - end - table.sort(unified_inventory.filtered_items_list[player_name]) - unified_inventory.filtered_items_list_size[player_name] = #unified_inventory.filtered_items_list[player_name] - unified_inventory.current_index[player_name] = 1 - unified_inventory.activefilter[player_name] = filter - unified_inventory.active_search_direction[player_name] = search_dir - unified_inventory.set_inventory_formspec(player, - unified_inventory.current_page[player_name]) -end - -function unified_inventory.items_in_group(groups) - local items = {} - for name, item in pairs(minetest.registered_items) do - for _, group in pairs(groups:split(',')) do - if item.groups[group] then - table.insert(items, name) + elseif category == 'uncategorized' then + for name, def in pairs(minetest.registered_items) do + if (not ui.find_category(name)) + and valid_def(def) + and ffilter(name, def) then + table.insert(ui.filtered_items_list[player_name], name) + end + end + else + for name,exists in pairs(ui.registered_category_items[category]) do + local def = minetest.registered_items[name] + if exists and def + and valid_def(def) + and ffilter(name, def) then + table.insert(ui.filtered_items_list[player_name], name) end end end - return items -end - -function unified_inventory.sort_inventory(inv) - 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) + table.sort(ui.filtered_items_list[player_name]) + ui.filtered_items_list_size[player_name] = #ui.filtered_items_list[player_name] + ui.current_index[player_name] = 1 + ui.activefilter[player_name] = filter + ui.active_search_direction[player_name] = search_dir + ui.set_inventory_formspec(player, ui.current_page[player_name]) end diff --git a/unified_inventory/locale/unified_inventory.template.tr b/unified_inventory/locale/template.txt similarity index 73% rename from unified_inventory/locale/unified_inventory.template.tr rename to unified_inventory/locale/template.txt index 2ea4fca..fd931d8 100644 --- a/unified_inventory/locale/unified_inventory.template.tr +++ b/unified_inventory/locale/template.txt @@ -1,54 +1,52 @@ # textdomain: unified_inventory - -# waypoints.lua - -White= -Yellow= -Red= -Green= -Blue= -Waypoints= -Select Waypoint #@1= -Waypoint @1= -Set waypoint to current location= -Make waypoint @1= -invisible= -visible= -@1 display of waypoint coordinates= -Disable= -Enable= -Change color of waypoint display= -Edit waypoint name= -Waypoint active= -Waypoint inactive= -Finish editing= -World position= -Name= -HUD text color= - -# group.lua - +Mixing= +Cooking= +Digging= +Bags= +Bag @1= +Small Bag= +Medium Bag= +Large Bag= +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = - -# register.lua - +Scroll categories left= +Scroll categories right= +Search= +Reset search and display everything= +First page= +Back three pages= +Back one page= +Forward one page= +Forward three pages= +Last page= +No matching items= +No matches.= +Page= +@1 of @2= +Filter= Can use the creative inventory= Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Crafting Grid= Crafting Guide= Set home position= Home position set to: @1= -You don't have the \"home\" privilege!= +You don't have the "home" privilege!= Go home= Set time to day= -Set time to night= Time of day set to 6am= -Time of day set to 9pm= You don't have the settime privilege!= +Set time to night= +Time of day set to 9pm= Clear inventory= +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!= -This button has been disabled outside= -Crafting= Trash:= Refill:= Any item belonging to the @1 group= @@ -65,36 +63,28 @@ Show previous recipe= Show previous usage= @1 (@2)= Give me:= -This recipe is too@nlarge to be displayed.= +This recipe is too@@large to be displayed.= To craft grid:= All= - -# api.lua - -Mixing= -Cooking= -Digging= - -# internal.lua - -First page= -Back three pages= -Back one page= -Forward one page= -Forward three pages= -Last page= -Search= -Reset search and display everything= -No matching items= -No matches.= -Page= -@1 of @2= -Filter= - -# bags.lua - -Bags= -Bag @1= -Small Bag= -Medium Bag= -Large Bag= +Crafting= +White= +Yellow= +Red= +Green= +Blue= +Waypoints= +Select Waypoint #@1= +Waypoint @1= +Set waypoint to current location= +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= +Change color of waypoint display= +Edit waypoint name= +Waypoint active= +Waypoint inactive= +Finish editing= +World position= +Name= +HUD text color= diff --git a/unified_inventory/locale/unified_inventory.de.tr b/unified_inventory/locale/unified_inventory.de.tr index e2a05be..474049c 100644 --- a/unified_inventory/locale/unified_inventory.de.tr +++ b/unified_inventory/locale/unified_inventory.de.tr @@ -1,5 +1,4 @@ # textdomain: unified_inventory -Crafting=Fertigung Mixing=Mischen Cooking=Kochen Digging=Graben @@ -8,21 +7,32 @@ Bag @1=Tasche @1 Small Bag=Kleine Tasche Medium Bag=Mittelgroße Tasche Large Bag=Große Tasche +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = und +Scroll categories left= +Scroll categories right= +Search=Suchen +Reset search and display everything=Suche zurücksetzen und alles anzeigen First page=Erste Seite Back three pages=3 Seiten zurückblättern Back one page=1 Seite zurückblättern Forward one page=1 Seite vorblättern Forward three pages=3 Seiten vorblättern Last page=Letzte Seite -Search=Suchen -Reset search and display everything=Suche zurücksetzen und alles anzeigen No matching items=Keine passenden Gegenstände No matches.=Keine Treffer Page=Seite @1 of @2=@1 von @2 Filter=Filter Can use the creative inventory=Kann das Kreativinventar nutzen +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Zwingt Unified Inventory, im Vollmodus angezeigt zu werden, wenn der Minimalmodus global eingestellt ist Crafting Grid=Fertigungsraster Crafting Guide=Fertigungsführer Set home position=Heimatposition setzen @@ -35,6 +45,7 @@ You don't have the settime privilege!=Du hast das „settime“-Privileg nicht! Set time to night=Zur Nachtzeit wechseln Time of day set to 9pm=Tageszeit auf 21 Uhr gesetzt Clear inventory=Inventar leeren +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=Inventar geleert! Trash:=Müll: Refill:=Nachfüllen: @@ -50,9 +61,12 @@ Show next recipe=Nächstes Rezept zeigen Show next usage=Nächste Verwendung zeigen Show previous recipe=Vorheriges Rezept zeigen Show previous usage=Vorherige Verwendung zeigen +@1 (@2)= Give me:=Gib mir: +This recipe is too@@large to be displayed.= To craft grid:=Ins Fertigungsraster: All=Alles +Crafting=Fertigung White=Weiß Yellow=Gelb Red=Rot @@ -62,12 +76,10 @@ Waypoints=Wegpunkte Select Waypoint #@1=Wegpunkt Nr. @1 auswählen Waypoint @1=Wegpunkt Nr. @1 Set waypoint to current location=Setze Wegpunkt zur derzeitigen Position -invisible=unsichtbar -visible=sichtbar -Make waypoint @1=Wegpunkt @1 machen -Disable=ausschalten -Enable=einschalten -@1 display of waypoint coordinates=Anzeige der Wegpunktkoordinaten @1 +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=Farbe der Darstellung der Wegpunkte ändern Edit waypoint name=Name des Wegpunkts ändern Waypoint active=Wegpunkt aktiv @@ -76,4 +88,13 @@ Finish editing=Bearbeitung abschließen World position=Weltposition Name=Name HUD text color=HUD-Textfarbe -Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Zwingt Unified Inventory, im Vollmodus angezeigt zu werden, wenn der Minimalmodus global eingestellt ist + + +##### not used anymore ##### + +invisible=unsichtbar +visible=sichtbar +Make waypoint @1=Wegpunkt @1 machen +Disable=ausschalten +Enable=einschalten +@1 display of waypoint coordinates=Anzeige der Wegpunktkoordinaten @1 diff --git a/unified_inventory/locale/unified_inventory.es.tr b/unified_inventory/locale/unified_inventory.es.tr index 18b6c77..85a794e 100644 --- a/unified_inventory/locale/unified_inventory.es.tr +++ b/unified_inventory/locale/unified_inventory.es.tr @@ -1,54 +1,57 @@ # textdomain: unified_inventory - -# waypoints.lua - -White=Blanco -Yellow=Amarillo -Red=Rojo -Green=Verde -Blue=Azul -Waypoints=Puntos -Select Waypoint #@1=Seleccionar Punto #@1 -Waypoint @1=Punto @1 -Set waypoint to current location=Establecer el punto a la ubicación actual -Make waypoint @1=Hacer punto @1 -invisible=invisible -visible=visible -@1 display of waypoint coordinates=Visualizar coordenadas del punto @1 -Disable=Deshabilitado -Enable=Habilitado -Change color of waypoint display=Cambiar el color del punto -Edit waypoint name=Editar nombre del punto -Waypoint active=Punto activo -Waypoint inactive=Punto inactivo -Finish editing=Terminar edición -World position=Posición en el mundo -Name=Nombre -HUD text color=Color del texto de la Interfaz - +# api.lua +Mixing=Mezclar +Cooking=Hornear +Digging=Recoger +# bags.lua +Bags=Bolsos +Bag @1=Bolso @1 +Small Bag=Bolso Pequeño +Medium Bag=Bolso Mediano +Large Bag=Bolso Grande +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= # group.lua - and = y - +Scroll categories left= +Scroll categories right= +Search=Buscar +Reset search and display everything=Limpiar la busqueda y mostrar todo +# internal.lua +First page=Primera página +Back three pages=Volver tres páginas +Back one page=Volver una página +Forward one page=Avanzar una página +Forward three pages=Avanzar tres páginas +Last page=Ultima Pagina +No matching items=No se encontraron elementos +No matches.=No hay resultados. +Page=Página +@1 of @2=@1 de @2 +Filter=Filtro # register.lua - Can use the creative inventory=Puede usar el inventario creativo Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Obliga al Inventario Unificado a mostrarse en modo Completo si el modo Simple está configurado globalmente Crafting Grid=Cuadricula de Elaboración Crafting Guide=Guía de Elaboración Set home position=Establecer posición de la casa Home position set to: @1=Posición de la casa cambiada a: @1 -You don't have the \"home\" privilege!=¡No tienes el privilegio \"home\"! +You don't have the "home" privilege!= Go home=Ir a casa Set time to day=Cambiar a dia -Set time to night=Cambiar a noche Time of day set to 6am=Hora del día cambiada a 6 AM -Time of day set to 9pm=Hora del día cambiada a 9 PM You don't have the settime privilege!=¡No tienes el privilegio "settime"! +Set time to night=Cambiar a noche +Time of day set to 9pm=Hora del día cambiada a 9 PM Clear inventory=Limpiar inventario +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=¡Inventario limpio! -This button has been disabled outside=Este botón ha sido deshabilitado -Crafting=Elaboración Trash:=Basura: Refill:=Rellenar: Any item belonging to the @1 group=Cualquier elemento que pertenezca al grupo @1 @@ -65,36 +68,41 @@ Show previous recipe=Mostrar la receta anterior Show previous usage=Mostrar el uso anterior @1 (@2)=@1 (@2) Give me:=Dame: -This recipe is too@nlarge to be displayed.=Esta receta es demasiado@ngrande para ser mostrada. +This recipe is too@@large to be displayed.= To craft grid:=Construir: All=Todos +Crafting=Elaboración +White=Blanco +Yellow=Amarillo +Red=Rojo +Green=Verde +Blue=Azul +Waypoints=Puntos +Select Waypoint #@1=Seleccionar Punto #@1 +Waypoint @1=Punto @1 +Set waypoint to current location=Establecer el punto a la ubicación actual +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= +Change color of waypoint display=Cambiar el color del punto +Edit waypoint name=Editar nombre del punto +Waypoint active=Punto activo +Waypoint inactive=Punto inactivo +Finish editing=Terminar edición +World position=Posición en el mundo +Name=Nombre +HUD text color=Color del texto de la Interfaz -# api.lua -Mixing=Mezclar -Cooking=Hornear -Digging=Recoger +##### not used anymore ##### -# internal.lua - -First page=Primera página -Back three pages=Volver tres páginas -Back one page=Volver una página -Forward one page=Avanzar una página -Forward three pages=Avanzar tres páginas -Last page=Ultima Pagina -Search=Buscar -Reset search and display everything=Limpiar la busqueda y mostrar todo -No matching items=No se encontraron elementos -No matches.=No hay resultados. -Page=Página -@1 of @2=@1 de @2 -Filter=Filtro - -# bags.lua - -Bags=Bolsos -Bag @1=Bolso @1 -Small Bag=Bolso Pequeño -Medium Bag=Bolso Mediano -Large Bag=Bolso Grande +Make waypoint @1=Hacer punto @1 +invisible=invisible +visible=visible +@1 display of waypoint coordinates=Visualizar coordenadas del punto @1 +Disable=Deshabilitado +Enable=Habilitado +You don't have the \"home\" privilege!=¡No tienes el privilegio \"home\"! +This button has been disabled outside=Este botón ha sido deshabilitado +This recipe is too@nlarge to be displayed.=Esta receta es demasiado@ngrande para ser mostrada. diff --git a/unified_inventory/locale/unified_inventory.fr.tr b/unified_inventory/locale/unified_inventory.fr.tr index 5367ddb..96d8c3f 100644 --- a/unified_inventory/locale/unified_inventory.fr.tr +++ b/unified_inventory/locale/unified_inventory.fr.tr @@ -1,5 +1,5 @@ # textdomain: unified_inventory -Crafting=Création +Mixing= Cooking=Cuisson Digging=Creuser Bags=Sacs @@ -7,35 +7,66 @@ Bag @1=Sac @1 Small Bag=Petit sac Medium Bag=Sac moyen Large Bag=Grand sac +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = et +Scroll categories left= +Scroll categories right= +Search=Rechercher +Reset search and display everything= First page=1ère page Back three pages=3 pages en arrière Back one page=Page précédente Forward one page=Page suivante Forward three pages=3 pages en avant Last page=Dernière page -Search=Rechercher No matching items=Aucun élément correspondant No matches.=Aucun match Page=Page @1 of @2=@1 de @2 Filter=Filtre Can use the creative inventory=Vous pouvez utiliser l'inventaire créatif +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Crafting Grid=Grille de création Crafting Guide=Guide de création Set home position=Position dans le monde Home position set to: @1=Position de votre base fixée à: @1 You don't have the "home" privilege!=Vous n'avez pas le privilège "home"! +Go home= +Set time to day= Time of day set to 6am=Heure fixée à 6h You don't have the settime privilege!=Vous n'avez pas le privilège "settime"! +Set time to night= Time of day set to 9pm=Heure fixée à 21h +Clear inventory= +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=Inventaire vidé ! Trash:=Poubelle : Refill:=Remplir : +Any item belonging to the @1 group= +Any item belonging to the groups @1= Recipe @1 of @2=Recette @1 de @2 +Usage @1 of @2= +No recipes= +No usages= Result=Résultat +Ingredient= +Show next recipe= +Show next usage= +Show previous recipe= +Show previous usage= +@1 (@2)= +Give me:= +This recipe is too@@large to be displayed.= To craft grid:=Sur de création: All=Tout +Crafting=Création White=Blanc Yellow=Jaune Red=Rouge @@ -45,8 +76,10 @@ Waypoints=Point de passage Select Waypoint #@1=Choisir un point de passage #@1 Waypoint @1=Point de passage @1 Set waypoint to current location=Marquer un point de passage à la position actuelle -Make waypoint @1=Rendre @1 le point de passage -@1 display of waypoint coordinates=@1 montrer les coordonnées des points de passages +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=Changer la couleur du point de passage Edit waypoint name=Editer le nom du point de passage Waypoint active=Point de passage actif @@ -55,3 +88,9 @@ Finish editing=Terminer l'édition World position=Position dans le monde Name=Nom HUD text color=Couleur de texte du HUD + + +##### not used anymore ##### + +Make waypoint @1=Rendre @1 le point de passage +@1 display of waypoint coordinates=@1 montrer les coordonnées des points de passages diff --git a/unified_inventory/locale/unified_inventory.it.tr b/unified_inventory/locale/unified_inventory.it.tr index 1bf7660..c30d9e0 100644 --- a/unified_inventory/locale/unified_inventory.it.tr +++ b/unified_inventory/locale/unified_inventory.it.tr @@ -1,5 +1,4 @@ # textdomain: unified_inventory -Crafting=Assemblaggio Mixing=Unione Cooking=Cottura Digging=Scavo @@ -8,21 +7,32 @@ Bag @1=Borsa @1 Small Bag=Borsa piccola Medium Bag=Borsa media Large Bag=Borsa grande +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = e +Scroll categories left= +Scroll categories right= +Search=Cerca +Reset search and display everything=Azzera la ricerca e mostra tutto First page=Prima pagina Back three pages=Indietro di tre pagine Back one page=Indietro di una pagina Forward one page=Avanti di una pagina Forward three pages=Avanti di tre pagine Last page=Ultima pagina -Search=Cerca -Reset search and display everything=Azzera la ricerca e mostra tutto No matching items=Nessun oggetto corrispondente No matches.=Nessuna corrispondenza. Page=Pagina @1 of @2=@1 di @2 Filter=Filtro Can use the creative inventory=Può usare l'inventario creativo +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Forza la visualizzazione di Unified Inventory in modalità completa se è configurata globalmente la visualizzazione semplice Crafting Grid=Griglia di assemblaggio Crafting Guide=Guida di assemblaggio Set home position=Imposta la residenza @@ -35,6 +45,7 @@ You don't have the settime privilege!=Non hai il privilegio "time"! Set time to night=Imposta l'orario sulla notte Time of day set to 9pm=Orario impostato sulle 9am Clear inventory=Ripulisci l'inventario +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=Inventario ripulito! Trash:=Butta: Refill:=Riempi: @@ -50,9 +61,12 @@ Show next recipe=Mostra la prossima ricetta Show next usage=Mostra il prossimo utilizzo Show previous recipe=Mostra la ricetta precedente Show previous usage=Mostra l'utilizzo precedente +@1 (@2)= Give me:=Dammi: +This recipe is too@@large to be displayed.= To craft grid:=Alla griglia di assemblaggio: All=Tutto +Crafting=Assemblaggio White=Bianco Yellow=Giallo Red=Rosso @@ -62,12 +76,10 @@ Waypoints=Tappe Select Waypoint #@1=Seleziona tappa n°@1 Waypoint @1=Tappa @1 Set waypoint to current location=Imposta tappa alla posizione attuale -invisible=invisibile -visible=visibile -Make waypoint @1=Crea tappa @1 -Disable=Disabilita -Enable=Abilita -@1 display of waypoint coordinates=@1 la visualizzazione delle coordinate della tappa +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=Modifica il colore della visualizzazione della tappa Edit waypoint name=Modifica il nome della tappa Waypoint active=Tappa attiva @@ -76,4 +88,13 @@ Finish editing=Termina la modifica World position=Posizione del mondo Name=Nome HUD text color=Colore del testo del visore -Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally=Forza la visualizzazione di Unified Inventory in modalità completa se è configurata globalmente la visualizzazione semplice + + +##### not used anymore ##### + +invisible=invisibile +visible=visibile +Make waypoint @1=Crea tappa @1 +Disable=Disabilita +Enable=Abilita +@1 display of waypoint coordinates=@1 la visualizzazione delle coordinate della tappa diff --git a/unified_inventory/locale/unified_inventory.ms.tr b/unified_inventory/locale/unified_inventory.ms.tr index 25fc853..be4eb5e 100644 --- a/unified_inventory/locale/unified_inventory.ms.tr +++ b/unified_inventory/locale/unified_inventory.ms.tr @@ -1,5 +1,4 @@ # textdomain: unified_inventory -Crafting=Pertukangan Mixing=Pencampuran Cooking=Pemasakan Digging=Penggalian @@ -8,21 +7,32 @@ Bag @1=Beg @1 Small Bag=Beg Kecil Medium Bag=Beg Sederhana Large Bag=Beg Besar +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = dan +Scroll categories left= +Scroll categories right= +Search=Cari +Reset search and display everything=Set semula carian dan tunjukkan semua benda First page=Halaman pertama Back three pages=Tiga halaman sebelumnya Back one page=Halaman sebelumnya Forward one page=Halaman seterusnya Forward three pages=Tiga halaman seterusnya Last page=Halaman terakhir -Search=Cari -Reset search and display everything=Set semula carian dan tunjukkan semua benda No matching items=Tiada item sepadan No matches.=Tiada padanan. Page=Halaman @1 of @2=@1 drpd @2 Filter=Tapis Can use the creative inventory=Boleh guna inventori kreatif +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Crafting Grid=Grid Pertukangan Crafting Guide=Panduan Pertukangan Set home position=Tetapkan kedudukan rumah @@ -35,6 +45,7 @@ You don't have the settime privilege!=Anda tidak ada keistimewaan settime! Set time to night=Tetapkan masa jadi malam Time of day set to 9pm=Masa ditetapkan ke 9 malam Clear inventory=Kosongkan inventori +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=Inventori dikosongkan! Trash:=Buang: Refill:=Isi balik: @@ -52,7 +63,10 @@ Show previous recipe=Tunjuk resipi sebelumnya Show previous usage=Tunjuk kegunaan sebelumnya @1 (@2)=@1 (@2) Give me:=Beri saya: +This recipe is too@@large to be displayed.= To craft grid:=Ke grid pertukangan: +All= +Crafting=Pertukangan White=Putih Yellow=Kuning Red=Merah @@ -62,12 +76,10 @@ Waypoints=Titik Arah Select Waypoint #@1=Pilih Titik Arah #@1 Waypoint @1=Titik Arah @1 Set waypoint to current location=Tetapkan titik arah ke lokasi semasa -invisible=Sembunyikan -visible=Paparkan -Make waypoint @1=@1 titik arah -Disable=Sembunyikan -Enable=Paparkan -@1 display of waypoint coordinates=@1 koordinat untuk titik arah +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=Tukar warna paparan titik arah Edit waypoint name=Edit nama titik arah Waypoint active=Titik arah aktif @@ -76,3 +88,13 @@ Finish editing=Selesai edit World position=Kedudukan dunia Name=Nama HUD text color=Warna tulisan HUD + + +##### not used anymore ##### + +invisible=Sembunyikan +visible=Paparkan +Make waypoint @1=@1 titik arah +Disable=Sembunyikan +Enable=Paparkan +@1 display of waypoint coordinates=@1 koordinat untuk titik arah diff --git a/unified_inventory/locale/unified_inventory.pl.tr b/unified_inventory/locale/unified_inventory.pl.tr index 19121d8..69d39e3 100644 --- a/unified_inventory/locale/unified_inventory.pl.tr +++ b/unified_inventory/locale/unified_inventory.pl.tr @@ -1,22 +1,40 @@ # textdomain: unified_inventory +Mixing= +Cooking= +Digging= Bags=Plecaki Bag @1=Plecak @1 Small Bag=Maly plecak Medium Bag=Sredni plecak Large Bag=Duzy plecak +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = i +Scroll categories left= +Scroll categories right= +Search=Szukaj +Reset search and display everything= First page=Pierwsza strona Back three pages=3 strony w tyl Back one page=1 strona w tyl Forward one page=1 strona do przodu Forward three pages=3 strony do przodu Last page=Ostatnia strona -Search=Szukaj No matching items=Brak pasujacych przedmiotow No matches.=Brak wyników Page=Strona @1 of @2=@1 z @2 Filter=Filtr +Can use the creative inventory= +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= +Crafting Grid= +Crafting Guide= Set home position=Ustaw pozycję wyjściową Home position set to: @1=Pozycja domowa ustawiona na: @1 You don't have the "home" privilege!=Nie masz uprawnien do zmiany czasu "home"! @@ -27,17 +45,28 @@ You don't have the settime privilege!=Nie masz uprawnien do zmiany czasu "settim Set time to night=Ustaw czas na noc Time of day set to 9pm=Czas ustawiony na 21:00 Clear inventory=Wyczyść zapasy +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=Zapasy zostały wyczyszczone! Trash:=Smietnik: Refill:=Uzupelnianie: +Any item belonging to the @1 group= +Any item belonging to the groups @1= Recipe @1 of @2=Recepta @1 z @2 Usage @1 of @2=Użycie @1 z @2 No recipes=Brak recepty No usages=Bez użycia Result=Wynik Ingredient=Składnik +Show next recipe= +Show next usage= +Show previous recipe= +Show previous usage= +@1 (@2)= Give me:=Daj mi: +This recipe is too@@large to be displayed.= +To craft grid:= All=Wszystko +Crafting= White=Bialy Yellow=Zolty Red=Czerwony @@ -47,10 +76,10 @@ Waypoints=Punkty orientacyjne Select Waypoint #@1=Wybierz punkt #@1 Waypoint @1=Punkty orientacyjne @1 Set waypoint to current location=Ustaw punkt orientacyjny na biezacej pozycji -invisible=niewidzialny -visible=widomy -Make waypoint @1=Robić punkt @1 -@1 display of waypoint coordinates=@1 koordynatow punktu +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=Zmien kolor punktu Edit waypoint name=Edytuj nazwe punktu Waypoint active=Punkt wlaczony @@ -59,3 +88,11 @@ Finish editing=Zakoncz edycje World position=Pozycja Name=Nazwa HUD text color=Kolor tekstu HUD + + +##### not used anymore ##### + +invisible=niewidzialny +visible=widomy +Make waypoint @1=Robić punkt @1 +@1 display of waypoint coordinates=@1 koordynatow punktu diff --git a/unified_inventory/locale/unified_inventory.pt.tr b/unified_inventory/locale/unified_inventory.pt.tr index 3b0b902..5fedbc0 100644 --- a/unified_inventory/locale/unified_inventory.pt.tr +++ b/unified_inventory/locale/unified_inventory.pt.tr @@ -1,5 +1,4 @@ # textdomain: unified_inventory -Crafting=Artesanato Mixing=Muistura Cooking=Cozimento Digging=Escavação @@ -8,21 +7,32 @@ Bag @1=Bolsa @1 Small Bag=Bolsa Pequena Medium Bag=Bolsa Média Large Bag=Bolsa Grande +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = e +Scroll categories left= +Scroll categories right= +Search=Pesquisar +Reset search and display everything=Redefinir pesquisa e exibir tudo First page=Primeira Página Back three pages=Voltar 3 Páginas Back one page=Voltar 1 Página Forward one page=Avançar 1 Página Forward three pages=Avançar 3 Páginas Last page=Ultima Página -Search=Pesquisar -Reset search and display everything=Redefinir pesquisa e exibir tudo No matching items=Nenhum item correspondente No matches.=Sem correspondências Page=Página @1 of @2=@1 de @2 Filter=Filtro Can use the creative inventory=Pode usar o inventário do criativo +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Crafting Grid=Grade de Artesanato Crafting Guide=Guia de Artesanato Set home position=Definir posição de casa @@ -35,6 +45,7 @@ You don't have the settime privilege!=Você não tem o privilégio de "settime"! Set time to night=Definir turno para noite Time of day set to 9pm=Hora do dia ajustada para 21h Clear inventory=Limpar Inventário +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=Inventário Apagado! Trash:=Lixo: Refill:=Recarga: @@ -50,9 +61,12 @@ Show next recipe=Exibir Próxima Receita Show next usage=Mostrar Próxima Utilização Show previous recipe=Exibir Receita Anterior Show previous usage=Exibir Utilização Anterior +@1 (@2)= Give me:=Gerado: +This recipe is too@@large to be displayed.= To craft grid:=Para Grade de Artesanato All=MAX +Crafting=Artesanato White=Branco Yellow=Amarelo Red=Vermelho @@ -62,10 +76,10 @@ Waypoints=Apontador de Direção Select Waypoint #@1=Seleção de Apontador de Direção #@1 Waypoint @1=Apontador de Direção @1 Set waypoint to current location=Configurar localização atual do Apontador de Direção -invisible=invisível -visible=visível -Make waypoint @1=Fazer Apontador de Direção @1 -@1 display of waypoint coordinates=@1 exibição de coordenadas de Fazer Apontador de Direção +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=Mudar cor exibida do Apontador de Direção Edit waypoint name=Editar Nome de Apontador de Direção Waypoint active=Apontador de Direção Ativo @@ -74,3 +88,11 @@ Finish editing=Edição Finalizada World position=Posição Mundial Name=Nome HUD text color=Cor de HUD + + +##### not used anymore ##### + +invisible=invisível +visible=visível +Make waypoint @1=Fazer Apontador de Direção @1 +@1 display of waypoint coordinates=@1 exibição de coordenadas de Fazer Apontador de Direção diff --git a/unified_inventory/locale/unified_inventory.ru.tr b/unified_inventory/locale/unified_inventory.ru.tr index f2a2300..2e3489c 100644 --- a/unified_inventory/locale/unified_inventory.ru.tr +++ b/unified_inventory/locale/unified_inventory.ru.tr @@ -1,5 +1,4 @@ # textdomain: unified_inventory -Crafting=Крафт Mixing=Мешать Cooking=Варить Digging=Копать @@ -8,21 +7,32 @@ Bag @1=Сумка @1 Small Bag=Малая сумка Medium Bag=Средняя сумка Large Bag=Большая сумка +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = и +Scroll categories left= +Scroll categories right= +Search=Поиск +Reset search and display everything=Сброс поиска, показать всё First page=Первая страница Back three pages=3 страницы назад Back one page=1 страницу назад Forward one page=1 страницу вперёд Forward three pages=3 страницы вперёд Last page=Последняя страница -Search=Поиск -Reset search and display everything=Сброс поиска, показать всё No matching items=Нет подходящих элементов No matches.=Ничего не найдено Page=Страница @1 of @2=@1 из @2 Filter=Фильтр Can use the creative inventory=Можно использовать инвентарь творческого режима +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Crafting Grid=Решетка крафта Crafting Guide=Книга рецептов Set home position=Установить позицию дома @@ -35,6 +45,7 @@ You don't have the settime privilege!=Вам не разрешено устан Set time to night=Ночь Time of day set to 9pm=Установлено время 9 вечера Clear inventory=Очистить инвентарь +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=Инвентарь очищен! Trash:=Мусор: Refill:=Наполнить: @@ -50,9 +61,12 @@ Show next recipe=Следующий рецепт Show next usage=Следующее использование Show previous recipe=Прошлый рецепт Show previous usage=Прошлая страница +@1 (@2)= Give me:=Дай мне: +This recipe is too@@large to be displayed.= To craft grid:=На решeтку крафта: All=Все +Crafting=Крафт White=Белый Yellow=Желтый Red=Красный @@ -62,12 +76,10 @@ Waypoints=Путевые точки Select Waypoint #@1=Выбрать путевую точку №@1 Waypoint @1=Путевая точка @1 Set waypoint to current location=Установить путевую точку по текущей позиции -invisible=невидимой -visible=видимой -Make waypoint @1=Сделать путевую точку @1 -Disable=Выключить -Enable=Включить -@1 display of waypoint coordinates=@1 показ координат путевых точек +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=Поменять цвет путевой точки Edit waypoint name=Переименовать путевую точку Waypoint active=Путевая точка включена @@ -76,3 +88,13 @@ Finish editing=Закончить редакцию World position=Позиция мира Name=Имя HUD text color=Цвет текста HUDа + + +##### not used anymore ##### + +invisible=невидимой +visible=видимой +Make waypoint @1=Сделать путевую точку @1 +Disable=Выключить +Enable=Включить +@1 display of waypoint coordinates=@1 показ координат путевых точек diff --git a/unified_inventory/locale/unified_inventory.tr.tr b/unified_inventory/locale/unified_inventory.tr.tr index 93246cc..b4e15b8 100644 --- a/unified_inventory/locale/unified_inventory.tr.tr +++ b/unified_inventory/locale/unified_inventory.tr.tr @@ -1,5 +1,4 @@ # textdomain: unified_inventory -Crafting=Üretim Mixing=Karıştırma Cooking=Pişirme Digging=Kazma @@ -8,20 +7,32 @@ Bag @1=@1. Çanta Small Bag=Küçük Çanta Medium Bag=Çanta Large Bag=Büyük Çanta +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = ve +Scroll categories left= +Scroll categories right= +Search=Ara +Reset search and display everything= First page=İlk Sayfa Back three pages=3 Sayfa Gerile Back one page=Geri Forward one page=İleri Forward three pages=3 Sayfa İlerile Last page=Son Sayfa -Search=Ara No matching items=Eşleşme yok No matches.=Eşleşme yok Page=Sayfa @1 of @2=@1 dan @2 Filter=Süzgeç Can use the creative inventory=Yaratıcı envanteri kullanabilir +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Crafting Grid=Üretim tablosu Crafting Guide=Kılavuz Set home position=Set ev pozisyon @@ -33,19 +44,29 @@ Time of day set to 6am=Saat 06:00 olarak ayarlandı You don't have the settime privilege!="settime" yetkiniz yok! Set time to night=Geceye zaman ayarla Time of day set to 9pm=Saat 19:00 olarak ayarlandı -msgid ""=Yaratıcı modu dışında iken bu tuş kullanılamaz. +Clear inventory= +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= Inventory cleared!=Envanter temizlendi! Trash:=Çöp Refill:=Doldur +Any item belonging to the @1 group= +Any item belonging to the groups @1= Recipe @1 of @2=@1 dan @2 tarifi Usage @1 of @2=Kullanım @1/@2 No recipes=Tarifi yok No usages=Kullanım yok Result=Çıktı Ingredient=Bileşen +Show next recipe= +Show next usage= +Show previous recipe= +Show previous usage= +@1 (@2)= Give me:=Ver bana: +This recipe is too@@large to be displayed.= To craft grid:=Üretim tablosuna kopyala All=Tümü +Crafting=Üretim White=Beyaz Yellow=Sarı Red=Kırmızı @@ -55,10 +76,10 @@ Waypoints=Konum Noktaları Select Waypoint #@1=#@1 konum noktası seç Waypoint @1=@1 Konum Noktaları Set waypoint to current location=Bulunduğun noktayı işaretle -invisible=görünmez -visible=görünür -Make waypoint @1=Yol noktası @1 -@1 display of waypoint coordinates=Yol noktası koordinatlarının görüntülenmesini @1 +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=Konum Gösterge Rengi Edit waypoint name=Konum Noktasını Düzenle Waypoint active=Konum Etkin @@ -67,3 +88,12 @@ Finish editing=Düzenleme bitti World position=Dünya konumu Name=İsim HUD text color=Metin rengi + + +##### not used anymore ##### + +msgid ""=Yaratıcı modu dışında iken bu tuş kullanılamaz. +invisible=görünmez +visible=görünür +Make waypoint @1=Yol noktası @1 +@1 display of waypoint coordinates=Yol noktası koordinatlarının görüntülenmesini @1 diff --git a/unified_inventory/locale/unified_inventory.zh_CN.tr b/unified_inventory/locale/unified_inventory.zh_CN.tr index 30e15e3..595a492 100644 --- a/unified_inventory/locale/unified_inventory.zh_CN.tr +++ b/unified_inventory/locale/unified_inventory.zh_CN.tr @@ -1,8 +1,4 @@ # textdomain: unified_inventory -# traslation by: IFRFSX(BingFengFSX) -#Email: IFRFSX@Protonmail.com - -Crafting=合成 Mixing=混合 Cooking=烹饪 Digging=挖出 @@ -11,20 +7,32 @@ Bag @1=背包@1 Small Bag=小背包 Medium Bag=中背包 Large Bag=大背包 +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = 和 +Scroll categories left= +Scroll categories right= +Search=搜索 +Reset search and display everything=重置搜索并显示所有物品 First page=第一页 Back three pages=后退三页 Back one page=后退一页 Forward one page=前进一页 Forward three pages=前进三页 Last page=最后一页 -Search=搜索 No matching items=没有匹配物品 No matches.=没有匹配 Page=页面 @1 of @2=第@1页,共@2页 Filter=过滤器 Can use the creative inventory=可以使用创造背包 +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Crafting Grid=合成表 Crafting Guide=合成指南 Set home position=设置家的位置 @@ -36,21 +44,29 @@ Time of day set to 6am=时间设置到早晨6点 You don't have the settime privilege!=你没有“settime”权限! Set time to night=设置时间到晚上 Time of day set to 9pm=时间设置到晚上9点 - -Inventory cleared!=清空背包 Clear inventory=清空背包 - +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= +Inventory cleared!=清空背包 Trash:=丢弃: Refill:=填满: +Any item belonging to the @1 group=属于@1组的任何项目 +Any item belonging to the groups @1=属于组@1的任何项目 Recipe @1 of @2=第@1配方,共@2个 Usage @1 of @2=第@1用法,共@2个 No recipes=没有配方 No usages=没有用法 Result=结果 Ingredient=原料 +Show next recipe= +Show next usage= +Show previous recipe= +Show previous usage= +@1 (@2)= Give me:=给予: +This recipe is too@@large to be displayed.= To craft grid:=填充物品到合成表 All=全部 +Crafting=合成 White=白 Yellow=黄 Red=红 @@ -60,10 +76,10 @@ Waypoints=航路点 Select Waypoint #@1=查询航路点 #@1 Waypoint @1=航路点 @1 Set waypoint to current location=将航路点设置到当前位置 -invisible=不可见的 -visible=可见的 -Make waypoint @1=设置航路点 @1 -@1 display of waypoint coordinates=显示航路点@1坐标 +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=改变航路点显示的颜色 Edit waypoint name=编辑航路点名称 Waypoint active=航路点已激活 @@ -73,7 +89,10 @@ World position=世界位置 Name=名称 HUD text color=HUD文本颜色 -Reset search and display everything=重置搜索并显示所有物品 -Any item belonging to the @1 group=属于@1组的任何项目 -Any item belonging to the groups @1=属于组@1的任何项目 +##### not used anymore ##### + +invisible=不可见的 +visible=可见的 +Make waypoint @1=设置航路点 @1 +@1 display of waypoint coordinates=显示航路点@1坐标 diff --git a/unified_inventory/locale/unified_inventory.zh_TW.tr b/unified_inventory/locale/unified_inventory.zh_TW.tr index 3e8d1a1..f41190c 100644 --- a/unified_inventory/locale/unified_inventory.zh_TW.tr +++ b/unified_inventory/locale/unified_inventory.zh_TW.tr @@ -1,8 +1,4 @@ # textdomain: unified_inventory -# traslation by: IFRFSX(BingFengFSX) -#Email: IFRFSX@Protonmail.com - -Crafting=合成 Mixing=混合 Cooking=烹飪 Digging=挖出 @@ -11,20 +7,32 @@ Bag @1=揹包@1 Small Bag=小揹包 Medium Bag=中揹包 Large Bag=大揹包 +All Items= +Misc. Items= +Plant Life= +Building Materials= +Tools= +Minerals and Metals= +Environment and Worldgen= +Lighting= and = 和 +Scroll categories left= +Scroll categories right= +Search=搜索 +Reset search and display everything=重置搜索並顯示所有物品 First page=第一頁 Back three pages=後退三頁 Back one page=後退一頁 Forward one page=前進一頁 Forward three pages=前進三頁 Last page=最後一頁 -Search=搜索 No matching items=沒有匹配物品 No matches.=沒有匹配 Page=頁面 @1 of @2=第@1頁,共@2頁 Filter=過濾器 Can use the creative inventory=可以使用創造揹包 +Forces Unified Inventory to be displayed in Full mode if Lite mode is configured globally= Crafting Grid=合成表 Crafting Guide=合成指南 Set home position=設置家的位置 @@ -36,21 +44,29 @@ Time of day set to 6am=時間設置到早晨6點 You don't have the settime privilege!=你沒有“settime”權限! Set time to night=設置時間到晚上 Time of day set to 9pm=時間設置到晚上9點 - -Inventory cleared!=清空揹包 Clear inventory=清空揹包 - +This button has been disabled outside of creative mode to prevent accidental inventory trashing.@nUse the trash slot instead.= +Inventory cleared!=清空揹包 Trash:=丟棄: Refill:=填滿: +Any item belonging to the @1 group=屬於@1組的任何項目 +Any item belonging to the groups @1=屬於組@1的任何項目 Recipe @1 of @2=第@1配方,共@2個 Usage @1 of @2=第@1用法,共@2個 No recipes=沒有配方 No usages=沒有用法 Result=結果 Ingredient=原料 +Show next recipe= +Show next usage= +Show previous recipe= +Show previous usage= +@1 (@2)= Give me:=給予: +This recipe is too@@large to be displayed.= To craft grid:=填充物品到合成表 All=全部 +Crafting=合成 White=白 Yellow=黃 Red=紅 @@ -60,10 +76,10 @@ Waypoints=航路點 Select Waypoint #@1=查詢航路點 #@1 Waypoint @1=航路點 @1 Set waypoint to current location=將航路點設置到當前位置 -invisible=不可見的 -visible=可見的 -Make waypoint @1=設置航路點 @1 -@1 display of waypoint coordinates=顯示航路點@1座標 +Hide waypoint= +Show waypoint= +Hide coordinates= +Show coordinates= Change color of waypoint display=改變航路點顯示的顏色 Edit waypoint name=編輯航路點名稱 Waypoint active=航路點已激活 @@ -73,7 +89,10 @@ World position=世界位置 Name=名稱 HUD text color=HUD文本顏色 -Reset search and display everything=重置搜索並顯示所有物品 -Any item belonging to the @1 group=屬於@1組的任何項目 -Any item belonging to the groups @1=屬於組@1的任何項目 +##### not used anymore ##### + +invisible=不可見的 +visible=可見的 +Make waypoint @1=設置航路點 @1 +@1 display of waypoint coordinates=顯示航路點@1座標 diff --git a/unified_inventory/mod.conf b/unified_inventory/mod.conf index bca70ca..3d27d29 100644 --- a/unified_inventory/mod.conf +++ b/unified_inventory/mod.conf @@ -1,7 +1,8 @@ name = unified_inventory -depends = default -optional_depends = creative, sfinv, datastorage, farming + +optional_depends = default, creative, sfinv, datastorage, farming description = """ Unified Inventory replaces the default survival and creative inventory. It adds a nicer interface and a number of features, such as a crafting guide. """ +min_minetest_version = 5.4.0 diff --git a/unified_inventory/register.lua b/unified_inventory/register.lua index cfc1d7d..8dc20f0 100644 --- a/unified_inventory/register.lua +++ b/unified_inventory/register.lua @@ -1,6 +1,7 @@ local S = minetest.get_translator("unified_inventory") local NS = function(s) return s end local F = minetest.formspec_escape +local ui = unified_inventory minetest.register_privilege("creative", { description = S("Can use the creative inventory"), @@ -12,10 +13,9 @@ minetest.register_privilege("ui_full", { give_to_singleplayer = false, }) - local trash = minetest.create_detached_inventory("trash", { --allow_put = function(inv, listname, index, stack, player) - -- if unified_inventory.is_creative(player:get_player_name()) then + -- if ui.is_creative(player:get_player_name()) then -- return stack:get_count() -- else -- return 0 @@ -29,19 +29,19 @@ local trash = minetest.create_detached_inventory("trash", { }) trash:set_size("main", 1) -unified_inventory.register_button("craft", { +ui.register_button("craft", { type = "image", image = "ui_craft_icon.png", tooltip = S("Crafting Grid") }) -unified_inventory.register_button("craftguide", { +ui.register_button("craftguide", { type = "image", image = "ui_craftguide_icon.png", tooltip = S("Crafting Guide") }) -unified_inventory.register_button("home_gui_set", { +ui.register_button("home_gui_set", { type = "image", image = "ui_sethome_icon.png", tooltip = S("Set home position"), @@ -49,8 +49,8 @@ unified_inventory.register_button("home_gui_set", { action = function(player) local player_name = player:get_player_name() if minetest.check_player_privs(player_name, {home=true}) then - unified_inventory.set_home(player, player:get_pos()) - local home = unified_inventory.home_pos[player_name] + ui.set_home(player, player:get_pos()) + local home = ui.home_pos[player_name] if home ~= nil then minetest.sound_play("dingdong", {to_player=player_name, gain = 1.0}) @@ -60,7 +60,7 @@ unified_inventory.register_button("home_gui_set", { else minetest.chat_send_player(player_name, S("You don't have the \"home\" privilege!")) - unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name]) + ui.set_inventory_formspec(player, ui.current_page[player_name]) end end, condition = function(player) @@ -68,7 +68,7 @@ unified_inventory.register_button("home_gui_set", { end, }) -unified_inventory.register_button("home_gui_go", { +ui.register_button("home_gui_go", { type = "image", image = "ui_gohome_icon.png", tooltip = S("Go home"), @@ -76,13 +76,13 @@ unified_inventory.register_button("home_gui_go", { action = function(player) local player_name = player:get_player_name() if minetest.check_player_privs(player_name, {home=true}) then - if unified_inventory.go_home(player) then + if ui.go_home(player) then minetest.sound_play("teleport", {to_player = player_name}) end else minetest.chat_send_player(player_name, S("You don't have the \"home\" privilege!")) - unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name]) + ui.set_inventory_formspec(player, ui.current_page[player_name]) end end, condition = function(player) @@ -90,7 +90,7 @@ unified_inventory.register_button("home_gui_go", { end, }) -unified_inventory.register_button("misc_set_day", { +ui.register_button("misc_set_day", { type = "image", image = "ui_sun_icon.png", tooltip = S("Set time to day"), @@ -106,7 +106,7 @@ unified_inventory.register_button("misc_set_day", { else minetest.chat_send_player(player_name, S("You don't have the settime privilege!")) - unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name]) + ui.set_inventory_formspec(player, ui.current_page[player_name]) end end, condition = function(player) @@ -114,7 +114,7 @@ unified_inventory.register_button("misc_set_day", { end, }) -unified_inventory.register_button("misc_set_night", { +ui.register_button("misc_set_night", { type = "image", image = "ui_moon_icon.png", tooltip = S("Set time to night"), @@ -130,7 +130,7 @@ unified_inventory.register_button("misc_set_night", { else minetest.chat_send_player(player_name, S("You don't have the settime privilege!")) - unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name]) + ui.set_inventory_formspec(player, ui.current_page[player_name]) end end, condition = function(player) @@ -138,19 +138,19 @@ unified_inventory.register_button("misc_set_night", { end, }) -unified_inventory.register_button("clear_inv", { +ui.register_button("clear_inv", { type = "image", image = "ui_trash_icon.png", tooltip = S("Clear inventory"), action = function(player) local player_name = player:get_player_name() - if not unified_inventory.is_creative(player_name) then + if not ui.is_creative(player_name) then minetest.chat_send_player(player_name, S("This button has been disabled outside" .." of creative mode to prevent" .." accidental inventory trashing." .."\nUse the trash slot instead.")) - unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name]) + ui.set_inventory_formspec(player, ui.current_page[player_name]) return end player:get_inventory():set_list("main", {}) @@ -159,35 +159,42 @@ unified_inventory.register_button("clear_inv", { {to_player=player_name, gain = 1.0}) end, condition = function(player) - return unified_inventory.is_creative(player:get_player_name()) + return ui.is_creative(player:get_player_name()) end, }) -unified_inventory.register_page("craft", { +ui.register_page("craft", { get_formspec = function(player, perplayer_formspec) - local formspecy = perplayer_formspec.formspec_y - local formheadery = perplayer_formspec.form_header_y + local formheaderx = perplayer_formspec.form_header_x + local formheadery = perplayer_formspec.form_header_y + local craftx = perplayer_formspec.craft_x + local crafty = perplayer_formspec.craft_y local player_name = player:get_player_name() - local formspec = "background[2,"..formspecy..";6,3;ui_crafting_form.png]" - formspec = formspec..string.gsub(unified_inventory.standard_inv_bg, "YYY", (formspecy + 3.4)) - formspec = formspec.."label[0,"..formheadery..";" ..F(S("Crafting")).."]" - formspec = formspec.."listcolors[#00000000;#00000000]" - formspec = formspec.."list[current_player;craftpreview;6,"..formspecy..";1,1;]" - formspec = formspec.."list[current_player;craft;2,"..formspecy..";3,3;]" - if unified_inventory.trash_enabled or unified_inventory.is_creative(player_name) or minetest.get_player_privs(player_name).give then - formspec = formspec.."label[7,"..(formspecy + 1.5)..";" .. F(S("Trash:")) .. "]" - formspec = formspec.."background[7,"..(formspecy + 2)..";1,1;ui_single_slot.png]" - formspec = formspec.."list[detached:trash;main;7,"..(formspecy + 2)..";1,1;]" + local formspec = { + perplayer_formspec.standard_inv_bg, + perplayer_formspec.craft_grid, + "label["..formheaderx..","..formheadery..";" ..F(S("Crafting")).."]", + "listcolors[#00000000;#00000000]", + "listring[current_name;craft]", + "listring[current_player;main]" + } + local n=#formspec+1 + + if ui.trash_enabled or ui.is_creative(player_name) or minetest.get_player_privs(player_name).give then + formspec[n] = string.format("label[%f,%f;%s]", craftx + 6.45, crafty + 2.4, F(S("Trash:"))) + formspec[n+1] = ui.make_trash_slot(craftx + 6.25, crafty + 2.5) + n=n + 2 end - formspec = formspec.."listring[current_name;craft]" - formspec = formspec.."listring[current_player;main]" - if unified_inventory.is_creative(player_name) then - formspec = formspec.."label[0,"..(formspecy + 1.5)..";" .. F(S("Refill:")) .. "]" - formspec = formspec.."list[detached:"..F(player_name).."refill;main;0,"..(formspecy +2)..";1,1;]" + + if ui.is_creative(player_name) then + formspec[n] = ui.single_slot(craftx - 2.5, crafty + 2.5) + formspec[n+1] = string.format("label[%f,%f;%s]", craftx - 2.3, crafty + 2.4,F(S("Refill:"))) + formspec[n+2] = string.format("list[detached:%srefill;main;%f,%f;1,1;]", + F(player_name), craftx - 2.5 + ui.list_img_offset, crafty + 2.5 + ui.list_img_offset) end - return {formspec=formspec} + return {formspec=table.concat(formspec)} end, }) @@ -201,23 +208,27 @@ unified_inventory.register_page("craft", { local function stack_image_button(x, y, w, h, buttonname_prefix, item) local name = item:get_name() local count = item:get_count() + local wear = item:get_wear() + local description = item:get_meta():get_string("description") local show_is_group = false - local displayitem = name.." "..count + local displayitem = name.." "..count.." "..wear local selectitem = name if name:sub(1, 6) == "group:" then local group_name = name:sub(7) - local group_item = unified_inventory.get_group_item(group_name) + local group_item = ui.get_group_item(group_name) show_is_group = not group_item.sole displayitem = group_item.item or "unknown" selectitem = group_item.sole and displayitem or name end local label = show_is_group and "G" or "" - local buttonname = F(buttonname_prefix..unified_inventory.mangle_for_formspec(selectitem)) + -- Unique id to prevent tooltip being overridden + local id = string.format("%i%i_", x*10, y*10) + local buttonname = F(id..buttonname_prefix..ui.mangle_for_formspec(selectitem)) local button = string.format("item_image_button[%f,%f;%f,%f;%s;%s;%s]", x, y, w, h, F(displayitem), buttonname, label) if show_is_group then - local groupstring, andcount = unified_inventory.extract_groupnames(name) + local groupstring, andcount = ui.extract_groupnames(name) local grouptip if andcount == 1 then grouptip = S("Any item belonging to the @1 group", groupstring) @@ -228,6 +239,8 @@ local function stack_image_button(x, y, w, h, buttonname_prefix, item) if andcount >= 1 then button = button .. string.format("tooltip[%s;%s]", buttonname, grouptip) end + elseif description ~= "" then + button = button .. string.format("tooltip[%s;%s]", buttonname, F(description)) end return button end @@ -257,26 +270,33 @@ local other_dir = { usage = "recipe", } -unified_inventory.register_page("craftguide", { +ui.register_page("craftguide", { get_formspec = function(player, perplayer_formspec) - local formspecy = perplayer_formspec.formspec_y - local formheadery = perplayer_formspec.form_header_y - local craftresultx = perplayer_formspec.craft_result_x - local craftresulty = perplayer_formspec.craft_result_y + local craftguidex = perplayer_formspec.craft_guide_x + local craftguidey = perplayer_formspec.craft_guide_y + local craftguidearrowx = perplayer_formspec.craft_guide_arrow_x + local craftguideresultx = perplayer_formspec.craft_guide_result_x + local formheaderx = perplayer_formspec.form_header_x + local formheadery = perplayer_formspec.form_header_y + local give_x = perplayer_formspec.give_btn_x local player_name = player:get_player_name() local player_privs = minetest.get_player_privs(player_name) - local fs = { - string.gsub(unified_inventory.standard_inv_bg, "YYY", (formspecy + 3.4)), - "label[0,"..formheadery..";" .. F(S("Crafting Guide")) .. "]", + + local formspec = { + perplayer_formspec.standard_inv_bg, + "label["..formheaderx..","..formheadery..";" .. F(S("Crafting Guide")) .. "]", "listcolors[#00000000;#00000000]" } - local item_name = unified_inventory.current_item[player_name] + + local item_name = ui.current_item[player_name] if not item_name then - return { formspec = table.concat(fs) } + return { formspec = table.concat(formspec) } end + local n = 4 + local item_name_shown if minetest.registered_items[item_name] and minetest.registered_items[item_name].description then @@ -286,51 +306,60 @@ unified_inventory.register_page("craftguide", { item_name_shown = item_name end - local dir = unified_inventory.current_craft_direction[player_name] + local dir = ui.current_craft_direction[player_name] local rdir = dir == "recipe" and "usage" or "recipe" - local crafts = unified_inventory.crafts_for[dir][item_name] - local alternate = unified_inventory.alternate[player_name] + local crafts = ui.crafts_for[dir][item_name] + local alternate = ui.alternate[player_name] local alternates, craft if crafts and #crafts > 0 then alternates = #crafts craft = crafts[alternate] end - local has_give = player_privs.give or unified_inventory.is_creative(player_name) + local has_give = player_privs.give or ui.is_creative(player_name) - fs[#fs + 1] = "background[0.5,"..(formspecy + 0.2)..";8,3;ui_craftguide_form.png]" - fs[#fs + 1] = string.format("textarea[%f,%f;10,1;;%s: %s;]", - craftresultx, craftresulty, F(role_text[dir]), item_name_shown) - fs[#fs + 1] = stack_image_button(0, formspecy, 1.1, 1.1, - "item_button_" .. rdir .. "_", ItemStack(item_name)) + formspec[n] = string.format("image[%f,%f;%f,%f;ui_crafting_arrow.png]", + craftguidearrowx, craftguidey, ui.imgscale, ui.imgscale) + + formspec[n+1] = string.format("textarea[%f,%f;10,1;;%s: %s;]", + perplayer_formspec.craft_guide_resultstr_x, perplayer_formspec.craft_guide_resultstr_y, + F(role_text[dir]), item_name_shown) + n = n + 2 + + local giveme_form = table.concat({ + "label[".. (give_x+0.1)..",".. (craftguidey + 2.7) .. ";" .. F(S("Give me:")) .. "]", + "button["..(give_x)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_1;1]", + "button["..(give_x+0.8)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_10;10]", + "button["..(give_x+1.6)..",".. (craftguidey + 2.9) .. ";0.75,0.5;craftguide_giveme_99;99]" + }) if not craft then -- No craft recipes available for this item. - fs[#fs + 1] = "label[5.5,"..(formspecy + 2.35)..";" - .. F(no_recipe_text[dir]) .. "]" - local no_pos = dir == "recipe" and 4.5 or 6.5 - local item_pos = dir == "recipe" and 6.5 or 4.5 - fs[#fs + 1] = "image["..no_pos..","..formspecy..";1.1,1.1;ui_no.png]" - fs[#fs + 1] = stack_image_button(item_pos, formspecy, 1.1, 1.1, + formspec[n] = string.format("label[%f,%f;%s]", craftguidex+2.5, craftguidey+1.5, F(no_recipe_text[dir])) + local no_pos = dir == "recipe" and (craftguidex+2.5) or craftguideresultx + local item_pos = dir == "recipe" and craftguideresultx or (craftguidex+2.5) + formspec[n+1] = "image["..no_pos..","..craftguidey..";1.2,1.2;ui_no.png]" + formspec[n+2] = stack_image_button(item_pos, craftguidey, 1.2, 1.2, "item_button_" .. other_dir[dir] .. "_", ItemStack(item_name)) if has_give then - fs[#fs + 1] = "label[0," .. (formspecy + 2.10) .. ";" .. F(S("Give me:")) .. "]" - .. "button[0, " .. (formspecy + 2.7) .. ";0.6,0.5;craftguide_giveme_1;1]" - .. "button[0.6," .. (formspecy + 2.7) .. ";0.7,0.5;craftguide_giveme_10;10]" - .. "button[1.3," .. (formspecy + 2.7) .. ";0.8,0.5;craftguide_giveme_99;99]" + formspec[n+3] = giveme_form end - return { formspec = table.concat(fs) } + return { formspec = table.concat(formspec) } + else + formspec[n] = stack_image_button(craftguideresultx, craftguidey, 1.2, 1.2, + "item_button_" .. rdir .. "_", ItemStack(craft.output)) + n = n + 1 end - local craft_type = unified_inventory.registered_craft_types[craft.type] or - unified_inventory.craft_type_defaults(craft.type, {}) + local craft_type = ui.registered_craft_types[craft.type] or + ui.craft_type_defaults(craft.type, {}) if craft_type.icon then - fs[#fs + 1] = string.format("image[%f,%f;%f,%f;%s]", - 5.7, (formspecy + 0.05), 0.5, 0.5, craft_type.icon) + formspec[n] = string.format("image[%f,%f;%f,%f;%s]", + craftguidearrowx+0.35, craftguidey, 0.5, 0.5, craft_type.icon) + n = n + 1 end - fs[#fs + 1] = "label[5.5,"..(formspecy + 1)..";" .. F(craft_type.description).."]" - fs[#fs + 1] = stack_image_button(6.5, formspecy, 1.1, 1.1, - "item_button_usage_", ItemStack(craft.output)) + formspec[n] = string.format("label[%f,%f;%s]", craftguidearrowx + 0.15, craftguidey + 1.4, F(craft_type.description)) + n = n + 1 local display_size = craft_type.dynamic_display_size and craft_type.dynamic_display_size(craft) @@ -341,11 +370,12 @@ unified_inventory.register_page("craftguide", { -- This keeps recipes aligned to the right, -- so that they're close to the arrow. - local xoffset = 5.5 + local xoffset = craftguidex+3.75 + local bspc = 1.25 -- Offset factor for crafting grids with side length > 4 local of = (3/math.max(3, math.max(display_size.width, display_size.height))) local od = 0 - -- Minimum grid size at which size optimazation measures kick in + -- Minimum grid size at which size optimization measures kick in local mini_craft_size = 6 if display_size.width >= mini_craft_size then od = math.max(1, display_size.width - 2) @@ -354,12 +384,12 @@ unified_inventory.register_page("craftguide", { -- Size modifier factor local sf = math.min(1, of * (1.05 + 0.05*od)) -- Button size - local bsize_h = 1.1 * sf - local bsize_w = bsize_h - if display_size.width >= mini_craft_size then - bsize_w = 1.175 * sf + local bsize = 1.2 * sf + + if display_size.width >= mini_craft_size then -- it's not a normal 3x3 grid + bsize = 0.8 * sf end - if (bsize_h > 0.35 and display_size.width) then + if (bsize > 0.35 and display_size.width) then for y = 1, display_size.height do for x = 1, display_size.width do local item @@ -369,48 +399,53 @@ unified_inventory.register_page("craftguide", { -- Flipped x, used to build formspec buttons from right to left local fx = display_size.width - (x-1) -- x offset, y offset - local xof = (fx-1) * of + of - local yof = (y-1) * of + 1 + local xof = ((fx-1) * of + of) * bspc + local yof = ((y-1) * of + 1) * bspc if item then - fs[#fs + 1] = stack_image_button( - xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h, + formspec[n] = stack_image_button( + xoffset - xof, craftguidey - 1.25 + yof, bsize, bsize, "item_button_recipe_", ItemStack(item)) else -- Fake buttons just to make grid - fs[#fs + 1] = string.format("image_button[%f,%f;%f,%f;ui_blank_image.png;;]", - xoffset - xof, formspecy - 1 + yof, bsize_w, bsize_h) + formspec[n] = string.format("image_button[%f,%f;%f,%f;ui_blank_image.png;;]", + xoffset - xof, craftguidey - 1.25 + yof, bsize, bsize) end + n = n + 1 end end else -- Error - fs[#fs + 1] = string.format("label[2,%f;%s]", - formspecy, F(S("This recipe is too@nlarge to be displayed."))) + formspec[n] = string.format("label[2,%f;%s]", + craftguidey, F(S("This recipe is too@nlarge to be displayed."))) + n = n + 1 end if craft_type.uses_crafting_grid and display_size.width <= 3 then - fs[#fs + 1] = "label[0," .. (formspecy + 0.9) .. ";" .. F(S("To craft grid:")) .. "]" - .. "button[0, " .. (formspecy + 1.5) .. ";0.6,0.5;craftguide_craft_1;1]" - .. "button[0.6," .. (formspecy + 1.5) .. ";0.7,0.5;craftguide_craft_10;10]" - .. "button[1.3," .. (formspecy + 1.5) .. ";0.8,0.5;craftguide_craft_max;" .. F(S("All")) .. "]" + formspec[n] = "label["..(give_x+0.1)..",".. (craftguidey + 1.7) .. ";" .. F(S("To craft grid:")) .. "]" + formspec[n+1] = "button[".. (give_x)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_1;1]" + formspec[n+2] = "button[".. (give_x+0.8)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_10;10]" + formspec[n+3] = "button[".. (give_x+1.6)..",".. (craftguidey + 1.9) .. ";0.75,0.5;craftguide_craft_max;" .. F(S("All")) .. "]" + n = n + 4 end + if has_give then - fs[#fs + 1] = "label[0," .. (formspecy + 2.1) .. ";" .. F(S("Give me:")) .. "]" - .. "button[0, " .. (formspecy + 2.7) .. ";0.6,0.5;craftguide_giveme_1;1]" - .. "button[0.6," .. (formspecy + 2.7) .. ";0.7,0.5;craftguide_giveme_10;10]" - .. "button[1.3," .. (formspecy + 2.7) .. ";0.8,0.5;craftguide_giveme_99;99]" + formspec[n] = giveme_form + n = n + 1 end if alternates and alternates > 1 then - fs[#fs + 1] = "label[5.5," .. (formspecy + 1.6) .. ";" - .. F(S(recipe_text[dir], alternate, alternates)) .. "]" - .. "image_button[5.5," .. (formspecy + 2) .. ";1,1;ui_left_icon.png;alternate_prev;]" - .. "image_button[6.5," .. (formspecy + 2) .. ";1,1;ui_right_icon.png;alternate;]" - .. "tooltip[alternate_prev;" .. F(prev_alt_text[dir]) .. "]" - .. "tooltip[alternate;" .. F(next_alt_text[dir]) .. "]" + formspec[n] = string.format("label[%f,%f;%s]", + craftguidex+4, craftguidey + 2.3, F(S(recipe_text[dir], alternate, alternates))) + formspec[n+1] = string.format("image_button[%f,%f;1.1,1.1;ui_left_icon.png;alternate_prev;]", + craftguidearrowx+0.2, craftguidey + 2.6) + formspec[n+2] = string.format("image_button[%f,%f;1.1,1.1;ui_right_icon.png;alternate;]", + craftguidearrowx+1.35, craftguidey + 2.6) + formspec[n+3] = "tooltip[alternate_prev;" .. F(prev_alt_text[dir]) .. "]" + formspec[n+4] = "tooltip[alternate;" .. F(next_alt_text[dir]) .. "]" end - return { formspec = table.concat(fs) } + + return { formspec = table.concat(formspec) } end, }) @@ -418,7 +453,7 @@ local function craftguide_giveme(player, formname, fields) local player_name = player:get_player_name() local player_privs = minetest.get_player_privs(player_name) if not player_privs.give and - not unified_inventory.is_creative(player_name) then + not ui.is_creative(player_name) then minetest.log("action", "[unified_inventory] Denied give action to player " .. player_name) return @@ -433,7 +468,7 @@ local function craftguide_giveme(player, formname, fields) amount = tonumber(amount) or 0 if amount == 0 then return end - local output = unified_inventory.current_item[player_name] + local output = ui.current_item[player_name] if (not output) or (output == "") then return end local player_inv = player:get_inventory() @@ -454,21 +489,29 @@ local function craftguide_craft(player, formname, fields) local player_name = player:get_player_name() - local output = unified_inventory.current_item[player_name] or "" + local output = ui.current_item[player_name] or "" if output == "" then return end - local crafts = unified_inventory.crafts_for[ - unified_inventory.current_craft_direction[player_name]][output] or {} + local crafts = ui.crafts_for[ + ui.current_craft_direction[player_name]][output] or {} if #crafts == 0 then return end - local alternate = unified_inventory.alternate[player_name] + local alternate = ui.alternate[player_name] local craft = crafts[alternate] + if not craft.width then + if not craft.output then + minetest.log("warning", "[unified_inventory] Craft has no output.") + else + minetest.log("warning", ("[unified_inventory] Craft for '%s' has no width."):format(craft.output)) + end + return + end if craft.width > 3 then return end - unified_inventory.craftguide_match_craft(player, "main", "craft", craft, amount) + ui.craftguide_match_craft(player, "main", "craft", craft, amount) - unified_inventory.set_inventory_formspec(player, "craft") + ui.set_inventory_formspec(player, "craft") end minetest.register_on_player_receive_fields(function(player, formname, fields) diff --git a/unified_inventory/settingtypes.txt b/unified_inventory/settingtypes.txt index 910989f..27768ac 100644 --- a/unified_inventory/settingtypes.txt +++ b/unified_inventory/settingtypes.txt @@ -9,3 +9,6 @@ unified_inventory_bags (Enable bags) bool true #If enabled, the trash slot can be used by those without both creative #and the give privilege. unified_inventory_trash (Enable trash) bool true + + +unified_inventory_automatic_categorization (Items automatically added to categories) bool true \ No newline at end of file diff --git a/unified_inventory/textures/ui_bags_header.png b/unified_inventory/textures/ui_bags_header.png deleted file mode 100644 index f9bf1dd..0000000 Binary files a/unified_inventory/textures/ui_bags_header.png and /dev/null differ diff --git a/unified_inventory/textures/ui_bags_inv_large.png b/unified_inventory/textures/ui_bags_inv_large.png deleted file mode 100644 index a3725ee..0000000 Binary files a/unified_inventory/textures/ui_bags_inv_large.png and /dev/null differ diff --git a/unified_inventory/textures/ui_bags_inv_medium.png b/unified_inventory/textures/ui_bags_inv_medium.png deleted file mode 100644 index 5924f54..0000000 Binary files a/unified_inventory/textures/ui_bags_inv_medium.png and /dev/null differ diff --git a/unified_inventory/textures/ui_bags_inv_small.png b/unified_inventory/textures/ui_bags_inv_small.png deleted file mode 100644 index 6776754..0000000 Binary files a/unified_inventory/textures/ui_bags_inv_small.png and /dev/null differ diff --git a/unified_inventory/textures/ui_bags_trash.png b/unified_inventory/textures/ui_bags_trash.png deleted file mode 100644 index 8247130..0000000 Binary files a/unified_inventory/textures/ui_bags_trash.png and /dev/null differ diff --git a/unified_inventory/textures/ui_category_all.png b/unified_inventory/textures/ui_category_all.png new file mode 100644 index 0000000..0af7a53 Binary files /dev/null and b/unified_inventory/textures/ui_category_all.png differ diff --git a/unified_inventory/textures/ui_category_none.png b/unified_inventory/textures/ui_category_none.png new file mode 100644 index 0000000..8976fb0 Binary files /dev/null and b/unified_inventory/textures/ui_category_none.png differ diff --git a/unified_inventory/textures/ui_craftguide_form.png b/unified_inventory/textures/ui_craftguide_form.png deleted file mode 100644 index d9be53f..0000000 Binary files a/unified_inventory/textures/ui_craftguide_form.png and /dev/null differ diff --git a/unified_inventory/textures/ui_crafting_arrow.png b/unified_inventory/textures/ui_crafting_arrow.png new file mode 100644 index 0000000..6901c58 Binary files /dev/null and b/unified_inventory/textures/ui_crafting_arrow.png differ diff --git a/unified_inventory/textures/ui_crafting_form.png b/unified_inventory/textures/ui_crafting_form.png deleted file mode 100644 index 9043287..0000000 Binary files a/unified_inventory/textures/ui_crafting_form.png and /dev/null differ diff --git a/unified_inventory/textures/ui_form_bg.png b/unified_inventory/textures/ui_form_bg.png deleted file mode 100644 index 7111fac..0000000 Binary files a/unified_inventory/textures/ui_form_bg.png and /dev/null differ diff --git a/unified_inventory/textures/ui_formbg_9_sliced.png b/unified_inventory/textures/ui_formbg_9_sliced.png new file mode 100644 index 0000000..0b8463c Binary files /dev/null and b/unified_inventory/textures/ui_formbg_9_sliced.png differ diff --git a/unified_inventory/textures/ui_main_inventory.png b/unified_inventory/textures/ui_main_inventory.png deleted file mode 100644 index b9a0545..0000000 Binary files a/unified_inventory/textures/ui_main_inventory.png and /dev/null differ diff --git a/unified_inventory/textures/ui_misc_form.png b/unified_inventory/textures/ui_misc_form.png deleted file mode 100644 index c6a6057..0000000 Binary files a/unified_inventory/textures/ui_misc_form.png and /dev/null differ diff --git a/unified_inventory/textures/ui_single_slot.png b/unified_inventory/textures/ui_single_slot.png index 63da98d..2451623 100644 Binary files a/unified_inventory/textures/ui_single_slot.png and b/unified_inventory/textures/ui_single_slot.png differ diff --git a/unified_inventory/textures/ui_single_slot_bright.png b/unified_inventory/textures/ui_single_slot_bright.png new file mode 100644 index 0000000..c66365c Binary files /dev/null and b/unified_inventory/textures/ui_single_slot_bright.png differ diff --git a/unified_inventory/textures/ui_smallbg_9_sliced.png b/unified_inventory/textures/ui_smallbg_9_sliced.png new file mode 100644 index 0000000..865e0c9 Binary files /dev/null and b/unified_inventory/textures/ui_smallbg_9_sliced.png differ diff --git a/unified_inventory/textures/ui_trash_slot_icon.png b/unified_inventory/textures/ui_trash_slot_icon.png new file mode 100644 index 0000000..5fc4de1 Binary files /dev/null and b/unified_inventory/textures/ui_trash_slot_icon.png differ diff --git a/unified_inventory/textures/ui_xyz_off_icon.png b/unified_inventory/textures/ui_xyz_off_icon.png deleted file mode 100644 index 3c1836e..0000000 Binary files a/unified_inventory/textures/ui_xyz_off_icon.png and /dev/null differ diff --git a/unified_inventory/textures/ui_xyz_on_icon.png b/unified_inventory/textures/ui_xyz_on_icon.png deleted file mode 100644 index 003ea63..0000000 Binary files a/unified_inventory/textures/ui_xyz_on_icon.png and /dev/null differ diff --git a/unified_inventory/waypoints.lua b/unified_inventory/waypoints.lua index 97712b7..1496cdd 100644 --- a/unified_inventory/waypoints.lua +++ b/unified_inventory/waypoints.lua @@ -1,5 +1,7 @@ local S = minetest.get_translator("unified_inventory") local F = minetest.formspec_escape +local ui = unified_inventory +local COUNT = 5 local hud_colors = { {"#FFFFFF", 0xFFFFFF, S("White")}, @@ -9,107 +11,199 @@ local hud_colors = { {"#2c4df1", 0x2c4df1, S("Blue")}, } -local hud_colors_max = #hud_colors +-- Storage compatibility code --- Stores temporary player data (persists until player leaves) +--[[ +Stores temporary player data (persists until player leaves) + [player_name] = { + [] = { + edit = , + hud = , + }, + [] = { ... }, + ... + } +]] local waypoints_temp = {} -unified_inventory.register_page("waypoints", { +--[[ +Datastorage format (per-player): + { + selected = , + [] = { + name = + world_pos = , + color = <"hud_colors" index>, + active = , + display_pos = , + }, + [] = { ... }, + ... + } +Player metadata format: + { + selected = , + -- Cannot mix integer/string keys in JSON + data = { + [] = { same as above }, + ... + } + } +]] + +local function set_waypoint_data(player, waypoints) + local meta = player:get_meta() + if not next(waypoints.data or {}) then + -- Empty data. Do not save anything, or delete + meta:set_string("ui_waypoints", "") + else + meta:set_string("ui_waypoints", minetest.write_json(waypoints)) + end +end + +local function migrate_datastorage(player, waypoints) + -- Copy values from old table + local new_data = { + selected = waypoints.selected, + data = {} + } + for i = 1, COUNT do + new_data.data[i] = waypoints[i] + end + + set_waypoint_data(player, new_data) + + -- Delete values, but keep one entry so that it's saved by datastorage + for k, _ in pairs(waypoints) do + waypoints[k] = nil + end + waypoints[1] = 1 +end + +local have_datastorage = minetest.get_modpath("datastorage") ~= nil +local function get_waypoint_data(player) + local player_name = player:get_player_name() + + -- Migration step + if have_datastorage then + local waypoints = datastorage.get(player_name, "waypoints") + if waypoints.selected then + migrate_datastorage(player, waypoints) + minetest.log("action", "[unified_inventory] " .. + "Migrated waypoints of player: " .. player_name) + end + end + + -- Get directly from metadata + local waypoints = player:get_meta():get("ui_waypoints") + waypoints = waypoints and minetest.parse_json(waypoints) or {} + waypoints.data = waypoints.data or {} + + return waypoints +end + +ui.register_page("waypoints", { get_formspec = function(player) local player_name = player:get_player_name() + local wp_info_x = ui.style_full.form_header_x + 1.25 + local wp_info_y = ui.style_full.form_header_y + 0.5 + local wp_bottom_row = ui.style_full.std_inv_y - 1 + local wp_buttons_rj = ui.style_full.std_inv_x + 10.1 - ui.style_full.btn_spc + local wp_edit_w = ui.style_full.btn_spc * 4 - 0.1 - -- build a "fake" temp entry if the server took too long - -- during sign-on and returned an empty entry - if not waypoints_temp[player_name] then waypoints_temp[player_name] = {hud = 1} end + local waypoints = get_waypoint_data(player) + local sel = waypoints.selected or 1 - local waypoints = datastorage.get(player_name, "waypoints") - local formspec = string.gsub(unified_inventory.standard_inv_bg, "YYY", "4.4") .. - "image[0,0;1,1;ui_waypoints_icon.png]" .. - "label[1,0;" .. F(S("Waypoints")) .. "]" + local formspec = { + ui.style_full.standard_inv_bg, + string.format("label[%f,%f;%s]", + ui.style_full.form_header_x, ui.style_full.form_header_y, F(S("Waypoints"))), + "image["..wp_info_x..","..wp_info_y..";1,1;ui_waypoints_icon.png]" + } + local n=4 -- Tabs buttons: - for i = 1, 5, 1 do - formspec = formspec .. - "image_button[0.0," .. 0.2 + i * 0.7 .. ";.8,.8;" .. - (i == waypoints.selected and "ui_blue_icon_background.png^" or "") .. - "ui_" .. i .. "_icon.png;" .. - "select_waypoint" .. i .. ";]" .. - "tooltip[select_waypoint" .. i .. ";" - .. S("Select Waypoint #@1", i).."]" + for i = 1, COUNT do + local sw="select_waypoint"..i + formspec[n] = string.format("image_button[%f,%f;%f,%f;%sui_%i_icon.png;%s;]", + ui.style_full.main_button_x, wp_bottom_row - (5-i) * ui.style_full.btn_spc, + ui.style_full.btn_size, ui.style_full.btn_size, + (i == sel) and "ui_blue_icon_background.png^" or "", + i, sw) + formspec[n+1] = "tooltip["..sw..";"..S("Select Waypoint #@1", i).."]" + n = n + 2 end - local i = waypoints.selected or 1 - local waypoint = waypoints[i] or {} - local temp = waypoints_temp[player_name][i] or {} - local default_name = S("Waypoint @1", i) + local waypoint = waypoints.data[sel] or {} + local temp = waypoints_temp[player_name][sel] or {} + local default_name = S("Waypoint @1", sel) -- Main buttons: - formspec = formspec .. - "image_button[4.5,3.7;.8,.8;".. - "ui_waypoint_set_icon.png;".. - "set_waypoint"..i..";]".. - "tooltip[set_waypoint" .. i .. ";" - .. F(S("Set waypoint to current location")).."]" + local btnlist = { + set_waypoint = { + "ui_waypoint_set_icon.png", + S("Set waypoint to current location") + }, + toggle_waypoint = { + waypoint.active and "ui_on_icon.png" or "ui_off_icon.png", + waypoint.active and S("Hide waypoint") or S("Show waypoint") + }, + toggle_display_pos = { + waypoint.display_pos and "ui_green_icon_background.png^ui_xyz_icon.png" or "ui_red_icon_background.png^ui_xyz_icon.png^(ui_no.png^[transformR90)", + waypoint.display_pos and S("Hide coordinates") or S("Show coordinates") + }, + toggle_color = { + "ui_circular_arrows_icon.png", + S("Change color of waypoint display") + }, + rename_waypoint = { + "ui_pencil_icon.png", + S("Edit waypoint name") + } + } - formspec = formspec .. - "image_button[5.2,3.7;.8,.8;".. - (waypoint.active and "ui_on_icon.png" or "ui_off_icon.png")..";".. - "toggle_waypoint"..i..";]".. - "tooltip[toggle_waypoint" .. i .. ";" - .. F(S("Make waypoint @1", - waypoint.active and S("invisible") or S("visible"))).."]" - - formspec = formspec .. - "image_button[5.9,3.7;.8,.8;".. - (waypoint.display_pos and "ui_green_icon_background.png" or "ui_red_icon_background.png").."^ui_xyz_icon.png;".. - "toggle_display_pos" .. i .. ";]".. - "tooltip[toggle_display_pos" .. i .. ";" - .. F(S("@1 display of waypoint coordinates", - waypoint.display_pos and S("Disable") or S("Enable"))) .."]" - - formspec = formspec .. - "image_button[6.6,3.7;.8,.8;".. - "ui_circular_arrows_icon.png;".. - "toggle_color"..i..";]".. - "tooltip[toggle_color" .. i .. ";" - .. F(S("Change color of waypoint display")).."]" - - formspec = formspec .. - "image_button[7.3,3.7;.8,.8;".. - "ui_pencil_icon.png;".. - "rename_waypoint"..i..";]".. - "tooltip[rename_waypoint" .. i .. ";" - .. F(S("Edit waypoint name")).."]" + local x = 4 + for name, def in pairs(btnlist) do + formspec[n] = string.format("image_button[%f,%f;%f,%f;%s;%s%i;]", + wp_buttons_rj - ui.style_full.btn_spc * x, wp_bottom_row, + ui.style_full.btn_size, ui.style_full.btn_size, + def[1], name, sel) + formspec[n+1] = "tooltip["..name..sel..";"..F(def[2]).."]" + x = x - 1 + n = n + 2 + end -- Waypoint's info: - if waypoint.active then - formspec = formspec .. "label[1,0.8;"..F(S("Waypoint active")).."]" - else - formspec = formspec .. "label[1,0.8;"..F(S("Waypoint inactive")).."]" - end + formspec[n] = ("label[%f,%f;%s]"):format( + wp_info_x, wp_info_y + 1.1, + F(waypoint.active and S("Waypoint active") or S("Waypoint inactive")) + ) + n = n + 1 if temp.edit then - formspec = formspec .. - "field[1.3,3.2;6,.8;rename_box" .. i .. ";;" - ..(waypoint.name or default_name).."]" .. - "image_button[7.3,2.9;.8,.8;".. - "ui_ok_icon.png;".. - "confirm_rename"..i.. ";]".. - "tooltip[confirm_rename" .. i .. ";" - .. F(S("Finish editing")).."]" + formspec[n] = string.format("field[%f,%f;%f,%f;rename_box%i;;%s]", + wp_buttons_rj - wp_edit_w - 0.1, wp_bottom_row - ui.style_full.btn_spc, + wp_edit_w, ui.style_full.btn_size, sel, (waypoint.name or default_name)) + formspec[n+1] = string.format("image_button[%f,%f;%f,%f;ui_ok_icon.png;confirm_rename%i;]", + wp_buttons_rj, wp_bottom_row - ui.style_full.btn_spc, + ui.style_full.btn_size, ui.style_full.btn_size, sel) + formspec[n+2] = "tooltip[confirm_rename"..sel..";"..F(S("Finish editing")).."]" + n = n + 3 end - formspec = formspec .. "label[1,1.3;"..F(S("World position"))..": " .. - minetest.pos_to_string(waypoint.world_pos or vector.new()) .. "]" .. - "label[1,1.8;"..F(S("Name"))..": ".. (waypoint.name or default_name) .. "]" .. - "label[1,2.3;"..F(S("HUD text color"))..": " .. - hud_colors[waypoint.color or 1][3] .. "]" + formspec[n] = string.format("label[%f,%f;%s: %s]", + wp_info_x, wp_info_y+1.6, F(S("World position")), + minetest.pos_to_string(waypoint.world_pos or vector.new())) + formspec[n+1] = string.format("label[%f,%f;%s: %s]", + wp_info_x, wp_info_y+2.10, F(S("Name")), (waypoint.name or default_name)) + formspec[n+2] = string.format("label[%f,%f;%s: %s]", + wp_info_x, wp_info_y+2.60, F(S("HUD text color")), hud_colors[waypoint.color or 1][3]) - return {formspec=formspec} + return {formspec=table.concat(formspec)} end, }) -unified_inventory.register_button("waypoints", { +ui.register_button("waypoints", { type = "image", image = "ui_waypoints_icon.png", tooltip = S("Waypoints"), @@ -117,10 +211,12 @@ unified_inventory.register_button("waypoints", { }) local function update_hud(player, waypoints, temp, i) - local waypoint = waypoints[i] + local waypoint = waypoints.data[i] if not waypoint then return end + temp[i] = temp[i] or {} temp = temp[i] + local pos = waypoint.world_pos or vector.new() local name if waypoint.display_pos then @@ -129,10 +225,13 @@ local function update_hud(player, waypoints, temp, i) name = name..", "..waypoint.name end else - name = waypoint.name or "Waypoint "..i + name = waypoint.name or S("Waypoint @1", i) end + + -- Perform HUD updates if temp.hud then player:hud_remove(temp.hud) + temp.hud = nil end if waypoint.active then temp.hud = player:hud_add({ @@ -142,8 +241,6 @@ local function update_hud(player, waypoints, temp, i) text = "m", world_pos = pos }) - else - temp.hud = nil end end @@ -155,9 +252,11 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local need_update_hud = false local hit = false - local waypoints = datastorage.get(player_name, "waypoints") + local waypoints = get_waypoint_data(player) local temp = waypoints_temp[player_name] - for i = 1, 5, 1 do + for i = 1, COUNT do + local waypoint = waypoints.data[i] or {} + if fields["select_waypoint"..i] then hit = true waypoints.selected = i @@ -166,20 +265,15 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields["toggle_waypoint"..i] then hit = true - waypoints[i] = waypoints[i] or {} - waypoints[i].active = not (waypoints[i].active) + waypoint.active = not (waypoint.active) need_update_hud = true update_formspec = true end if fields["set_waypoint"..i] then hit = true - local pos = player:get_pos() - pos.x = math.floor(pos.x) - pos.y = math.floor(pos.y) - pos.z = math.floor(pos.z) - waypoints[i] = waypoints[i] or {} - waypoints[i].world_pos = pos + local pos = vector.round(player:get_pos()) + waypoint.world_pos = pos need_update_hud = true update_formspec = true end @@ -193,51 +287,58 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields["toggle_display_pos"..i] then hit = true - waypoints[i] = waypoints[i] or {} - waypoints[i].display_pos = not waypoints[i].display_pos + waypoint.display_pos = not waypoint.display_pos need_update_hud = true update_formspec = true end if fields["toggle_color"..i] then hit = true - waypoints[i] = waypoints[i] or {} - local color = waypoints[i].color or 1 + local color = waypoint.color or 0 color = color + 1 - if color > hud_colors_max then + if color > #hud_colors then color = 1 end - waypoints[i].color = color + waypoint.color = color need_update_hud = true update_formspec = true end if fields["confirm_rename"..i] then hit = true - waypoints[i] = waypoints[i] or {} + temp[i] = temp[i] or {} temp[i].edit = false - waypoints[i].name = fields["rename_box"..i] + waypoint.name = fields["rename_box"..i] need_update_hud = true update_formspec = true end + + if hit then + -- Save first + waypoints.data[i] = waypoint + set_waypoint_data(player, waypoints) + end + -- Update after if need_update_hud then update_hud(player, waypoints, temp, i) end if update_formspec then - unified_inventory.set_inventory_formspec(player, "waypoints") + ui.set_inventory_formspec(player, "waypoints") end + if hit then return end end end) - -minetest.register_on_joinplayer(function(player) +-- waypoints_temp must be initialized before the general unified_inventory +-- joinplayer callback is run for updating the inventory +table.insert(minetest.registered_on_joinplayers, 1, function(player) local player_name = player:get_player_name() - local waypoints = datastorage.get(player_name, "waypoints") - local temp = {} - waypoints_temp[player_name] = temp - for i = 1, 5 do - update_hud(player, waypoints, temp, i) + local waypoints = get_waypoint_data(player) + + waypoints_temp[player_name] = {} + for i = 1, COUNT do + update_hud(player, waypoints, waypoints_temp[player_name], i) end end)