From cf95f6ab80a9363e76cd289b87179a10dd6f3cfe Mon Sep 17 00:00:00 2001 From: poikilos <7557867+poikilos@users.noreply.github.com> Date: Thu, 3 Feb 2022 18:49:25 -0500 Subject: [PATCH] Draw new dye images for dye and unifieddyes so they are the same style (related to issue #486). The colors are based on the historical and natural pigment palette from poikilos/dyed WIP mod. --- .../dye-redrawn-vs-220114/mods/LICENSE | 12 + .../mods/coderbuild/unifieddyes/00README | 1 + .../mods/coderbuild/unifieddyes/LICENSE | 282 +++ .../mods/coderbuild/unifieddyes/README.md | 16 + .../mods/coderbuild/unifieddyes/init.lua | 1531 +++++++++++++++++ .../mods/coderbuild/unifieddyes/oldcoder.txt | 17 + .../unifieddyes/textures/unifieddyes_dye.png | Bin 0 -> 150 bytes .../mods/codercore/dye/license.txt | 60 + .../mods/codercore/dye/textures/dye_black.png | Bin 0 -> 1122 bytes .../mods/codercore/dye/textures/dye_blue.png | Bin 0 -> 1135 bytes .../mods/codercore/dye/textures/dye_brown.png | Bin 0 -> 1122 bytes .../mods/codercore/dye/textures/dye_cyan.png | Bin 0 -> 1136 bytes .../codercore/dye/textures/dye_dark_green.png | Bin 0 -> 1137 bytes .../codercore/dye/textures/dye_dark_grey.png | Bin 0 -> 1102 bytes .../mods/codercore/dye/textures/dye_green.png | Bin 0 -> 1134 bytes .../mods/codercore/dye/textures/dye_grey.png | Bin 0 -> 1102 bytes .../codercore/dye/textures/dye_magenta.png | Bin 0 -> 1134 bytes .../codercore/dye/textures/dye_orange.png | Bin 0 -> 1133 bytes .../mods/codercore/dye/textures/dye_pink.png | Bin 0 -> 1133 bytes .../mods/codercore/dye/textures/dye_red.png | Bin 0 -> 1146 bytes .../codercore/dye/textures/dye_violet.png | Bin 0 -> 1137 bytes .../mods/codercore/dye/textures/dye_white.png | Bin 0 -> 1124 bytes .../codercore/dye/textures/dye_yellow.png | Bin 0 -> 1139 bytes ...drawn-vs-220114-alternative-multiply.patch | 66 + Bucket_Game-branches/dye-redrawn-vs-220114.md | 12 + .../dye-redrawn-vs-220114.patch | 176 ++ Bucket_Game-branches/dye-redrawn-vs-220114.sh | 37 + .../dye-redrawn-vs-220114/mods/LICENSE | 12 + .../mods/coderbuild/unifieddyes/00README | 1 + .../mods/coderbuild/unifieddyes/LICENSE | 282 +++ .../mods/coderbuild/unifieddyes/README.md | 18 + .../mods/coderbuild/unifieddyes/init.lua | 1531 +++++++++++++++++ .../mods/coderbuild/unifieddyes/oldcoder.txt | 17 + .../unifieddyes/textures/unifieddyes_dye.png | Bin 0 -> 1089 bytes .../mods/codercore/dye/license.txt | 60 + .../codercore/dye/projects/dye-poikilos.xcf | Bin 0 -> 52894 bytes .../mods/codercore/dye/textures/dye_black.png | Bin 0 -> 940 bytes .../mods/codercore/dye/textures/dye_blue.png | Bin 0 -> 976 bytes .../mods/codercore/dye/textures/dye_brown.png | Bin 0 -> 1065 bytes .../mods/codercore/dye/textures/dye_cyan.png | Bin 0 -> 1003 bytes .../codercore/dye/textures/dye_dark_green.png | Bin 0 -> 1021 bytes .../codercore/dye/textures/dye_dark_grey.png | Bin 0 -> 979 bytes .../mods/codercore/dye/textures/dye_green.png | Bin 0 -> 1008 bytes .../mods/codercore/dye/textures/dye_grey.png | Bin 0 -> 1020 bytes .../codercore/dye/textures/dye_magenta.png | Bin 0 -> 1028 bytes .../codercore/dye/textures/dye_orange.png | Bin 0 -> 1014 bytes .../mods/codercore/dye/textures/dye_pink.png | Bin 0 -> 1101 bytes .../mods/codercore/dye/textures/dye_red.png | Bin 0 -> 1000 bytes .../codercore/dye/textures/dye_violet.png | Bin 0 -> 1053 bytes .../mods/codercore/dye/textures/dye_white.png | Bin 0 -> 699 bytes .../codercore/dye/textures/dye_yellow.png | Bin 0 -> 1009 bytes 51 files changed, 4131 insertions(+) create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/LICENSE create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/00README create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/LICENSE create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/oldcoder.txt create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/textures/unifieddyes_dye.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/license.txt create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_black.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_blue.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_brown.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_cyan.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_green.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_grey.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_green.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_grey.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_magenta.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_orange.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_pink.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_red.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_violet.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_white.png create mode 100644 Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_yellow.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114-alternative-multiply.patch create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114.md create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114.patch create mode 100755 Bucket_Game-branches/dye-redrawn-vs-220114.sh create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/LICENSE create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/00README create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/LICENSE create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/oldcoder.txt create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/textures/unifieddyes_dye.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/license.txt create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/projects/dye-poikilos.xcf create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_black.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_blue.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_brown.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_cyan.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_green.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_grey.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_green.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_grey.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_magenta.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_orange.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_pink.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_red.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_violet.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_white.png create mode 100644 Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_yellow.png diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/LICENSE b/Bucket_Game-base/dye-redrawn-vs-220114/mods/LICENSE new file mode 100644 index 0000000..4ebf695 --- /dev/null +++ b/Bucket_Game-base/dye-redrawn-vs-220114/mods/LICENSE @@ -0,0 +1,12 @@ +For license information, see the following files, where they exist, in +each modpack or mod: + + oldcoder.txt + LICENSE + LICENSE.txt + license.txt + README.md + README.txt + readme.txt + +and/or files with similar names. diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/00README b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/00README new file mode 100644 index 0000000..1aa78a4 --- /dev/null +++ b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/00README @@ -0,0 +1 @@ +See "oldcoder.txt". diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/LICENSE b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/LICENSE new file mode 100644 index 0000000..4eb7598 --- /dev/null +++ b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/LICENSE @@ -0,0 +1,282 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md new file mode 100644 index 0000000..44ddbb2 --- /dev/null +++ b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md @@ -0,0 +1,16 @@ +VanessaE's Unified Dyes +======================= + +The purpose of this mod originally was to supply a complete set of colors for Minetest mod authors to use for colorized nodes, or to reference in recipes. Since the advent of the default dyes mod in minetest_game, this mod has become more of an extension of the default mod. Since the advent of param2 colorization, it has also become a library for general color handling. + +Unified Dyes expands the standard dye set from 15 colors to 32, 89, or 256 (see the API and usage info). + +Dependencies: Minetest engine version 0.4.16 or higher and a corresponding copy of minetest_game. + +License: GPL 2.0 or higher. + +Install: Unzip the distribution file, rename the resultant folder to just "unifieddyes", move it into Minetest's mods folder, and enable it in your world configuration. + +Usage: for detailed usage information, please see [the Unified Dyes Thread](https://forum.minetest.net/viewtopic.php?f=11&t=2178&p=28399) on the Minetest forum. + +API: the full API is documented here: https://github.com/minetest-mods/unifieddyes/blob/master/API.md diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua new file mode 100644 index 0000000..b692810 --- /dev/null +++ b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua @@ -0,0 +1,1531 @@ +--[[ + +Unified Dyes + +This mod provides an extension to the Minetest 0.4.x dye system + +============================================================================== + +Copyright (C) 2012-2013, Vanessa Ezekowitz +Email: vanessaezekowitz@gmail.com + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +============================================================================== + +--]] + +--===================================================================== + +unifieddyes = {} + +local creative_mode = minetest.settings:get_bool("creative_mode") + +-- Boilerplate to support localized strings if intllib mod is installed. +local S +if minetest.get_modpath("intllib") then + S = intllib.Getter() +else + S = function(s) return s end +end + +-- the names of the various colors here came from http://www.procato.com/rgb+index/ + +unifieddyes.HUES_EXTENDED = { + { "red", 0xff, 0x00, 0x00 }, + { "vermilion", 0xff, 0x40, 0x00 }, + { "orange", 0xff, 0x80, 0x00 }, + { "amber", 0xff, 0xbf, 0x00 }, + { "yellow", 0xff, 0xff, 0x00 }, + { "lime", 0xbf, 0xff, 0x00 }, + { "chartreuse", 0x80, 0xff, 0x00 }, + { "harlequin", 0x40, 0xff, 0x00 }, + { "green", 0x00, 0xff, 0x00 }, + { "malachite", 0x00, 0xff, 0x40 }, + { "spring", 0x00, 0xff, 0x80 }, + { "turquoise", 0x00, 0xff, 0xbf }, + { "cyan", 0x00, 0xff, 0xff }, + { "cerulean", 0x00, 0xbf, 0xff }, + { "azure", 0x00, 0x80, 0xff }, + { "sapphire", 0x00, 0x40, 0xff }, + { "blue", 0x00, 0x00, 0xff }, + { "indigo", 0x40, 0x00, 0xff }, + { "violet", 0x80, 0x00, 0xff }, + { "mulberry", 0xbf, 0x00, 0xff }, + { "magenta", 0xff, 0x00, 0xff }, + { "fuchsia", 0xff, 0x00, 0xbf }, + { "rose", 0xff, 0x00, 0x80 }, + { "crimson", 0xff, 0x00, 0x40 } +} + +unifieddyes.HUES_WITH_GREY = {} + +for _,i in ipairs(unifieddyes.HUES_EXTENDED) do + table.insert(unifieddyes.HUES_WITH_GREY, i[1]) +end +table.insert(unifieddyes.HUES_WITH_GREY, "grey") + +unifieddyes.HUES_WALLMOUNTED = { + "red", + "orange", + "yellow", + "green", + "cyan", + "blue", + "violet", + "magenta" +} + +unifieddyes.SATS = { + "", + "_s50" +} + +unifieddyes.VALS = { + "", + "medium_", + "dark_" +} + +unifieddyes.VALS_SPLIT = { + "faint_", + "light_", + "", + "medium_", + "dark_" +} + +unifieddyes.VALS_EXTENDED = { + "faint_", + "pastel_", + "light_", + "bright_", + "", + "medium_", + "dark_" +} + +unifieddyes.GREYS = { + "white", + "light_grey", + "grey", + "dark_grey", + "black" +} + +unifieddyes.GREYS_EXTENDED = table.copy(unifieddyes.GREYS) + +for i = 1, 14 do + if i ~= 0 and i ~= 4 and i ~= 8 and i ~= 11 and i ~= 15 then + table.insert(unifieddyes.GREYS_EXTENDED, "grey_"..i) + end +end + +local default_dyes = { + "black", + "blue", + "brown", + "cyan", + "dark_green", + "dark_grey", + "green", + "grey", + "magenta", + "orange", + "pink", + "red", + "violet", + "white", + "yellow" +} + +unifieddyes.player_current_dye = {} +unifieddyes.player_selected_dye = {} +unifieddyes.player_last_right_clicked = {} +unifieddyes.palette_has_color = {} +unifieddyes.player_showall = {} + +-- if a node with a palette is placed in the world, +-- but the itemstack used to place it has no palette_index (color byte), +-- create something appropriate to make it officially white. + +minetest.register_on_placenode( + function(pos, newnode, placer, oldnode, itemstack, pointed_thing) + local def = minetest.registered_items[newnode.name] + + if not def + or not def.palette + or def.after_place_node then + return false + end + + if not string.find(itemstack:to_string(), "palette_index") then + local param2 + local color = 0 + + if def.palette == "unifieddyes_palette_extended.png" + and def.paramtype2 == "color" then + param2 = 240 + color = 240 + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" + and def.paramtype2 == "colorwallmounted" then + param2 = newnode.param2 % 8 + elseif string.find(def.palette, "unifieddyes_palette_") + and def.paramtype2 == "colorfacedir" then -- it's a split palette + param2 = newnode.param2 % 32 + end + + if param2 then + minetest.swap_node(pos, {name = newnode.name, param2 = param2}) + minetest.get_meta(pos):set_int("palette_index", color) + end + end + end +) + +-- just stubs to keep old mods from crashing when expecting auto-coloring +-- or getting back the dye on dig. + +function unifieddyes.recolor_on_place(foo) +end + +function unifieddyes.after_dig_node(foo) +end + +-- This helper function creates multiple copies of the passed node, +-- for the split palette - one per hue, plus grey - and assigns +-- proper palettes and other attributes + +function unifieddyes.generate_split_palette_nodes(name, def, drop) + for _, color in ipairs(unifieddyes.HUES_WITH_GREY) do + local def2 = table.copy(def) + local desc_color = string.gsub(string.upper(string.sub(color, 1, 1))..string.sub(color, 2), "_", " ") + if string.sub(def2.description, -1) == ")" then + def2.description = string.sub(def2.description, 1, -2)..", "..desc_color.." shades)" + else + def2.description = def2.description.."("..desc_color.." shades)" + end + def2.palette = "unifieddyes_palette_"..color.."s.png" + def2.paramtype2 = "colorfacedir" + def2.groups.ud_param2_colorable = 1 + + if drop then + def2.drop = { + items = { + {items = {drop.."_"..color}, inherit_color = true }, + } + } + end + + minetest.register_node(":"..name.."_"..color, def2) + end +end + +-- This helper function creates a colored itemstack + +function unifieddyes.make_colored_itemstack(item, palette, color) + local paletteidx = unifieddyes.getpaletteidx(color, palette) + local stack = ItemStack(item) + stack:get_meta():set_int("palette_index", paletteidx) + return stack:to_string(),paletteidx +end + +-- these helper functions register all of the recipes needed to create colored +-- nodes with any of the dyes supported by that node's palette. + +local function register_c(craft, h, sat, val) + local hue = (type(h) == "table") and h[1] or h + local color = "" + if val then + if craft.palette == "wallmounted" then + color = val..hue..sat + else + color = val..hue..sat + end + else + color = hue -- if val is nil, then it's grey. + end + + local dye = "dye:"..color + local recipe = minetest.serialize(craft.recipe) + recipe = string.gsub(recipe, "MAIN_DYE", dye) + recipe = string.gsub(recipe, "NEUTRAL_NODE", craft.neutral_node) + local newrecipe = minetest.deserialize(recipe) + + local coutput = craft.output or "" + local output = coutput + if craft.output_prefix then + if craft.palette ~= "split" then + output = craft.output_prefix..color..craft.output_suffix..coutput + else + if hue == "white" or hue == "black" or string.find(hue, "grey") then + output = craft.output_prefix.."grey"..craft.output_suffix..coutput + elseif hue == "pink" then + dye = "dye:light_red" + output = craft.output_prefix.."red"..craft.output_suffix..coutput + else + output = craft.output_prefix..hue..craft.output_suffix..coutput + end + end + end + + local colored_itemstack = + unifieddyes.make_colored_itemstack(output, craft.palette, dye) + + minetest.register_craft({ + output = colored_itemstack, + type = craft.type, + recipe = newrecipe + }) + +end + +function unifieddyes.register_color_craft(craft) + local hues_table = unifieddyes.HUES_EXTENDED + local sats_table = unifieddyes.SATS + local vals_table = unifieddyes.VALS_SPLIT + local greys_table = unifieddyes.GREYS + + if craft.palette == "wallmounted" then + register_c(craft, "green", "", "light_") + register_c(craft, "blue", "", "light_") + hues_table = unifieddyes.HUES_WALLMOUNTED + sats_table = {""} + vals_table = unifieddyes.VALS + elseif craft.palette == "extended" then + vals_table = unifieddyes.VALS_EXTENDED + greys_table = unifieddyes.GREYS_EXTENDED + end + + for _, hue in ipairs(hues_table) do + for _, val in ipairs(vals_table) do + for _, sat in ipairs(sats_table) do + + if sat == "_s50" and val ~= "" and val ~= "medium_" and val ~= "dark_" then break end + register_c(craft, hue, sat, val) + + end + end + end + + for _, grey in ipairs(greys_table) do + register_c(craft, grey) + end + + register_c(craft, "pink") + +end + +-- code borrowed from homedecor +-- call this function to reset the rotation of a "wallmounted" object on place + +function unifieddyes.fix_rotation(pos, placer, itemstack, pointed_thing) + local node = minetest.get_node(pos) + local colorbits = node.param2 - (node.param2 % 8) + + local yaw = placer:get_look_horizontal() + local dir = minetest.yaw_to_dir(yaw) -- -1.5) + local pitch = placer:get_look_vertical() + + local fdir = minetest.dir_to_wallmounted(dir) + + if pitch < -(math.pi/8) then + fdir = 0 + elseif pitch > math.pi/8 then + fdir = 1 + end + minetest.swap_node(pos, { name = node.name, param2 = fdir+colorbits }) +end + +-- use this when you have a "wallmounted" node that should never be oriented +-- to floor or ceiling... + +function unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + local node = minetest.get_node(pos) + local colorbits = node.param2 - (node.param2 % 8) + local yaw = placer:get_look_horizontal() + local dir = minetest.yaw_to_dir(yaw+1.5) + local fdir = minetest.dir_to_wallmounted(dir) + + minetest.swap_node(pos, { name = node.name, param2 = fdir+colorbits }) +end + +-- ... and use this one to force that kind of node off of floor/ceiling +-- orientation after the screwdriver rotates it. + +function unifieddyes.fix_after_screwdriver_nsew(pos, node, user, mode, new_param2) + local new_fdir = new_param2 % 8 + local color = new_param2 - new_fdir + if new_fdir < 2 then + new_fdir = 2 + minetest.swap_node(pos, { name = node.name, param2 = new_fdir + color }) + return true + end +end + +function unifieddyes.is_buildable_to(placer_name, ...) + for _, pos in ipairs({...}) do + local node = minetest.get_node_or_nil(pos) + local def = node and minetest.registered_nodes[node.name] + if not (def and def.buildable_to) or minetest.is_protected(pos, placer_name) then + return false + end + end + return true +end + +function unifieddyes.get_hsv(name) -- expects a node/item name + local hue = "" + local a,b + for _, i in ipairs(unifieddyes.HUES_EXTENDED) do + a,b = string.find(name, "_"..i[1]) + if a then + hue = i[1] + break + end + end + + if string.find(name, "_light_grey") then hue = "light_grey" + elseif string.find(name, "_lightgrey") then hue = "light_grey" + elseif string.find(name, "_dark_grey") then hue = "dark_grey" + elseif string.find(name, "_darkgrey") then hue = "dark_grey" + elseif string.find(name, "_grey") then hue = "grey" + elseif string.find(name, "_white") then hue = "white" + elseif string.find(name, "_black") then hue = "black" + end + + local sat = "" + if string.find(name, "_s50") then sat = "_s50" end + + local val = "" + if string.find(name, "dark_") then val = "dark_" end + if string.find(name, "medium_") then val = "medium_" end + if string.find(name, "light_") then val = "light_" end + + return hue, sat, val +end + +-- code partially borrowed from cheapie's plasticbox mod + +-- in the function below, color is just a color string, while +-- palette_type can be: +-- +-- "extended" = 256 color palette +-- "split" = 200 color palette split into pieces for colorfacedir +-- "wallmounted" = 32-color abridged palette + + +function unifieddyes.getpaletteidx(color, palette_type) + + local origcolor = color + local aliases = { + ["pink"] = "light_red", + ["brown"] = "medium_orange", + ["azure"] = "light_blue" + } + + local grayscale = { + ["white"] = 1, + ["light_grey"] = 2, + ["grey"] = 3, + ["dark_grey"] = 4, + ["black"] = 5, + } + + local grayscale_extended = { + ["white"] = 0, + ["grey_14"] = 1, + ["grey_13"] = 2, + ["grey_12"] = 3, + ["light_grey"] = 4, + ["grey_11"] = 4, + ["grey_10"] = 5, + ["grey_9"] = 6, + ["grey_8"] = 7, + ["grey"] = 7, + ["grey_7"] = 8, + ["grey_6"] = 9, + ["grey_5"] = 10, + ["grey_4"] = 11, + ["dark_grey"] = 11, + ["grey_3"] = 12, + ["grey_2"] = 13, + ["grey_1"] = 14, + ["black"] = 15, + } + + local grayscale_wallmounted = { + ["white"] = 0, + ["light_grey"] = 1, + ["grey"] = 2, + ["dark_grey"] = 3, + ["black"] = 4, + } + + local hues_extended = { + ["red"] = 0, + ["vermilion"] = 1, + ["orange"] = 2, + ["amber"] = 3, + ["yellow"] = 4, + ["lime"] = 5, + ["chartreuse"] = 6, + ["harlequin"] = 7, + ["green"] = 8, + ["malachite"] = 9, + ["spring"] = 10, + ["aqua"] = 10, + ["turquoise"] = 11, + ["cyan"] = 12, + ["cerulean"] = 13, + ["azure"] = 14, + ["skyblue"] = 14, + ["sapphire"] = 15, + ["blue"] = 16, + ["indigo"] = 17, + ["violet"] = 18, + ["mulberry"] = 19, + ["magenta"] = 20, + ["fuchsia"] = 21, + ["rose"] = 22, + ["redviolet"] = 22, + ["crimson"] = 23, + } + + local hues_wallmounted = { + ["red"] = 0, + ["orange"] = 1, + ["yellow"] = 2, + ["green"] = 3, + ["cyan"] = 4, + ["blue"] = 5, + ["violet"] = 6, + ["magenta"] = 7 + } + + local shades = { + [""] = 1, + ["s50"] = 2, + ["light"] = 3, + ["medium"] = 4, + ["mediums50"] = 5, + ["dark"] = 6, + ["darks50"] = 7, + } + + local shades_split = { + ["faint"] = 0, + [""] = 1, + ["s50"] = 2, + ["light"] = 3, + ["medium"] = 4, + ["mediums50"] = 5, + ["dark"] = 6, + ["darks50"] = 7, + } + + local shades_extended = { + ["faint"] = 0, + ["pastel"] = 1, + ["light"] = 2, + ["bright"] = 3, + [""] = 4, + ["s50"] = 5, + ["medium"] = 6, + ["mediums50"] = 7, + ["dark"] = 8, + ["darks50"] = 9 + } + + local shades_wallmounted = { + [""] = 1, + ["medium"] = 2, + ["dark"] = 3 + } + + if string.sub(color,1,4) == "dye:" then + color = string.sub(color,5,-1) + elseif string.sub(color,1,12) == "unifieddyes:" then + color = string.sub(color,13,-1) + else + return + end + + if palette_type == "wallmounted" then + if grayscale_wallmounted[color] then + return (grayscale_wallmounted[color] * 8), 0 + end + elseif palette_type == "split" then + if grayscale[color] then + return (grayscale[color] * 32), 0 + end + elseif palette_type == "extended" then + if grayscale_extended[color] then + return grayscale_extended[color]+240, 0 + end + end + + local shade = "" -- assume full + if string.sub(color,1,6) == "faint_" then + shade = "faint" + color = string.sub(color,7,-1) + elseif string.sub(color,1,7) == "pastel_" then + shade = "pastel" + color = string.sub(color,8,-1) + elseif string.sub(color,1,6) == "light_" then + shade = "light" + color = string.sub(color,7,-1) + elseif string.sub(color,1,7) == "bright_" then + shade = "bright" + color = string.sub(color,8,-1) + elseif string.sub(color,1,7) == "medium_" then + shade = "medium" + color = string.sub(color,8,-1) + elseif string.sub(color,1,5) == "dark_" then + shade = "dark" + color = string.sub(color,6,-1) + end + if string.sub(color,-4,-1) == "_s50" then + shade = shade.."s50" + color = string.sub(color,1,-5) + end + + if palette_type == "wallmounted" then + if color == "green" and shade == "light" then return 48,3 + elseif color == "brown" then return 17,1 + elseif color == "pink" then return 56,7 + elseif color == "blue" and shade == "light" then return 40,5 + elseif hues_wallmounted[color] and shades_wallmounted[shade] then + return (shades_wallmounted[shade] * 64 + hues_wallmounted[color] * 8), hues_wallmounted[color] + end + else + if color == "brown" then + color = "orange" + shade = "medium" + elseif color == "pink" then + color = "red" + shade = "light" + end + if palette_type == "split" then -- it's colorfacedir + if hues_extended[color] and shades_split[shade] then + return (shades_split[shade] * 32), hues_extended[color]+1 + end + elseif palette_type == "extended" then + if hues_extended[color] and shades_extended[shade] then + return (hues_extended[color] + shades_extended[shade]*24), hues_extended[color] + end + end + end +end + +function unifieddyes.get_color_from_dye_name(name) + if name == "dye:black" then + return "000000" + elseif name == "dye:white" then + return "ffffff" + end + local item = minetest.registered_items[name] + if not item then return end + local inv_image = item.inventory_image + if not inv_image then return end + return string.match(inv_image,"colorize:#(......):200") +end + +-- punch-to-recolor using the airbrush + +function unifieddyes.on_airbrush(itemstack, player, pointed_thing) + local player_name = player:get_player_name() + local painting_with = nil + + if unifieddyes.player_current_dye[player_name] then + painting_with = unifieddyes.player_current_dye[player_name] + end + + if not painting_with then + minetest.chat_send_player(player_name, "*** You need to set a color first.") + minetest.chat_send_player(player_name, "*** Right-click any random node to open the color selector,") + minetest.chat_send_player(player_name, "*** or shift+right-click a colorized node to use its color.") + minetest.chat_send_player(player_name, "*** Be sure to click \"Accept\", or the color you select will be ignored.") + return + end + + local pos = minetest.get_pointed_thing_position(pointed_thing) + if not pos then + local look_angle = player:get_look_vertical() + if look_angle > -1.55 then + minetest.chat_send_player(player_name, "*** No node selected") + else + local hexcolor = unifieddyes.get_color_from_dye_name(painting_with) + local r = tonumber(string.sub(hexcolor,1,2),16) + local g = tonumber(string.sub(hexcolor,3,4),16) + local b = tonumber(string.sub(hexcolor,5,6),16) + player:set_sky({r=r,g=g,b=b,a=255},"plain") + end + return + end + + local node = minetest.get_node(pos) + local def = minetest.registered_items[node.name] + if not def then return end + + if minetest.is_protected(pos, player_name) then + minetest.chat_send_player(player_name, "*** Sorry, someone else owns that node.") + return + end + + if not (def.groups and def.groups.ud_param2_colorable and def.groups.ud_param2_colorable > 0) then + minetest.chat_send_player(player_name, "*** That node can't be colored.") + return + end + + local palette = nil + local fdir = 0 + if not def or not def.palette then + minetest.chat_send_player(player_name, "*** That node can't be colored -- it's either undefined or has no palette.") + return + elseif def.palette == "unifieddyes_palette_extended.png" then + palette = "extended" + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" then + palette = "wallmounted" + fdir = node.param2 % 8 + elseif def.palette ~= "unifieddyes_palette_extended.png" + and def.palette ~= "unifieddyes_palette_colorwallmounted.png" + and string.find(def.palette, "unifieddyes_palette_") then + palette = "split" + fdir = node.param2 % 32 + else + minetest.chat_send_player(player_name, "*** That node can't be colored -- it has an invalid color mode.") + return + end + + local idx, hue = unifieddyes.getpaletteidx(painting_with, palette) + local inv = player:get_inventory() + if (not creative or not creative.is_enabled_for(player_name)) and not inv:contains_item("main", painting_with) then + local suff = "" + if not idx then + suff = " Besides, "..string.sub(painting_with, 5).." can't be applied to that node." + end + minetest.chat_send_player(player_name, "*** You're in survival mode, and you're out of "..string.sub(painting_with, 5).."."..suff) + return + end + + if not idx then + minetest.chat_send_player(player_name, "*** "..string.sub(painting_with, 5).." can't be applied to that node.") + return + end + + local oldidx = node.param2 - fdir + local name = def.airbrush_replacement_node or node.name + + if palette == "split" then + + local modname = string.sub(name, 1, string.find(name, ":")-1) + local nodename2 = string.sub(name, string.find(name, ":")+1) + local oldcolor = "snozzberry" + local newcolor = "razzberry" -- intentionally misspelled ;-) + + if def.ud_color_start and def.ud_color_end then + oldcolor = string.sub(node.name, def.ud_color_start, def.ud_color_end) + newcolor = string.sub(painting_with, 5) + else + if hue ~= 0 then + newcolor = unifieddyes.HUES_EXTENDED[hue][1] + else + newcolor = "grey" + end + + if def.airbrush_replacement_node then + oldcolor = "grey" + else + local s = string.sub(def.palette, 21) + oldcolor = string.sub(s, 1, string.find(s, "s.png")-1) + end + end + + name = modname..":"..string.gsub(nodename2, oldcolor, newcolor) + + if not minetest.registered_items[name] then + minetest.chat_send_player(player_name, "*** "..string.sub(painting_with, 5).." can't be applied to that node.") + return + end + elseif idx == oldidx then + return + end + minetest.swap_node(pos, {name = name, param2 = fdir + idx}) + if not creative or not creative.is_enabled_for(player_name) then + inv:remove_item("main", painting_with) + return + end +end + +-- get a node's dye color based on its palette and param2 + +function unifieddyes.color_to_name(param2, def) + if not param2 or not def or not def.palette then return end + + if def.palette == "unifieddyes_palette_extended.png" then + local color = param2 + + local v = 0 + local s = 1 + if color < 24 then v = 1 + elseif color > 23 and color < 48 then v = 2 + elseif color > 47 and color < 72 then v = 3 + elseif color > 71 and color < 96 then v = 4 + elseif color > 95 and color < 120 then v = 5 + elseif color > 119 and color < 144 then v = 5 s = 2 + elseif color > 143 and color < 168 then v = 6 + elseif color > 167 and color < 192 then v = 6 s = 2 + elseif color > 191 and color < 216 then v = 7 + elseif color > 215 and color < 240 then v = 7 s = 2 + end + + if color > 239 then + if color == 240 then return "white" + elseif color == 244 then return "light_grey" + elseif color == 247 then return "grey" + elseif color == 251 then return "dark_grey" + elseif color == 255 then return "black" + else return "grey_"..15-(color-240) + end + else + local h = color - math.floor(color/24)*24 + return unifieddyes.VALS_EXTENDED[v]..unifieddyes.HUES_EXTENDED[h+1][1]..unifieddyes.SATS[s] + end + + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" then + local color = math.floor(param2 / 8) + if color == 0 then return "white" + elseif color == 1 then return "light_grey" + elseif color == 2 then return "grey" + elseif color == 3 then return "dark_grey" + elseif color == 4 then return "black" + elseif color == 5 then return "light_blue" + elseif color == 6 then return "light_green" + elseif color == 7 then return "pink" + end + local v = math.floor(color/8) + local h = color - v * 8 + return unifieddyes.VALS[v]..unifieddyes.HUES_WALLMOUNTED[h+1] + + elseif string.find(def.palette, "unifieddyes_palette") then -- it's the split palette + -- palette names in this mode are always "unifieddyes_palette_COLORs.png" + + local s = string.sub(def.palette, 21) + local color = string.sub(s, 1, string.find(s, "s.png")-1) + + local v = math.floor(param2/32) + if color ~= "grey" then + if v == 0 then return "faint_"..color + elseif v == 1 then return color + elseif v == 2 then return color.."_s50" + elseif v == 3 then return "light_"..color + elseif v == 4 then return "medium_"..color + elseif v == 5 then return "medium_"..color.."_s50" + elseif v == 6 then return "dark_"..color + elseif v == 7 then return "dark_"..color.."_s50" + end + else + if v > 0 and v < 6 then return unifieddyes.GREYS[v] + else return "white" + end + end + end +end + +local hps = 0.6 -- horizontal position scale +local vps = 1.3 -- vertical position scale +local vs = 0.1 -- vertical shift/offset + +local color_button_size = ";0.75,0.75;" +local color_square_size = ";0.69,0.69;" + +function unifieddyes.make_readable_color(color) + local s = string.gsub(color, "_", " ") + s = string.gsub(s, "s50", "(low saturation)") + return s +end + +function unifieddyes.make_colored_square(hexcolor, colorname, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + + local dye = "dye:"..colorname + + local overlay = "" + local colorize = minetest.formspec_escape("^[colorize:#"..hexcolor..":255") + + if not creative and inv:contains_item("main", dye) then + overlay = "^unifieddyes_onhand_overlay.png" + end + + local unavail_overlay = "" + if not showall and not unifieddyes.palette_has_color[nodepalette.."_"..colorname] + or (explist and not explist[colorname]) then + if overlay == "" then + unavail_overlay = "^unifieddyes_unavailable_overlay.png" + else + unavail_overlay = "^unifieddyes_onhand_unavailable_overlay.png" + end + end + + local tooltip = "tooltip["..colorname..";".. + unifieddyes.make_readable_color(colorname).. + "\n(dye:"..colorname..")]" + + if dye == painting_with then + overlay = "^unifieddyes_select_overlay.png" + selindic = "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay.."]"..tooltip + end + + local form + if unavail_overlay == "" then + form = "image_button[".. + (hp*hps)..","..(v2*vps+vs).. + color_button_size.. + "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay..";".. + colorname..";]".. + tooltip + else + form = "image[".. + (hp*hps)..","..(v2*vps+vs).. + color_square_size.. + "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay.."]".. + tooltip + end + + return form, selindic +end + +function unifieddyes.show_airbrush_form(player) + if not player then return end + + local t = {} + + local player_name = player:get_player_name() + local painting_with = unifieddyes.player_selected_dye[player_name] or unifieddyes.player_current_dye[player_name] + local creative = creative and creative.is_enabled_for(player_name) + local inv = player:get_inventory() + local nodepalette = "extended" + local showall = unifieddyes.player_showall[player_name] + + t[1] = "size[14.5,8.5]label[7,-0.3;Select a color:]" + local selindic = "unifieddyes_select_overlay.png^unifieddyes_question.png]" + + local last_right_click = unifieddyes.player_last_right_clicked[player_name] + if last_right_click then + if last_right_click.def and last_right_click.def.palette then + if last_right_click.def.palette == "unifieddyes_palette_colorwallmounted.png" then + nodepalette = "wallmounted" + elseif last_right_click.def.palette == "unifieddyes_palette_extended.png" then + t[#t+1] = "label[0.5,8.25;(Right-clicked a node that supports all 256 colors, showing them all)]" + showall = true + elseif last_right_click.def.palette ~= "unifieddyes_palette_extended.png" + and last_right_click.def.palette ~= "unifieddyes_palette_colorwallmounted.png" + and string.find(last_right_click.def.palette, "unifieddyes_palette_") then + nodepalette = "split" + end + end + end + + if not last_right_click.def.groups + or not last_right_click.def.groups.ud_param2_colorable + or not last_right_click.def.palette + or not string.find(last_right_click.def.palette, "unifieddyes_palette_") then + t[#t+1] = "label[0.5,8.25;(Right-clicked a node not supported by the Airbrush, showing all colors)]" + end + + local explist = last_right_click.def.explist + + for v = 0, 6 do + local val = unifieddyes.VALS_EXTENDED[v+1] + + local sat = "" + local v2=(v/2) + + for hi, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local hp=hi-1 + + local r = h[2] + local g = h[3] + local b = h[4] + + local factor = 40 + if v > 3 then + factor = 75 + v2 = (v-2) + end + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + local hexcolor = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) + local f + f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + end + + if v > 3 then + sat = "_s50" + v2 = (v-1.5) + + for hi, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local hp=hi-1 + + local r = h[2] + local g = h[3] + local b = h[4] + + local factor = 75 + + local pr = 0.299 + local pg = 0.587 + local pb = 0.114 + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + local p = math.sqrt(r2*r2*pr + g2*g2*pg + b2*b2*pb) + local r3 = math.floor(p+(r2-p)*0.5) + local g3 = math.floor(p+(g2-p)*0.5) + local b3 = math.floor(p+(b2-p)*0.5) + + local hexcolor = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3) + local f + f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + end + end + end + + local v2=5 + for y = 0, 15 do + + local hp=15-y + + local hexgrey = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) + local grey = "grey_"..y + + if y == 0 then grey = "black" + elseif y == 4 then grey = "dark_grey" + elseif y == 8 then grey = "grey" + elseif y == 11 then grey = "light_grey" + elseif y == 15 then grey = "white" + end + + local f + f, selindic = unifieddyes.make_colored_square(hexgrey, grey, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + + end + + if not creative then + t[#t+1] = "image[10," + t[#t+1] = (vps*5.55+vs) + t[#t+1] = color_button_size + t[#t+1] = "unifieddyes_onhand_overlay.png]label[10.7," + t[#t+1] = (vps*5.51+vs) + t[#t+1] = ";Dyes]" + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.67+vs) + t[#t+1] = ";on hand]" + + end + + t[#t+1] = "image[10," + t[#t+1] = (vps*5+vs) + t[#t+1] = color_button_size + t[#t+1] = selindic + + if painting_with then + t[#t+1] = "label[10.7," + t[#t+1] = (vps*4.90+vs) + t[#t+1] = ";Your selection:]" + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.07+vs) + t[#t+1] = ";" + t[#t+1] = unifieddyes.make_readable_color(string.sub(painting_with, 5)) + t[#t+1] = "]label[10.7," + t[#t+1] = (vps*5.24+vs) + t[#t+1] = ";(" + t[#t+1] = painting_with + t[#t+1] = ")]" + else + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.07+vs) + t[#t+1] = ";Your selection]" + end + + t[#t+1] = "button_exit[10.5,8;2,1;cancel;Cancel]button_exit[12.5,8;2,1;accept;Accept]" + + + if last_right_click and last_right_click.def and nodepalette ~= "extended" then + if showall then + t[#t+1] = "button[0,8;2,1;show_avail;Show Available]" + t[#t+1] = "label[2,8.25;(Currently showing all 256 colors)]" + else + t[#t+1] = "button[0,8;2,1;show_all;Show All Colors]" + t[#t+1] = "label[2,8.25;(Currently only showing what the right-clicked node can use)]" + end + end + + minetest.show_formspec(player_name, "unifieddyes:dye_select_form", table.concat(t)) +end + +minetest.register_tool("unifieddyes:airbrush", { + description = S("Dye Airbrush"), + inventory_image = "unifieddyes_airbrush.png", + use_texture_alpha = true, + tool_capabilities = { + full_punch_interval=0.1, + }, + range = 12, + on_use = unifieddyes.on_airbrush, + on_place = function(itemstack, placer, pointed_thing) + local keys = placer:get_player_control() + local player_name = placer:get_player_name() + local pos = minetest.get_pointed_thing_position(pointed_thing) + local node + local def + + if pos then node = minetest.get_node(pos) end + if node then def = minetest.registered_items[node.name] end + + unifieddyes.player_last_right_clicked[player_name] = {pos = pos, node = node, def = def} + + if not keys.sneak then + unifieddyes.show_airbrush_form(placer) + elseif keys.sneak then + + if not pos or not def then return end + local newcolor = unifieddyes.color_to_name(node.param2, def) + + if not newcolor then + minetest.chat_send_player(player_name, "*** That node is uncolored.") + return + end + minetest.chat_send_player(player_name, "*** Switching to "..newcolor.." for the airbrush, to match that node.") + unifieddyes.player_current_dye[player_name] = "dye:"..newcolor + end + end +}) + +minetest.register_craft( { + output = "unifieddyes:airbrush", + recipe = { + { "basic_materials:brass_ingot", "", "basic_materials:plastic_sheet" }, + { "", "default:steel_ingot", "" }, + { "", "", "default:steel_ingot" } + }, +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if formname == "unifieddyes:dye_select_form" then + + local player_name = player:get_player_name() + local nodepalette = "extended" + local showall = unifieddyes.player_showall[player_name] + + local last_right_click = unifieddyes.player_last_right_clicked[player_name] + if last_right_click and last_right_click.def then + if last_right_click.def.palette then + if last_right_click.def.palette == "unifieddyes_palette_colorwallmounted.png" then + nodepalette = "wallmounted" + elseif last_right_click.def.palette ~= "unifieddyes_palette_extended.png" then + nodepalette = "split" + end + end + end + + if fields.show_all then + unifieddyes.player_showall[player_name] = true + unifieddyes.show_airbrush_form(player) + return + elseif fields.show_avail then + unifieddyes.player_showall[player_name] = false + unifieddyes.show_airbrush_form(player) + return + elseif fields.quit then + if fields.accept then + local dye = unifieddyes.player_selected_dye[player_name] + if not dye then + minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but no color was selected!") + return + elseif not showall + and not unifieddyes.palette_has_color[nodepalette.."_"..string.sub(dye, 5)] then + minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but the selected color can't be used on the") + minetest.chat_send_player(player_name, "*** node that was right-clicked (and \"Show All\" wasn't in effect).") + if unifieddyes.player_current_dye[player_name] then + minetest.chat_send_player(player_name, "*** Ignoring it and sticking with "..string.sub(unifieddyes.player_current_dye[player_name], 5)..".") + else + minetest.chat_send_player(player_name, "*** Ignoring it.") + end + return + else + unifieddyes.player_current_dye[player_name] = dye + unifieddyes.player_selected_dye[player_name] = nil + minetest.chat_send_player(player_name, "*** Selected "..string.sub(dye, 5).." for the airbrush.") + return + end + else -- assume "Cancel" or Esc. + unifieddyes.player_selected_dye[player_name] = nil + return + end + else + local s1 = string.sub(minetest.serialize(fields), 11) + local s3 = string.sub(s1,1, string.find(s1, '"')-1) + + local inv = player:get_inventory() + local creative = creative and creative.is_enabled_for(player_name) + local dye = "dye:"..s3 + + if (showall or unifieddyes.palette_has_color[nodepalette.."_"..s3]) and + (minetest.registered_items[dye] and (creative or inv:contains_item("main", dye))) then + unifieddyes.player_selected_dye[player_name] = dye + unifieddyes.show_airbrush_form(player) + end + end + end +end) + +-- Generate all dyes that are not part of the default minetest_game dyes mod + +for _, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local r = h[2] + local g = h[3] + local b = h[4] + + for v = 0, 6 do + local val = unifieddyes.VALS_EXTENDED[v+1] + + local factor = 40 + if v > 3 then factor = 75 end + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + -- full-sat color + + local desc = hue:gsub("%a", string.upper, 1).." Dye" + + if val ~= "" then + desc = val:sub(1, -2):gsub("%a", string.upper, 1) .." "..desc + end + + local color = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) + if minetest.registered_items["dye:"..val..hue] then + minetest.override_item("dye:"..val..hue, { + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", + }) + else + if (val..hue) ~= "medium_orange" + and (val..hue) ~= "light_red" then + minetest.register_craftitem(":dye:"..val..hue, { + description = S(desc), + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + end + end + minetest.register_alias("unifieddyes:"..val..hue, "dye:"..val..hue) + + if v > 3 then -- also register the low-sat version + + local pr = 0.299 + local pg = 0.587 + local pb = 0.114 + + local p = math.sqrt(r2*r2*pr + g2*g2*pg + b2*b2*pb) + local r3 = math.floor(p+(r2-p)*0.5) + local g3 = math.floor(p+(g2-p)*0.5) + local b3 = math.floor(p+(b2-p)*0.5) + + local color = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3) + + minetest.register_craftitem(":dye:"..val..hue.."_s50", { + description = S(desc.." (low saturation)"), + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..val..hue.."_s50", "dye:"..val..hue.."_s50") + end + end +end + +-- register the greyscales too :P + +for y = 1, 14 do -- colors 0 and 15 are black and white, default dyes + + if y ~= 4 and y ~= 8 and y~= 11 then -- don't register the three greys, they're done separately. + + local rgb = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) + local name = "grey_"..y + local desc = "Grey Dye #"..y + + minetest.register_craftitem(":dye:"..name, { + description = S(desc), + inventory_image = "unifieddyes_dye.png^[colorize:#"..rgb..":200", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..name, "dye:"..name) + end +end + +minetest.override_item("dye:grey", { + inventory_image = "unifieddyes_dye.png^[colorize:#888888:200", +}) + +minetest.override_item("dye:dark_grey", { + inventory_image = "unifieddyes_dye.png^[colorize:#444444:200", +}) + +minetest.register_craftitem(":dye:light_grey", { + description = S("Light grey Dye"), + inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:200", + groups = { dye=1, not_in_creative_inventory=1 }, +}) + +-- build a table of color <-> palette associations to reduce the need for +-- realtime lookups with getpaletteidx() + +for _, palette in ipairs({"extended", "split", "wallmounted"}) do + local palette2 = palette + + for i in ipairs(unifieddyes.SATS) do + local sat = (palette == "wallmounted") and "" or unifieddyes.SATS[i] + for _, hue in ipairs(unifieddyes.HUES_EXTENDED) do + for _, val in ipairs(unifieddyes.VALS_EXTENDED) do + local color = val..hue[1]..sat + if unifieddyes.getpaletteidx("dye:"..color, palette2) then + unifieddyes.palette_has_color[palette.."_"..color] = true + end + end + end + end + + for y = 0, 15 do + local grey = "grey_"..y + + if y == 0 then grey = "black" + elseif y == 4 then grey = "dark_grey" + elseif y == 8 then grey = "grey" + elseif y == 11 then grey = "light_grey" + elseif y == 15 then grey = "white" + end + if unifieddyes.getpaletteidx("dye:"..grey, palette2) then + unifieddyes.palette_has_color[palette.."_"..grey] = true + end + end +end + +unifieddyes.palette_has_color["wallmounted_light_red"] = true + +-- crafting! + +unifieddyes.base_color_crafts = { + { "red", "flowers:rose", nil, nil, nil, nil, 4 }, + { "vermilion", "dye:red", "dye:orange", nil, nil, nil, 3 }, + { "orange", "flowers:tulip", nil, nil, nil, nil, 4 }, + { "orange", "dye:red", "dye:yellow", nil, nil, nil, 2 }, + { "amber", "dye:orange", "dye:yellow", nil, nil, nil, 2 }, + { "yellow", "flowers:dandelion_yellow", nil, nil, nil, nil, 4 }, + { "lime", "dye:yellow", "dye:chartreuse", nil, nil, nil, 2 }, + { "lime", "dye:yellow", "dye:yellow", "dye:green", nil, nil, 3 }, + { "chartreuse", "dye:yellow", "dye:green", nil, nil, nil, 2 }, + { "harlequin", "dye:chartreuse", "dye:green", nil, nil, nil, 2 }, + { "harlequin", "dye:yellow", "dye:green", "dye:green", nil, nil, 3 }, + { "green", "default:cactus", nil, nil, nil, nil, 4 }, + { "green", "dye:yellow", "dye:blue", nil, nil, nil, 2 }, + { "malachite", "dye:green", "dye:spring", nil, nil, nil, 2 }, + { "malachite", "dye:green", "dye:green", "dye:cyan", nil, nil, 3 }, + { "malachite", "dye:green", "dye:green", "dye:green", "dye:blue", nil, 4 }, + { "spring", "dye:green", "dye:cyan", nil, nil, nil, 2 }, + { "spring", "dye:green", "dye:green", "dye:blue", nil, nil, 3 }, + { "turquoise", "dye:spring", "dye:cyan", nil, nil, nil, 2 }, + { "turquoise", "dye:green", "dye:cyan", "dye:cyan", nil, nil, 3 }, + { "turquoise", "dye:green", "dye:green", "dye:green", "dye:blue", "dye:blue", 5 }, + { "cyan", "dye:green", "dye:blue", nil, nil, nil, 2 }, + { "cerulean", "dye:cyan", "dye:azure", nil, nil, nil, 2 }, + { "cerulean", "dye:cyan", "dye:cyan", "dye:blue", nil, nil, 3 }, + { "cerulean", "dye:green", "dye:green", "dye:blue", "dye:blue", "dye:blue", 5 }, + { "azure", "dye:cyan", "dye:blue", nil, nil, nil, 2 }, + { "azure", "dye:green", "dye:blue", "dye:blue", nil, nil, 3 }, + { "sapphire", "dye:azure", "dye:blue", nil, nil, nil, 2 }, + { "sapphire", "dye:cyan", "dye:blue", "dye:blue", nil, nil, 3 }, + { "sapphire", "dye:green", "dye:blue", "dye:blue", "dye:blue", nil, 4 }, + { "blue", "flowers:geranium", nil, nil, nil, nil, 4 }, + { "indigo", "dye:blue", "dye:violet", nil, nil, nil, 2 }, + { "violet", "flowers:viola", nil, nil, nil, nil, 4 }, + { "violet", "dye:blue", "dye:magenta", nil, nil, nil, 2 }, + { "mulberry", "dye:violet", "dye:magenta", nil, nil, nil, 2 }, + { "mulberry", "dye:violet", "dye:blue", "dye:red", nil, nil, 3 }, + { "magenta", "dye:blue", "dye:red", nil, nil, nil, 2 }, + { "fuchsia", "dye:magenta", "dye:rose", nil, nil, nil, 2 }, + { "fuchsia", "dye:blue", "dye:red", "dye:rose", nil, nil, 3 }, + { "fuchsia", "dye:red", "dye:violet", nil, nil, nil, 2 }, + { "rose", "dye:magenta", "dye:red", nil, nil, nil, 2 }, + { "rose", "dye:red", "dye:red", "dye:blue", nil, nil, 3 }, + { "crimson", "dye:rose", "dye:red", nil, nil, nil, 2 }, + { "crimson", "dye:magenta", "dye:red", "dye:red", nil, nil, 3 }, + { "crimson", "dye:red", "dye:red", "dye:red", "dye:blue", nil, 4 }, + + { "black", "default:coal_lump", nil, nil, nil, nil, 4 }, + { "white", "flowers:dandelion_white", nil, nil, nil, nil, 4 }, +} + +unifieddyes.shade_crafts = { + { "faint_", "", "dye:white", "dye:white", "dye:white", 4 }, + { "pastel_", "", "dye:white", "dye:white", nil, 3 }, + { "light_", "", "dye:white", nil, nil, 2 }, + { "bright_", "", "color", "dye:white", nil, 3 }, + { "", "_s50", "dye:light_grey", nil, nil, 2 }, + { "", "_s50", "dye:black", "dye:white", "dye:white", 3 }, + { "medium_", "", "dye:black", nil, nil, 2 }, + { "medium_", "_s50", "dye:grey", nil, nil, 2 }, + { "medium_", "_s50", "dye:black", "dye:white", nil, 3 }, + { "dark_", "", "dye:black", "dye:black", nil, 3 }, + { "dark_", "_s50", "dye:dark_grey", nil, nil, 2 }, + { "dark_", "_s50", "dye:black", "dye:black", "dye:white", 4 }, +} + +for _,i in ipairs(unifieddyes.base_color_crafts) do + local color = i[1] + local yield = i[7] + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..color.." "..yield, + recipe = { + i[2], + i[3], + i[4], + i[5], + i[6], + }, + }) + + for _,j in ipairs(unifieddyes.shade_crafts) do + local firstdye = j[3] + if firstdye == "color" then firstdye = "dye:"..color end + + -- ignore black, white, anything containing the word "grey" + + if color ~= "black" and color ~= "white" and not string.find(color, "grey") then + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..j[1]..color..j[2].." "..j[6], + recipe = { + "dye:"..color, + firstdye, + j[4], + j[5] + }, + }) + end + end +end + +-- greys + +unifieddyes.greymixes = { + { 1, "dye:black", "dye:black", "dye:black", "dye:dark_grey", 4 }, + { 2, "dye:black", "dye:black", "dye:dark_grey", nil, 3 }, + { 3, "dye:black", "dye:dark_grey", nil, nil, 2 }, + { 4, "dye:white", "dye:black", "dye:black", nil, 3 }, + { 5, "dye:dark_grey", "dye:dark_grey", "dye:grey", nil, 3 }, + { 6, "dye:dark_grey", "dye:grey", nil, nil, 2 }, + { 7, "dye:dark_grey", "dye:grey", "dye:grey", nil, 3 }, + { 8, "dye:white", "dye:black", nil, nil, 2 }, + { 9, "dye:grey", "dye:grey", "dye:light_grey", nil, 3 }, + { 10, "dye:grey", "dye:light_grey", "dye:light_grey", nil, 3 }, + { 11, "dye:white", "dye:white", "dye:black", nil, 3 }, + { 12, "dye:light_grey", "dye:light_grey", "dye:white", nil, 3 }, + { 13, "dye:light_grey", "dye:white", nil, nil, 2 }, + { 14, "dye:white", "dye:white", "dye:light_grey", nil, 3 }, +} + +for _, i in ipairs(unifieddyes.greymixes) do + local shade = i[1] + local dye1 = i[2] + local dye2 = i[3] + local dye3 = i[4] + local dye4 = i[5] + local yield = i[6] + local color = "grey_"..shade + if shade == 4 then + color = "dark_grey" + elseif shade == 8 then + color = "grey" + elseif shade == 11 then + color = "light_grey" + end + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..color.." "..yield, + recipe = { + dye1, + dye2, + dye3, + dye4, + }, + }) +end + +-- we can't make dark orange anymore because brown/medium orange conflicts + +minetest.register_craft( { + type = "shapeless", + output = "dye:dark_orange", + recipe = { + "dye:brown", + "dye:brown" + }, +}) + +-- aliases + +minetest.register_alias("dye:light_red", "dye:pink") +minetest.register_alias("dye:medium_orange", "dye:brown") + +minetest.register_alias("unifieddyes:black", "dye:black") +minetest.register_alias("unifieddyes:dark_grey", "dye:dark_grey") +minetest.register_alias("unifieddyes:grey", "dye:grey") +minetest.register_alias("unifieddyes:light_grey", "dye:light_grey") +minetest.register_alias("unifieddyes:white", "dye:white") + +minetest.register_alias("unifieddyes:grey_0", "dye:black") +minetest.register_alias("unifieddyes:grey_4", "dye:dark_grey") +minetest.register_alias("unifieddyes:grey_8", "dye:grey") +minetest.register_alias("unifieddyes:grey_11", "dye:light_grey") +minetest.register_alias("unifieddyes:grey_15", "dye:white") + +minetest.register_alias("unifieddyes:white_paint", "dye:white") +minetest.register_alias("unifieddyes:titanium_dioxide", "dye:white") +minetest.register_alias("unifieddyes:lightgrey_paint", "dye:light_grey") +minetest.register_alias("unifieddyes:grey_paint", "dye:grey") +minetest.register_alias("unifieddyes:darkgrey_paint", "dye:dark_grey") +minetest.register_alias("unifieddyes:carbon_black", "dye:black") + +minetest.register_alias("unifieddyes:brown", "dye:brown") + +print(S("[UnifiedDyes] Loaded!")) + diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/oldcoder.txt b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/oldcoder.txt new file mode 100644 index 0000000..64882f8 --- /dev/null +++ b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/oldcoder.txt @@ -0,0 +1,17 @@ +Name: unifieddyes +Source: Slightly modified upstream mod +License: See "README.txt" + +---------------------------------------------------------------------- + +1. This is a slightly modified version of an upstream mod. The start- +ing point was obtained originally as follows: + + rm -fr unifieddyes + git clone https://gitlab.com/VanessaE/unifieddyes.git + +---------------------------------------------------------------------- + +2. Changes include: + +2a. Added the files "00README" and "oldcoder.txt" (this file). diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/textures/unifieddyes_dye.png b/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/textures/unifieddyes_dye.png new file mode 100644 index 0000000000000000000000000000000000000000..ee792e54ebae0a7bc4d9b59f94f7359e9426ef88 GIT binary patch literal 150 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`v7RoDAr`0KPB7#m_ocZwGV=e}3_Sx$Ul#f?^l*xNOAxuYZp~HEgMGT& +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_black.png b/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_black.png new file mode 100644 index 0000000000000000000000000000000000000000..3fae20e916f87d290413a75dd5b6b2bef5198c70 GIT binary patch literal 1122 zcmZ`%YfPJE6h7ajrL<5!=)LQm_UoN~z0p$IwH>{V6$%tZH&~$z1TiqvB{CT)j32rz zoBr4&YOQ#~94$=JDLt4NXK(M%NJ!;`$fhgsENA=R4!I7|bSmH?h0 zSLs)PLkz(EJV0O>Kr-|8Cp|#`T%FyMi=%{~p4?^$A14SxC={Chr9Lk=W#@F5*#rJM zl#pR+`dfL!JDWx$Lgabc$3rsf=C*1Gn-sR$r^UAomkKjUz^ehP6thZzQGiPYdLfu4 zU=mk3W+B@3gq*@zB+g>7D2meQbcsa5?RNWU3Oy9Fu){P<*$5bhH8eEv`FychtWYRi zE>|EB2!%ophogfL^|#gywo?gfjZKcxB9QT+j>i=U1QLlvE|+VyTC>^gbUOWhzt88h znvH&oIA~z+ZmBIq1qcx>2Au$SY(S{hYPC|SM9{t|;_8n=zdLSyB?vl+9X^s|}4`vnJOs!)FxYZCc z;BgC?b#b0;phB*l{{$#l2uV2^xmpJs7HH$SL-=_%DjTGZ#}cDAr1H0jZRUx$Yb z#4Zz=WjHwxH^Xq^W>%Oc?Xv1bylSkynFur!NgLT=CR^m-RzaH%cPgP(i=i29ZEYpi zY#$-arebebA5b%;Dn(|>l@i00%aKT>TrO3ZQkg1OB9*>MWritLN}RjB)eXf)I+L+W zvD(R>(50rB&cti()=)tDE?vGULgBh}ESmG*EaauE@37-0g=u4X5qqXUdO$T4lIL-7?&ZwAr08LCY4O&lZ|Hy7+$sL+(S!0eL;RUj?=Pqy$W-sJFXIKr z!@Z{Njqg3HSC?OZcjd+pyfLAB^E3CG$G-u%&T0R4eE#ZNs8xnye4scwTs#mcym$a9 za4{~Yo$=Y7tvQAXFrI+dYpoj0=@aM2|5Nb7^ytLc?Ee?sTWk6e6+k-P75iXUe(@g; C?I1@0 literal 0 HcmV?d00001 diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_blue.png b/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..50b34421cb9caa1ee792503c52171e7482023e87 GIT binary patch literal 1135 zcmZ`%ZA_b06h3eJzWsO$ZK2<#v@b2~`UQRa36ugY{T?f{rDbe`1!w_r8W`5>!wtK^ zk8Ki-Su`_Q)F^SrA9gicW=tGoCS+!dGhs#(F^h3VW1@BO#|SgxZTRI6Z=QS3x#ylI z_dfUB^U3~bEvX~{pf(;0rIDwqlfy(dv~pn`Iea>h2mq8{yX*6QG0N<3;~_g>=XxlnRSvsoYhvsM4mDZ~55 z{ZJQwDk2J-Surb)ZZ6_AvWywNeT3I~pvHDk=ABRmp3y{(r~}ir^dY2lDk?fXs&O`A z5ex37FqKfi)TcP+A!+-#!k1I{r!@ofMyqWsC|b-J3KGE}X(;>rbzhdDqwV2Z#O{xZHuB`!_8tBq9!e%__;2iAWqwdT^ zrO(D>vjd8wDdnjV>genS+AhPx$v6>03ws8S~=oTHe!JD$im{h0iN_1K#i++wW!No?XD z+_>FalMEhHyyDN~&pc9GS|hja&wP2cTrPi7c3c*I``!GL--$&HaZgi6cK`ME#n+!c z9e%V?T1{WcO59&X7p#-Vmy{34<&C!<_MW(XKkq(S)fRcpLukFK^C0=iGD8 z$vwYw&V477iq&(PIRJqAL_E@uq@uRjIO37>$JdY`#ygXp09<*O`*@U9yUfS?lK{M? z0iZMsz~9JJdH}%73;@540N_0hfMn|IXMKJEFm0wc8$}L&HL*hmKB*!|vkV3p648Kz z6K`jSb>xtnha8d&m2+}OJ9dqQM9A`ti;H;LQs-3Q#wM^sE+w|3SmjVF0S*N)G(m#| zFfw431GNa~BtR>!5z-@iJfOyn0+MEtYBp(T#63E4G;U0Ig#jIj-iqkSpoXPuz?C?q z7vYQ?+SOQpXUkw%5q0rJ5l}CKiHLhzZ{qZnd?*ZUf;^Koys;(a@#E!;box zTafE&4H{S@Vd1g7rkItX5?N$0q9eRChAL)LLc0n&)X<|NLMCq1!W;1Ohr^pltrY~?u&AEMSlN3#eAI}EnD~XbWHK#1*w=jIImOZas_9|n;X(OC zqH(~+=`oQZ4PjRRw+aii;ayrH!?3eX#q|pM9tdX-oD!Pg#pcquGpU%0D`GfZH1=F)e^&$%b`%U{CTO$l*)o~HB=p_ zR;QR!wG>*HUilsc!Tmk4$S3Q-H;xWeF_DZ?zfuA~xYeAyXh(90VWB+#k-QuAV>zYAZ&Eiesb2 z1K#|h14sZXW3{w1u6Bzv%P?NX?sYf~HHEoQxLo_-{{_4_IW|#v_5TCz`q zN0va;YC?>QWQoBTqG&^+iJL!$%plp8%tZa;qM0GfjESj>al-|Ix8avRym{_9=bn#y z?{m*x42OKhEHMiJiUWRk57LUlByl9&A1-YpMVxI7wgPNq+57$ULNMv?2?9*205S^z z&yXwg8^A>h;P(W8?L7d&*vgHF9e`#Ccf~v?!Cp-qLCRw?IVGU6LNtL8HM9JBvR%VC zVdbENAjRypu=`t%rCfaEd7+VwWVfNnqQG@RI6`A3?Z`07Ftq^83eXBMtpF$~7-dk+ z2aN#K<$MO4!)9>#xKanfG1s^9_Y+9ubmuo<8 z2U`FJ(=f3BuP;I3yvbG9YvIJ3xn3<(C&pA|AmQQ+kpinVL%jnmZio#)>H@r)f$Wh-CJj6&<4pls?l*1^nb_T&01A9k-{z4W;CSdrIxW)RCqh!#_^VBi? zIs#prBuQ|EAaWWyUxeUE7`X&5PeP~<5ghdKrsML43e2k|%nGc$gaDf#+9MD@2gz}m zUQ{;e6YaeDq$(YgqK7g_F}H@WDQTukhFo1C)+xpMYOzrxZZ?WNcDdhS4mO9nYDYt& znNy1Sq;fng?WT&Jmq3FY95pmg9T7H?C!0!8M}~dnBYweXw`e>fp6XM~4OGpJ5+=Xbo$&kRyTYmYja=_U5v5YCfzOd5-_( zM+f9kQJC17QBK}o8JGE&=C^DoEl zqhEg{{j|5gGSX7l0beyMlhv!#PU%+e!Fg`3?Fr~y9j7;giAk;Q8!)GH zv!vT2^Iw}4t!EDBu5ct0iB_V$6^Oj~$J1Z#{=FaB+Asa!K|`LdxqdV2X*qbNHQx%I znttuxw;fk}YptJdTCe`2U#^`xN863x-Jvm_q)2V{@%E6>i^KiZrsFaJc^SP@P11{%ZQt1Tl{0wY0Tm)S~E?CisEhf%RfB%-E+=8_nh4O zJLk?P+oFY}k_3Rlcr4V3tTw-RETluPo!ml(7!4+Z0BffNy94a}VLH~C0C=1R$j$=% zi9*@$0gf^NKlTIo&j3&pXD@ct0pNjTYj+qW)ES6nwi%uInt3pP1sqkvI^s}u|p zuux!@<$?T=l~rqCDMdKJ##kglY6O%|-gKy%j?->?A-XGMwr?}3IIm>9`>CJqDg*4g( z7N*GVmAGo8O-;&FR5sqGm^z}JN$V$*>UM_jP=UJ)>Wz5VN+eypLp4G)ps}dz;TSdE zu9)mlK6zL>J*b=ND?ip#Iu@69xyhDFPJkw=v{0?X>y4}fW+KV(x~s?p!wXy3jWl6b zeIbQ5+)O+X=HBCq zfbhNZ?zR+#{)mTy-PPOaemVOlwqRD9cTS`*)2nr@*tdzu*7X%~N1l>*T&~%A5F=;h zh1$(Bwy0US9yE)N0(tn>@s*7$JPCIG?i@Z}qqWH1o`$6(k8(IuOV|Et4h(CbKeM+f zh4-h+viI>*?48P=SogmA4dZiW`GH@a>s>Mt3i;2$*LgGZ2Pb@UU+A9znU?MNnr1$f z$_BH_i`%`#D>|{^`bI&|#?w75&nzx3E-x;BGyC4w=?}&o^4%+=|I8(Sec{0y3wQ2* zqI+rT?`8j+=T;^g?x*=5>u>BokV0T<(P+8LkSi9RUfXR7=jk1g*or=LAH`k#VF#)rm6 Xj{kqbcQ;CIqXLMB+d^+0=%4-<-f1Hu literal 0 HcmV?d00001 diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_grey.png b/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..b7dcd1360a9d259e129501699999188a7440fea7 GIT binary patch literal 1102 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 b%}>cptHiD0`DLNoKn)C@u6{1-oD!M<>Z2$K literal 0 HcmV?d00001 diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_grey.png b/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..d7e7597ac7ba9bc72d4774e436f257b72d03e177 GIT binary patch literal 1102 zcmZ`%dq|sC6hB|`8Dng^phjbw#+YdG<)vQ|lW1bh>&yG0=4G7KCPu9aL+vtLN880m z3l7;BWut{b_mC|Nw#>58u~GJbI!iYkOvYH*R%!QO57JU-WK`VE{A+*ga_%{YbI*@^ ze&?K(zOaYQ;>M32eka)ZI3 z*Xu17i^JhaBoZSdBdJs>8jbe%NaBV=!)A_KS*hYrOe(B%yWNpU#AA}BoV80C zX*MQ6J<$j-N{*W(G^3bd(KMMg%@&=+Zj`yZRRODd$gfTN#WUf?vm>IVjAX7)&`Vae z9|2txSXyZ=1>UD+KHha0b$-fIKkaRp>1~|r=bt_%S{xOh9d3R)A)NAYqdHcgjbW4G z9U|xy(=4rY2Z8sI%vc92L^56S3ab=XHUPj_$g`1f6gacF^0CbpiaC-j6l}I);gejE%oR9=qOBM$7H7#^F=zXs zas6uq!bSrg>dHIQTWIy5GV2SuDu1rz0B(H$gPU9w+VfHNSm(`5idV6Xtr7xacOj0+ z-slcucS7!stvqX&7w7eV*0oXcvX*)5PhY>x+r8}5X&rx>9x-0CZPydC&IcKz%Psbml^1syr6;EzTo9GW{d3CO>9M zyXQ~3H`oiD=9c+~*A|tWcE>{q#{a7RkQ*#6FY{hKFZ{M_z&QTnX##fQ~wY6^_!Yo2mn4;n0nWdTKosyNjJU# literal 0 HcmV?d00001 diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_magenta.png b/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_magenta.png new file mode 100644 index 0000000000000000000000000000000000000000..f98182b595ed7bca598ed2f53be9f74c7cbcb099 GIT binary patch literal 1134 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 Pk0=3J{q4SwJhAk@pGPaT literal 0 HcmV?d00001 diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_red.png b/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_red.png new file mode 100644 index 0000000000000000000000000000000000000000..e83dff03361e3c13f031449f405ec9966a23be43 GIT binary patch literal 1146 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 Y|4=ac|A4!#R1*XMtFhaV>hR3`4Vt4>egFUf literal 0 HcmV?d00001 diff --git a/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_yellow.png b/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..fb0dbc8097871bb06512d00fa83ab0eb58c11502 GIT binary patch literal 1139 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+081Cv#NPlzi}fsG0a1UZ>V zdOE45rOJ1-%K%ZZDVK*XhqESIgar>!fv*93s2O*noluH{2v8*4oEu2`8*-W{FzZM# zK#;j26NF(T$EYFBV5-2NEy1WQ&R`(JU?j(&BEq04&Y&R%LO`~Q7PEsotD}*)yPdMH zyGneFVokN|+^NRXCd-Aoa0Bgf(PFb#V>Q>{cXv>Wi&l(@RLsnfFDaIrF->~TbmiI8 z)F(}lO%E0fHRFl37I4#M*O6jW6J^j-TAF2m-b`~Bu8oy9 zmSuF)W-(P@G}RO?E|RORlAYKuGi{3Wl!@}Qr>P}{2qicRHz%u=gvbCx%ut5WMU%x! znaN6(CCE)M*n>aBlRw;-KR%Q%BbF~Wfxj|cvLI3{-%qkGPN6wjxiCP+-+)tJn!#9} z!B&;YRf{FSh$G694;VF>?qXRU;`#oPg@IBvF$zsdN_DY{6=8Cjo}$6VT;6(Y4r(kW z3JexXOtz}bP8uu$1{@(KT)qYzu9~d&YAm{vpvW?nXS7ykwo+zx*I{wiWYLpiFqUJm zRAMreWiV4@1V-Qg|NjLxZN^$rg2*Y9t5Z_uz_ zVEucC_rdSq7Z^0WZ*aIPx$y!}6JwIMyUSkNtCuQ)9QG1VUsv|0>;eod=3BO&76nQ( zdb&78pF=hiyY^DNKM$nd{duCE$-l5g}ClF zj1dhYdmCmS_!1V;!IVdM^e%6_U%phuz12x zWv7Gb_lhqS)ysF+{Q4UHYRjrc$9|sZPvz+kXpU+ul=>X4;r}B{|8eY@6HIL1OgOY> ze>|39gTe~DWM4f<0(m9 literal 0 HcmV?d00001 diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114-alternative-multiply.patch b/Bucket_Game-branches/dye-redrawn-vs-220114-alternative-multiply.patch new file mode 100644 index 0000000..8ce3fab --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114-alternative-multiply.patch @@ -0,0 +1,66 @@ +--- /home/owner/minetest/games/bucket_game/mods/coderbuild/unifieddyes/init.lua 2022-02-02 15:50:11.886988899 -0500 ++++ /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua 2022-02-02 17:17:40.290915016 -0500 +@@ -640,7 +640,7 @@ + if not item then return end + local inv_image = item.inventory_image + if not inv_image then return end +- return string.match(inv_image,"colorize:#(......):128") ++ return string.match(inv_image,"multiply:#(......)") + end + + -- punch-to-recolor using the airbrush +@@ -1232,14 +1232,14 @@ + local color = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) + if minetest.registered_items["dye:"..val..hue] then + minetest.override_item("dye:"..val..hue, { +- inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", ++ inventory_image = "unifieddyes_dye.png^[multiply:#"..color, + }) + else + if (val..hue) ~= "medium_orange" + and (val..hue) ~= "light_red" then + minetest.register_craftitem(":dye:"..val..hue, { + description = S(desc), +- inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", ++ inventory_image = "unifieddyes_dye.png^[multiply:#"..color, + groups = { dye=1, not_in_creative_inventory=1 }, + }) + end +@@ -1261,7 +1261,7 @@ + + minetest.register_craftitem(":dye:"..val..hue.."_s50", { + description = S(desc.." (low saturation)"), +- inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", ++ inventory_image = "unifieddyes_dye.png^[multiply:#"..color, + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..val..hue.."_s50", "dye:"..val..hue.."_s50") +@@ -1281,7 +1281,7 @@ + + minetest.register_craftitem(":dye:"..name, { + description = S(desc), +- inventory_image = "unifieddyes_dye.png^[colorize:#"..rgb..":128", ++ inventory_image = "unifieddyes_dye.png^[multiply:#"..rgb, + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..name, "dye:"..name) +@@ -1289,16 +1289,16 @@ + end + + minetest.override_item("dye:grey", { +- inventory_image = "unifieddyes_dye.png^[colorize:#888888:128", ++ inventory_image = "unifieddyes_dye.png^[multiply:#888888", + }) + + minetest.override_item("dye:dark_grey", { +- inventory_image = "unifieddyes_dye.png^[colorize:#444444:128", ++ inventory_image = "unifieddyes_dye.png^[multiply:#444444", + }) + + minetest.register_craftitem(":dye:light_grey", { + description = S("Light grey Dye"), +- inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:128", ++ inventory_image = "unifieddyes_dye.png^[multiply:#cccccc", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114.md b/Bucket_Game-branches/dye-redrawn-vs-220114.md new file mode 100644 index 0000000..d493393 --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114.md @@ -0,0 +1,12 @@ +After editing /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/./mods/codercore/dye/textures/dye_red.png, then create a patch by running: +diff -u /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/./mods/codercore/dye/textures/dye_red.png /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/./mods/codercore/dye/textures/dye_red.png > /home/owner/git/EnlivenMinetest/dye-redrawn-vs-220114.patch + +* getting parent of /home/owner/minetest/bucket_game-211114a/./mods/codercore/dye/textures/dye_red.png... +* updating /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/./mods/codercore/dye/textures/dye_red.png +* creating /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/./mods/codercore/dye/textures/dye_red.png +* updating LICENSE '/home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/./mods/codercore/dye/license.txt'... + +To apply, set BUCKET_GAME then: +``` +cd EnlivenMinetest && git pull && rsync -rt Bucket_Game-branches/dye-redrawn-vs-220114/ $BUCKET_GAME +``` diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114.patch b/Bucket_Game-branches/dye-redrawn-vs-220114.patch new file mode 100644 index 0000000..3db9c0a --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114.patch @@ -0,0 +1,176 @@ +diff -ru /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua +--- /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua 2022-02-02 15:39:47.522997688 -0500 ++++ /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua 2022-02-03 18:29:06.109638406 -0500 +@@ -640,7 +640,7 @@ + if not item then return end + local inv_image = item.inventory_image + if not inv_image then return end +- return string.match(inv_image,"colorize:#(......):200") ++ return string.match(inv_image,"colorize:#(......):128") + end + + -- punch-to-recolor using the airbrush +@@ -779,7 +779,7 @@ + local color = param2 + + local v = 0 +- local s = 1 ++ local s = 1 + if color < 24 then v = 1 + elseif color > 23 and color < 48 then v = 2 + elseif color > 47 and color < 72 then v = 3 +@@ -797,7 +797,7 @@ + elseif color == 244 then return "light_grey" + elseif color == 247 then return "grey" + elseif color == 251 then return "dark_grey" +- elseif color == 255 then return "black" ++ elseif color == 255 then return "black" + else return "grey_"..15-(color-240) + end + else +@@ -1020,7 +1020,7 @@ + local hexgrey = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) + local grey = "grey_"..y + +- if y == 0 then grey = "black" ++ if y == 0 then grey = "black" + elseif y == 4 then grey = "dark_grey" + elseif y == 8 then grey = "grey" + elseif y == 11 then grey = "light_grey" +@@ -1119,7 +1119,7 @@ + return + end + minetest.chat_send_player(player_name, "*** Switching to "..newcolor.." for the airbrush, to match that node.") +- unifieddyes.player_current_dye[player_name] = "dye:"..newcolor ++ unifieddyes.player_current_dye[player_name] = "dye:"..newcolor + end + end + }) +@@ -1152,11 +1152,11 @@ + end + end + +- if fields.show_all then ++ if fields.show_all then + unifieddyes.player_showall[player_name] = true + unifieddyes.show_airbrush_form(player) + return +- elseif fields.show_avail then ++ elseif fields.show_avail then + unifieddyes.player_showall[player_name] = false + unifieddyes.show_airbrush_form(player) + return +@@ -1196,7 +1196,7 @@ + + if (showall or unifieddyes.palette_has_color[nodepalette.."_"..s3]) and + (minetest.registered_items[dye] and (creative or inv:contains_item("main", dye))) then +- unifieddyes.player_selected_dye[player_name] = dye ++ unifieddyes.player_selected_dye[player_name] = dye + unifieddyes.show_airbrush_form(player) + end + end +@@ -1232,14 +1232,14 @@ + local color = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) + if minetest.registered_items["dye:"..val..hue] then + minetest.override_item("dye:"..val..hue, { +- inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", ++ inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", + }) + else + if (val..hue) ~= "medium_orange" + and (val..hue) ~= "light_red" then + minetest.register_craftitem(":dye:"..val..hue, { + description = S(desc), +- inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", ++ inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + end +@@ -1261,7 +1261,7 @@ + + minetest.register_craftitem(":dye:"..val..hue.."_s50", { + description = S(desc.." (low saturation)"), +- inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":200", ++ inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..val..hue.."_s50", "dye:"..val..hue.."_s50") +@@ -1281,7 +1281,7 @@ + + minetest.register_craftitem(":dye:"..name, { + description = S(desc), +- inventory_image = "unifieddyes_dye.png^[colorize:#"..rgb..":200", ++ inventory_image = "unifieddyes_dye.png^[colorize:#"..rgb..":128", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..name, "dye:"..name) +@@ -1289,16 +1289,16 @@ + end + + minetest.override_item("dye:grey", { +- inventory_image = "unifieddyes_dye.png^[colorize:#888888:200", ++ inventory_image = "unifieddyes_dye.png^[colorize:#888888:128", + }) + + minetest.override_item("dye:dark_grey", { +- inventory_image = "unifieddyes_dye.png^[colorize:#444444:200", ++ inventory_image = "unifieddyes_dye.png^[colorize:#444444:128", + }) + + minetest.register_craftitem(":dye:light_grey", { + description = S("Light grey Dye"), +- inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:200", ++ inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:128", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + +@@ -1323,7 +1323,7 @@ + for y = 0, 15 do + local grey = "grey_"..y + +- if y == 0 then grey = "black" ++ if y == 0 then grey = "black" + elseif y == 4 then grey = "dark_grey" + elseif y == 8 then grey = "grey" + elseif y == 11 then grey = "light_grey" +diff -ru /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md +--- /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md 2022-02-02 14:41:24.795046997 -0500 ++++ /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md 2022-02-03 18:42:53.185626763 -0500 +@@ -9,6 +9,8 @@ + + License: GPL 2.0 or higher. + ++Authors: VanessaE, Poikilos (created new unifieddyes_dye.png from scratch, changed colorize value) ++ + Install: Unzip the distribution file, rename the resultant folder to just "unifieddyes", move it into Minetest's mods folder, and enable it in your world configuration. + + Usage: for detailed usage information, please see [the Unified Dyes Thread](https://forum.minetest.net/viewtopic.php?f=11&t=2178&p=28399) on the Minetest forum. +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/textures/unifieddyes_dye.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/textures/unifieddyes_dye.png differ +diff -ru /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/license.txt /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/license.txt +--- /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/license.txt 2022-02-02 14:21:04.655064173 -0500 ++++ /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/license.txt 2022-02-03 18:44:59.425624986 -0500 +@@ -29,7 +29,7 @@ + ---------------------------- + + Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +-Copyright (C) 2012-2016 Perttu Ahola (celeron55) ++Copyright (c) 2012-2016 Perttu Ahola (celeron55) , Copyright (c) 2022 Jake "Poikilos" Gustafson (all dyes redrawn) + + You are free to: + Share — copy and redistribute the material in any medium or format. +Only in /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye: projects +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_black.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_black.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_blue.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_blue.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_brown.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_brown.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_cyan.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_cyan.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_green.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_green.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_grey.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_grey.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_green.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_green.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_grey.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_grey.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_magenta.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_magenta.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_orange.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_orange.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_pink.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_pink.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_red.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_red.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_violet.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_violet.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_white.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_white.png differ +Binary files /home/owner/git/EnlivenMinetest/Bucket_Game-base/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_yellow.png and /home/owner/git/EnlivenMinetest/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_yellow.png differ diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114.sh b/Bucket_Game-branches/dye-redrawn-vs-220114.sh new file mode 100755 index 0000000..21c4ecb --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114.sh @@ -0,0 +1,37 @@ +#!/bin/bash +patch_name="dye-redrawn-vs-220114" +try_bg="$HOME/minetest/games/bucket_game" +if [ -z "$BUCKET_GAME" ]; then + if [ -d "$try_bg" ]; then + echo "* detected \"$try_bg\"" + BUCKET_GAME="$try_bg" + fi +fi + + +if [ -z "$BUCKET_GAME" ]; then + echo "* You must first set $BUCKET_GAME (Since it wasn't detected at \"$try_bg\")." + exit 1 +fi + +if [ ! -d "$BUCKET_GAME/mods" ]; then + echo "Error: the destination BUCKET_GAME \"$BUCKET_GAME\" doesn't appear to be a game (It has no mods folder)." + echo "* Set $BUCKET_GAME to your bucket_game directory." + exit 1 +fi + +try_patches_dir="Bucket_Game-branches" +patch_src="$patch_name" +if [ ! -d "$patch_name" ]; then + if [ -d "$try_patches_dir/$patch_name" ]; then + patch_src="$try_patches_dir/$patch_name" + fi +fi + +if [ ! -d "$patch_name" ]; then + echo "Error: \"$patch_src\" is not here." + echo "You must run this patch script from EnlivenMinetest or EnlivenMinetest/$try_patches_dir." + exit 1 +fi +echo "rsync -rtv \"$patch_src/\" \"$BUCKET_GAME\"" +rsync -rtv "$patch_src/" "$BUCKET_GAME" diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/LICENSE b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/LICENSE new file mode 100644 index 0000000..4ebf695 --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/LICENSE @@ -0,0 +1,12 @@ +For license information, see the following files, where they exist, in +each modpack or mod: + + oldcoder.txt + LICENSE + LICENSE.txt + license.txt + README.md + README.txt + readme.txt + +and/or files with similar names. diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/00README b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/00README new file mode 100644 index 0000000..1aa78a4 --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/00README @@ -0,0 +1 @@ +See "oldcoder.txt". diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/LICENSE b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/LICENSE new file mode 100644 index 0000000..4eb7598 --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/LICENSE @@ -0,0 +1,282 @@ + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md new file mode 100644 index 0000000..2b27c70 --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/README.md @@ -0,0 +1,18 @@ +VanessaE's Unified Dyes +======================= + +The purpose of this mod originally was to supply a complete set of colors for Minetest mod authors to use for colorized nodes, or to reference in recipes. Since the advent of the default dyes mod in minetest_game, this mod has become more of an extension of the default mod. Since the advent of param2 colorization, it has also become a library for general color handling. + +Unified Dyes expands the standard dye set from 15 colors to 32, 89, or 256 (see the API and usage info). + +Dependencies: Minetest engine version 0.4.16 or higher and a corresponding copy of minetest_game. + +License: GPL 2.0 or higher. + +Authors: VanessaE, Poikilos (created new unifieddyes_dye.png from scratch, changed colorize value) + +Install: Unzip the distribution file, rename the resultant folder to just "unifieddyes", move it into Minetest's mods folder, and enable it in your world configuration. + +Usage: for detailed usage information, please see [the Unified Dyes Thread](https://forum.minetest.net/viewtopic.php?f=11&t=2178&p=28399) on the Minetest forum. + +API: the full API is documented here: https://github.com/minetest-mods/unifieddyes/blob/master/API.md diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua new file mode 100644 index 0000000..021b6d5 --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/init.lua @@ -0,0 +1,1531 @@ +--[[ + +Unified Dyes + +This mod provides an extension to the Minetest 0.4.x dye system + +============================================================================== + +Copyright (C) 2012-2013, Vanessa Ezekowitz +Email: vanessaezekowitz@gmail.com + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +============================================================================== + +--]] + +--===================================================================== + +unifieddyes = {} + +local creative_mode = minetest.settings:get_bool("creative_mode") + +-- Boilerplate to support localized strings if intllib mod is installed. +local S +if minetest.get_modpath("intllib") then + S = intllib.Getter() +else + S = function(s) return s end +end + +-- the names of the various colors here came from http://www.procato.com/rgb+index/ + +unifieddyes.HUES_EXTENDED = { + { "red", 0xff, 0x00, 0x00 }, + { "vermilion", 0xff, 0x40, 0x00 }, + { "orange", 0xff, 0x80, 0x00 }, + { "amber", 0xff, 0xbf, 0x00 }, + { "yellow", 0xff, 0xff, 0x00 }, + { "lime", 0xbf, 0xff, 0x00 }, + { "chartreuse", 0x80, 0xff, 0x00 }, + { "harlequin", 0x40, 0xff, 0x00 }, + { "green", 0x00, 0xff, 0x00 }, + { "malachite", 0x00, 0xff, 0x40 }, + { "spring", 0x00, 0xff, 0x80 }, + { "turquoise", 0x00, 0xff, 0xbf }, + { "cyan", 0x00, 0xff, 0xff }, + { "cerulean", 0x00, 0xbf, 0xff }, + { "azure", 0x00, 0x80, 0xff }, + { "sapphire", 0x00, 0x40, 0xff }, + { "blue", 0x00, 0x00, 0xff }, + { "indigo", 0x40, 0x00, 0xff }, + { "violet", 0x80, 0x00, 0xff }, + { "mulberry", 0xbf, 0x00, 0xff }, + { "magenta", 0xff, 0x00, 0xff }, + { "fuchsia", 0xff, 0x00, 0xbf }, + { "rose", 0xff, 0x00, 0x80 }, + { "crimson", 0xff, 0x00, 0x40 } +} + +unifieddyes.HUES_WITH_GREY = {} + +for _,i in ipairs(unifieddyes.HUES_EXTENDED) do + table.insert(unifieddyes.HUES_WITH_GREY, i[1]) +end +table.insert(unifieddyes.HUES_WITH_GREY, "grey") + +unifieddyes.HUES_WALLMOUNTED = { + "red", + "orange", + "yellow", + "green", + "cyan", + "blue", + "violet", + "magenta" +} + +unifieddyes.SATS = { + "", + "_s50" +} + +unifieddyes.VALS = { + "", + "medium_", + "dark_" +} + +unifieddyes.VALS_SPLIT = { + "faint_", + "light_", + "", + "medium_", + "dark_" +} + +unifieddyes.VALS_EXTENDED = { + "faint_", + "pastel_", + "light_", + "bright_", + "", + "medium_", + "dark_" +} + +unifieddyes.GREYS = { + "white", + "light_grey", + "grey", + "dark_grey", + "black" +} + +unifieddyes.GREYS_EXTENDED = table.copy(unifieddyes.GREYS) + +for i = 1, 14 do + if i ~= 0 and i ~= 4 and i ~= 8 and i ~= 11 and i ~= 15 then + table.insert(unifieddyes.GREYS_EXTENDED, "grey_"..i) + end +end + +local default_dyes = { + "black", + "blue", + "brown", + "cyan", + "dark_green", + "dark_grey", + "green", + "grey", + "magenta", + "orange", + "pink", + "red", + "violet", + "white", + "yellow" +} + +unifieddyes.player_current_dye = {} +unifieddyes.player_selected_dye = {} +unifieddyes.player_last_right_clicked = {} +unifieddyes.palette_has_color = {} +unifieddyes.player_showall = {} + +-- if a node with a palette is placed in the world, +-- but the itemstack used to place it has no palette_index (color byte), +-- create something appropriate to make it officially white. + +minetest.register_on_placenode( + function(pos, newnode, placer, oldnode, itemstack, pointed_thing) + local def = minetest.registered_items[newnode.name] + + if not def + or not def.palette + or def.after_place_node then + return false + end + + if not string.find(itemstack:to_string(), "palette_index") then + local param2 + local color = 0 + + if def.palette == "unifieddyes_palette_extended.png" + and def.paramtype2 == "color" then + param2 = 240 + color = 240 + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" + and def.paramtype2 == "colorwallmounted" then + param2 = newnode.param2 % 8 + elseif string.find(def.palette, "unifieddyes_palette_") + and def.paramtype2 == "colorfacedir" then -- it's a split palette + param2 = newnode.param2 % 32 + end + + if param2 then + minetest.swap_node(pos, {name = newnode.name, param2 = param2}) + minetest.get_meta(pos):set_int("palette_index", color) + end + end + end +) + +-- just stubs to keep old mods from crashing when expecting auto-coloring +-- or getting back the dye on dig. + +function unifieddyes.recolor_on_place(foo) +end + +function unifieddyes.after_dig_node(foo) +end + +-- This helper function creates multiple copies of the passed node, +-- for the split palette - one per hue, plus grey - and assigns +-- proper palettes and other attributes + +function unifieddyes.generate_split_palette_nodes(name, def, drop) + for _, color in ipairs(unifieddyes.HUES_WITH_GREY) do + local def2 = table.copy(def) + local desc_color = string.gsub(string.upper(string.sub(color, 1, 1))..string.sub(color, 2), "_", " ") + if string.sub(def2.description, -1) == ")" then + def2.description = string.sub(def2.description, 1, -2)..", "..desc_color.." shades)" + else + def2.description = def2.description.."("..desc_color.." shades)" + end + def2.palette = "unifieddyes_palette_"..color.."s.png" + def2.paramtype2 = "colorfacedir" + def2.groups.ud_param2_colorable = 1 + + if drop then + def2.drop = { + items = { + {items = {drop.."_"..color}, inherit_color = true }, + } + } + end + + minetest.register_node(":"..name.."_"..color, def2) + end +end + +-- This helper function creates a colored itemstack + +function unifieddyes.make_colored_itemstack(item, palette, color) + local paletteidx = unifieddyes.getpaletteidx(color, palette) + local stack = ItemStack(item) + stack:get_meta():set_int("palette_index", paletteidx) + return stack:to_string(),paletteidx +end + +-- these helper functions register all of the recipes needed to create colored +-- nodes with any of the dyes supported by that node's palette. + +local function register_c(craft, h, sat, val) + local hue = (type(h) == "table") and h[1] or h + local color = "" + if val then + if craft.palette == "wallmounted" then + color = val..hue..sat + else + color = val..hue..sat + end + else + color = hue -- if val is nil, then it's grey. + end + + local dye = "dye:"..color + local recipe = minetest.serialize(craft.recipe) + recipe = string.gsub(recipe, "MAIN_DYE", dye) + recipe = string.gsub(recipe, "NEUTRAL_NODE", craft.neutral_node) + local newrecipe = minetest.deserialize(recipe) + + local coutput = craft.output or "" + local output = coutput + if craft.output_prefix then + if craft.palette ~= "split" then + output = craft.output_prefix..color..craft.output_suffix..coutput + else + if hue == "white" or hue == "black" or string.find(hue, "grey") then + output = craft.output_prefix.."grey"..craft.output_suffix..coutput + elseif hue == "pink" then + dye = "dye:light_red" + output = craft.output_prefix.."red"..craft.output_suffix..coutput + else + output = craft.output_prefix..hue..craft.output_suffix..coutput + end + end + end + + local colored_itemstack = + unifieddyes.make_colored_itemstack(output, craft.palette, dye) + + minetest.register_craft({ + output = colored_itemstack, + type = craft.type, + recipe = newrecipe + }) + +end + +function unifieddyes.register_color_craft(craft) + local hues_table = unifieddyes.HUES_EXTENDED + local sats_table = unifieddyes.SATS + local vals_table = unifieddyes.VALS_SPLIT + local greys_table = unifieddyes.GREYS + + if craft.palette == "wallmounted" then + register_c(craft, "green", "", "light_") + register_c(craft, "blue", "", "light_") + hues_table = unifieddyes.HUES_WALLMOUNTED + sats_table = {""} + vals_table = unifieddyes.VALS + elseif craft.palette == "extended" then + vals_table = unifieddyes.VALS_EXTENDED + greys_table = unifieddyes.GREYS_EXTENDED + end + + for _, hue in ipairs(hues_table) do + for _, val in ipairs(vals_table) do + for _, sat in ipairs(sats_table) do + + if sat == "_s50" and val ~= "" and val ~= "medium_" and val ~= "dark_" then break end + register_c(craft, hue, sat, val) + + end + end + end + + for _, grey in ipairs(greys_table) do + register_c(craft, grey) + end + + register_c(craft, "pink") + +end + +-- code borrowed from homedecor +-- call this function to reset the rotation of a "wallmounted" object on place + +function unifieddyes.fix_rotation(pos, placer, itemstack, pointed_thing) + local node = minetest.get_node(pos) + local colorbits = node.param2 - (node.param2 % 8) + + local yaw = placer:get_look_horizontal() + local dir = minetest.yaw_to_dir(yaw) -- -1.5) + local pitch = placer:get_look_vertical() + + local fdir = minetest.dir_to_wallmounted(dir) + + if pitch < -(math.pi/8) then + fdir = 0 + elseif pitch > math.pi/8 then + fdir = 1 + end + minetest.swap_node(pos, { name = node.name, param2 = fdir+colorbits }) +end + +-- use this when you have a "wallmounted" node that should never be oriented +-- to floor or ceiling... + +function unifieddyes.fix_rotation_nsew(pos, placer, itemstack, pointed_thing) + local node = minetest.get_node(pos) + local colorbits = node.param2 - (node.param2 % 8) + local yaw = placer:get_look_horizontal() + local dir = minetest.yaw_to_dir(yaw+1.5) + local fdir = minetest.dir_to_wallmounted(dir) + + minetest.swap_node(pos, { name = node.name, param2 = fdir+colorbits }) +end + +-- ... and use this one to force that kind of node off of floor/ceiling +-- orientation after the screwdriver rotates it. + +function unifieddyes.fix_after_screwdriver_nsew(pos, node, user, mode, new_param2) + local new_fdir = new_param2 % 8 + local color = new_param2 - new_fdir + if new_fdir < 2 then + new_fdir = 2 + minetest.swap_node(pos, { name = node.name, param2 = new_fdir + color }) + return true + end +end + +function unifieddyes.is_buildable_to(placer_name, ...) + for _, pos in ipairs({...}) do + local node = minetest.get_node_or_nil(pos) + local def = node and minetest.registered_nodes[node.name] + if not (def and def.buildable_to) or minetest.is_protected(pos, placer_name) then + return false + end + end + return true +end + +function unifieddyes.get_hsv(name) -- expects a node/item name + local hue = "" + local a,b + for _, i in ipairs(unifieddyes.HUES_EXTENDED) do + a,b = string.find(name, "_"..i[1]) + if a then + hue = i[1] + break + end + end + + if string.find(name, "_light_grey") then hue = "light_grey" + elseif string.find(name, "_lightgrey") then hue = "light_grey" + elseif string.find(name, "_dark_grey") then hue = "dark_grey" + elseif string.find(name, "_darkgrey") then hue = "dark_grey" + elseif string.find(name, "_grey") then hue = "grey" + elseif string.find(name, "_white") then hue = "white" + elseif string.find(name, "_black") then hue = "black" + end + + local sat = "" + if string.find(name, "_s50") then sat = "_s50" end + + local val = "" + if string.find(name, "dark_") then val = "dark_" end + if string.find(name, "medium_") then val = "medium_" end + if string.find(name, "light_") then val = "light_" end + + return hue, sat, val +end + +-- code partially borrowed from cheapie's plasticbox mod + +-- in the function below, color is just a color string, while +-- palette_type can be: +-- +-- "extended" = 256 color palette +-- "split" = 200 color palette split into pieces for colorfacedir +-- "wallmounted" = 32-color abridged palette + + +function unifieddyes.getpaletteidx(color, palette_type) + + local origcolor = color + local aliases = { + ["pink"] = "light_red", + ["brown"] = "medium_orange", + ["azure"] = "light_blue" + } + + local grayscale = { + ["white"] = 1, + ["light_grey"] = 2, + ["grey"] = 3, + ["dark_grey"] = 4, + ["black"] = 5, + } + + local grayscale_extended = { + ["white"] = 0, + ["grey_14"] = 1, + ["grey_13"] = 2, + ["grey_12"] = 3, + ["light_grey"] = 4, + ["grey_11"] = 4, + ["grey_10"] = 5, + ["grey_9"] = 6, + ["grey_8"] = 7, + ["grey"] = 7, + ["grey_7"] = 8, + ["grey_6"] = 9, + ["grey_5"] = 10, + ["grey_4"] = 11, + ["dark_grey"] = 11, + ["grey_3"] = 12, + ["grey_2"] = 13, + ["grey_1"] = 14, + ["black"] = 15, + } + + local grayscale_wallmounted = { + ["white"] = 0, + ["light_grey"] = 1, + ["grey"] = 2, + ["dark_grey"] = 3, + ["black"] = 4, + } + + local hues_extended = { + ["red"] = 0, + ["vermilion"] = 1, + ["orange"] = 2, + ["amber"] = 3, + ["yellow"] = 4, + ["lime"] = 5, + ["chartreuse"] = 6, + ["harlequin"] = 7, + ["green"] = 8, + ["malachite"] = 9, + ["spring"] = 10, + ["aqua"] = 10, + ["turquoise"] = 11, + ["cyan"] = 12, + ["cerulean"] = 13, + ["azure"] = 14, + ["skyblue"] = 14, + ["sapphire"] = 15, + ["blue"] = 16, + ["indigo"] = 17, + ["violet"] = 18, + ["mulberry"] = 19, + ["magenta"] = 20, + ["fuchsia"] = 21, + ["rose"] = 22, + ["redviolet"] = 22, + ["crimson"] = 23, + } + + local hues_wallmounted = { + ["red"] = 0, + ["orange"] = 1, + ["yellow"] = 2, + ["green"] = 3, + ["cyan"] = 4, + ["blue"] = 5, + ["violet"] = 6, + ["magenta"] = 7 + } + + local shades = { + [""] = 1, + ["s50"] = 2, + ["light"] = 3, + ["medium"] = 4, + ["mediums50"] = 5, + ["dark"] = 6, + ["darks50"] = 7, + } + + local shades_split = { + ["faint"] = 0, + [""] = 1, + ["s50"] = 2, + ["light"] = 3, + ["medium"] = 4, + ["mediums50"] = 5, + ["dark"] = 6, + ["darks50"] = 7, + } + + local shades_extended = { + ["faint"] = 0, + ["pastel"] = 1, + ["light"] = 2, + ["bright"] = 3, + [""] = 4, + ["s50"] = 5, + ["medium"] = 6, + ["mediums50"] = 7, + ["dark"] = 8, + ["darks50"] = 9 + } + + local shades_wallmounted = { + [""] = 1, + ["medium"] = 2, + ["dark"] = 3 + } + + if string.sub(color,1,4) == "dye:" then + color = string.sub(color,5,-1) + elseif string.sub(color,1,12) == "unifieddyes:" then + color = string.sub(color,13,-1) + else + return + end + + if palette_type == "wallmounted" then + if grayscale_wallmounted[color] then + return (grayscale_wallmounted[color] * 8), 0 + end + elseif palette_type == "split" then + if grayscale[color] then + return (grayscale[color] * 32), 0 + end + elseif palette_type == "extended" then + if grayscale_extended[color] then + return grayscale_extended[color]+240, 0 + end + end + + local shade = "" -- assume full + if string.sub(color,1,6) == "faint_" then + shade = "faint" + color = string.sub(color,7,-1) + elseif string.sub(color,1,7) == "pastel_" then + shade = "pastel" + color = string.sub(color,8,-1) + elseif string.sub(color,1,6) == "light_" then + shade = "light" + color = string.sub(color,7,-1) + elseif string.sub(color,1,7) == "bright_" then + shade = "bright" + color = string.sub(color,8,-1) + elseif string.sub(color,1,7) == "medium_" then + shade = "medium" + color = string.sub(color,8,-1) + elseif string.sub(color,1,5) == "dark_" then + shade = "dark" + color = string.sub(color,6,-1) + end + if string.sub(color,-4,-1) == "_s50" then + shade = shade.."s50" + color = string.sub(color,1,-5) + end + + if palette_type == "wallmounted" then + if color == "green" and shade == "light" then return 48,3 + elseif color == "brown" then return 17,1 + elseif color == "pink" then return 56,7 + elseif color == "blue" and shade == "light" then return 40,5 + elseif hues_wallmounted[color] and shades_wallmounted[shade] then + return (shades_wallmounted[shade] * 64 + hues_wallmounted[color] * 8), hues_wallmounted[color] + end + else + if color == "brown" then + color = "orange" + shade = "medium" + elseif color == "pink" then + color = "red" + shade = "light" + end + if palette_type == "split" then -- it's colorfacedir + if hues_extended[color] and shades_split[shade] then + return (shades_split[shade] * 32), hues_extended[color]+1 + end + elseif palette_type == "extended" then + if hues_extended[color] and shades_extended[shade] then + return (hues_extended[color] + shades_extended[shade]*24), hues_extended[color] + end + end + end +end + +function unifieddyes.get_color_from_dye_name(name) + if name == "dye:black" then + return "000000" + elseif name == "dye:white" then + return "ffffff" + end + local item = minetest.registered_items[name] + if not item then return end + local inv_image = item.inventory_image + if not inv_image then return end + return string.match(inv_image,"colorize:#(......):128") +end + +-- punch-to-recolor using the airbrush + +function unifieddyes.on_airbrush(itemstack, player, pointed_thing) + local player_name = player:get_player_name() + local painting_with = nil + + if unifieddyes.player_current_dye[player_name] then + painting_with = unifieddyes.player_current_dye[player_name] + end + + if not painting_with then + minetest.chat_send_player(player_name, "*** You need to set a color first.") + minetest.chat_send_player(player_name, "*** Right-click any random node to open the color selector,") + minetest.chat_send_player(player_name, "*** or shift+right-click a colorized node to use its color.") + minetest.chat_send_player(player_name, "*** Be sure to click \"Accept\", or the color you select will be ignored.") + return + end + + local pos = minetest.get_pointed_thing_position(pointed_thing) + if not pos then + local look_angle = player:get_look_vertical() + if look_angle > -1.55 then + minetest.chat_send_player(player_name, "*** No node selected") + else + local hexcolor = unifieddyes.get_color_from_dye_name(painting_with) + local r = tonumber(string.sub(hexcolor,1,2),16) + local g = tonumber(string.sub(hexcolor,3,4),16) + local b = tonumber(string.sub(hexcolor,5,6),16) + player:set_sky({r=r,g=g,b=b,a=255},"plain") + end + return + end + + local node = minetest.get_node(pos) + local def = minetest.registered_items[node.name] + if not def then return end + + if minetest.is_protected(pos, player_name) then + minetest.chat_send_player(player_name, "*** Sorry, someone else owns that node.") + return + end + + if not (def.groups and def.groups.ud_param2_colorable and def.groups.ud_param2_colorable > 0) then + minetest.chat_send_player(player_name, "*** That node can't be colored.") + return + end + + local palette = nil + local fdir = 0 + if not def or not def.palette then + minetest.chat_send_player(player_name, "*** That node can't be colored -- it's either undefined or has no palette.") + return + elseif def.palette == "unifieddyes_palette_extended.png" then + palette = "extended" + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" then + palette = "wallmounted" + fdir = node.param2 % 8 + elseif def.palette ~= "unifieddyes_palette_extended.png" + and def.palette ~= "unifieddyes_palette_colorwallmounted.png" + and string.find(def.palette, "unifieddyes_palette_") then + palette = "split" + fdir = node.param2 % 32 + else + minetest.chat_send_player(player_name, "*** That node can't be colored -- it has an invalid color mode.") + return + end + + local idx, hue = unifieddyes.getpaletteidx(painting_with, palette) + local inv = player:get_inventory() + if (not creative or not creative.is_enabled_for(player_name)) and not inv:contains_item("main", painting_with) then + local suff = "" + if not idx then + suff = " Besides, "..string.sub(painting_with, 5).." can't be applied to that node." + end + minetest.chat_send_player(player_name, "*** You're in survival mode, and you're out of "..string.sub(painting_with, 5).."."..suff) + return + end + + if not idx then + minetest.chat_send_player(player_name, "*** "..string.sub(painting_with, 5).." can't be applied to that node.") + return + end + + local oldidx = node.param2 - fdir + local name = def.airbrush_replacement_node or node.name + + if palette == "split" then + + local modname = string.sub(name, 1, string.find(name, ":")-1) + local nodename2 = string.sub(name, string.find(name, ":")+1) + local oldcolor = "snozzberry" + local newcolor = "razzberry" -- intentionally misspelled ;-) + + if def.ud_color_start and def.ud_color_end then + oldcolor = string.sub(node.name, def.ud_color_start, def.ud_color_end) + newcolor = string.sub(painting_with, 5) + else + if hue ~= 0 then + newcolor = unifieddyes.HUES_EXTENDED[hue][1] + else + newcolor = "grey" + end + + if def.airbrush_replacement_node then + oldcolor = "grey" + else + local s = string.sub(def.palette, 21) + oldcolor = string.sub(s, 1, string.find(s, "s.png")-1) + end + end + + name = modname..":"..string.gsub(nodename2, oldcolor, newcolor) + + if not minetest.registered_items[name] then + minetest.chat_send_player(player_name, "*** "..string.sub(painting_with, 5).." can't be applied to that node.") + return + end + elseif idx == oldidx then + return + end + minetest.swap_node(pos, {name = name, param2 = fdir + idx}) + if not creative or not creative.is_enabled_for(player_name) then + inv:remove_item("main", painting_with) + return + end +end + +-- get a node's dye color based on its palette and param2 + +function unifieddyes.color_to_name(param2, def) + if not param2 or not def or not def.palette then return end + + if def.palette == "unifieddyes_palette_extended.png" then + local color = param2 + + local v = 0 + local s = 1 + if color < 24 then v = 1 + elseif color > 23 and color < 48 then v = 2 + elseif color > 47 and color < 72 then v = 3 + elseif color > 71 and color < 96 then v = 4 + elseif color > 95 and color < 120 then v = 5 + elseif color > 119 and color < 144 then v = 5 s = 2 + elseif color > 143 and color < 168 then v = 6 + elseif color > 167 and color < 192 then v = 6 s = 2 + elseif color > 191 and color < 216 then v = 7 + elseif color > 215 and color < 240 then v = 7 s = 2 + end + + if color > 239 then + if color == 240 then return "white" + elseif color == 244 then return "light_grey" + elseif color == 247 then return "grey" + elseif color == 251 then return "dark_grey" + elseif color == 255 then return "black" + else return "grey_"..15-(color-240) + end + else + local h = color - math.floor(color/24)*24 + return unifieddyes.VALS_EXTENDED[v]..unifieddyes.HUES_EXTENDED[h+1][1]..unifieddyes.SATS[s] + end + + elseif def.palette == "unifieddyes_palette_colorwallmounted.png" then + local color = math.floor(param2 / 8) + if color == 0 then return "white" + elseif color == 1 then return "light_grey" + elseif color == 2 then return "grey" + elseif color == 3 then return "dark_grey" + elseif color == 4 then return "black" + elseif color == 5 then return "light_blue" + elseif color == 6 then return "light_green" + elseif color == 7 then return "pink" + end + local v = math.floor(color/8) + local h = color - v * 8 + return unifieddyes.VALS[v]..unifieddyes.HUES_WALLMOUNTED[h+1] + + elseif string.find(def.palette, "unifieddyes_palette") then -- it's the split palette + -- palette names in this mode are always "unifieddyes_palette_COLORs.png" + + local s = string.sub(def.palette, 21) + local color = string.sub(s, 1, string.find(s, "s.png")-1) + + local v = math.floor(param2/32) + if color ~= "grey" then + if v == 0 then return "faint_"..color + elseif v == 1 then return color + elseif v == 2 then return color.."_s50" + elseif v == 3 then return "light_"..color + elseif v == 4 then return "medium_"..color + elseif v == 5 then return "medium_"..color.."_s50" + elseif v == 6 then return "dark_"..color + elseif v == 7 then return "dark_"..color.."_s50" + end + else + if v > 0 and v < 6 then return unifieddyes.GREYS[v] + else return "white" + end + end + end +end + +local hps = 0.6 -- horizontal position scale +local vps = 1.3 -- vertical position scale +local vs = 0.1 -- vertical shift/offset + +local color_button_size = ";0.75,0.75;" +local color_square_size = ";0.69,0.69;" + +function unifieddyes.make_readable_color(color) + local s = string.gsub(color, "_", " ") + s = string.gsub(s, "s50", "(low saturation)") + return s +end + +function unifieddyes.make_colored_square(hexcolor, colorname, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + + local dye = "dye:"..colorname + + local overlay = "" + local colorize = minetest.formspec_escape("^[colorize:#"..hexcolor..":255") + + if not creative and inv:contains_item("main", dye) then + overlay = "^unifieddyes_onhand_overlay.png" + end + + local unavail_overlay = "" + if not showall and not unifieddyes.palette_has_color[nodepalette.."_"..colorname] + or (explist and not explist[colorname]) then + if overlay == "" then + unavail_overlay = "^unifieddyes_unavailable_overlay.png" + else + unavail_overlay = "^unifieddyes_onhand_unavailable_overlay.png" + end + end + + local tooltip = "tooltip["..colorname..";".. + unifieddyes.make_readable_color(colorname).. + "\n(dye:"..colorname..")]" + + if dye == painting_with then + overlay = "^unifieddyes_select_overlay.png" + selindic = "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay.."]"..tooltip + end + + local form + if unavail_overlay == "" then + form = "image_button[".. + (hp*hps)..","..(v2*vps+vs).. + color_button_size.. + "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay..";".. + colorname..";]".. + tooltip + else + form = "image[".. + (hp*hps)..","..(v2*vps+vs).. + color_square_size.. + "unifieddyes_white_square.png"..colorize..overlay..unavail_overlay.."]".. + tooltip + end + + return form, selindic +end + +function unifieddyes.show_airbrush_form(player) + if not player then return end + + local t = {} + + local player_name = player:get_player_name() + local painting_with = unifieddyes.player_selected_dye[player_name] or unifieddyes.player_current_dye[player_name] + local creative = creative and creative.is_enabled_for(player_name) + local inv = player:get_inventory() + local nodepalette = "extended" + local showall = unifieddyes.player_showall[player_name] + + t[1] = "size[14.5,8.5]label[7,-0.3;Select a color:]" + local selindic = "unifieddyes_select_overlay.png^unifieddyes_question.png]" + + local last_right_click = unifieddyes.player_last_right_clicked[player_name] + if last_right_click then + if last_right_click.def and last_right_click.def.palette then + if last_right_click.def.palette == "unifieddyes_palette_colorwallmounted.png" then + nodepalette = "wallmounted" + elseif last_right_click.def.palette == "unifieddyes_palette_extended.png" then + t[#t+1] = "label[0.5,8.25;(Right-clicked a node that supports all 256 colors, showing them all)]" + showall = true + elseif last_right_click.def.palette ~= "unifieddyes_palette_extended.png" + and last_right_click.def.palette ~= "unifieddyes_palette_colorwallmounted.png" + and string.find(last_right_click.def.palette, "unifieddyes_palette_") then + nodepalette = "split" + end + end + end + + if not last_right_click.def.groups + or not last_right_click.def.groups.ud_param2_colorable + or not last_right_click.def.palette + or not string.find(last_right_click.def.palette, "unifieddyes_palette_") then + t[#t+1] = "label[0.5,8.25;(Right-clicked a node not supported by the Airbrush, showing all colors)]" + end + + local explist = last_right_click.def.explist + + for v = 0, 6 do + local val = unifieddyes.VALS_EXTENDED[v+1] + + local sat = "" + local v2=(v/2) + + for hi, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local hp=hi-1 + + local r = h[2] + local g = h[3] + local b = h[4] + + local factor = 40 + if v > 3 then + factor = 75 + v2 = (v-2) + end + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + local hexcolor = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) + local f + f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + end + + if v > 3 then + sat = "_s50" + v2 = (v-1.5) + + for hi, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local hp=hi-1 + + local r = h[2] + local g = h[3] + local b = h[4] + + local factor = 75 + + local pr = 0.299 + local pg = 0.587 + local pb = 0.114 + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + local p = math.sqrt(r2*r2*pr + g2*g2*pg + b2*b2*pb) + local r3 = math.floor(p+(r2-p)*0.5) + local g3 = math.floor(p+(g2-p)*0.5) + local b3 = math.floor(p+(b2-p)*0.5) + + local hexcolor = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3) + local f + f, selindic = unifieddyes.make_colored_square(hexcolor, val..hue..sat, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + end + end + end + + local v2=5 + for y = 0, 15 do + + local hp=15-y + + local hexgrey = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) + local grey = "grey_"..y + + if y == 0 then grey = "black" + elseif y == 4 then grey = "dark_grey" + elseif y == 8 then grey = "grey" + elseif y == 11 then grey = "light_grey" + elseif y == 15 then grey = "white" + end + + local f + f, selindic = unifieddyes.make_colored_square(hexgrey, grey, showall, creative, painting_with, nodepalette, hp, v2, selindic, inv, explist) + t[#t+1] = f + + end + + if not creative then + t[#t+1] = "image[10," + t[#t+1] = (vps*5.55+vs) + t[#t+1] = color_button_size + t[#t+1] = "unifieddyes_onhand_overlay.png]label[10.7," + t[#t+1] = (vps*5.51+vs) + t[#t+1] = ";Dyes]" + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.67+vs) + t[#t+1] = ";on hand]" + + end + + t[#t+1] = "image[10," + t[#t+1] = (vps*5+vs) + t[#t+1] = color_button_size + t[#t+1] = selindic + + if painting_with then + t[#t+1] = "label[10.7," + t[#t+1] = (vps*4.90+vs) + t[#t+1] = ";Your selection:]" + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.07+vs) + t[#t+1] = ";" + t[#t+1] = unifieddyes.make_readable_color(string.sub(painting_with, 5)) + t[#t+1] = "]label[10.7," + t[#t+1] = (vps*5.24+vs) + t[#t+1] = ";(" + t[#t+1] = painting_with + t[#t+1] = ")]" + else + t[#t+1] = "label[10.7," + t[#t+1] = (vps*5.07+vs) + t[#t+1] = ";Your selection]" + end + + t[#t+1] = "button_exit[10.5,8;2,1;cancel;Cancel]button_exit[12.5,8;2,1;accept;Accept]" + + + if last_right_click and last_right_click.def and nodepalette ~= "extended" then + if showall then + t[#t+1] = "button[0,8;2,1;show_avail;Show Available]" + t[#t+1] = "label[2,8.25;(Currently showing all 256 colors)]" + else + t[#t+1] = "button[0,8;2,1;show_all;Show All Colors]" + t[#t+1] = "label[2,8.25;(Currently only showing what the right-clicked node can use)]" + end + end + + minetest.show_formspec(player_name, "unifieddyes:dye_select_form", table.concat(t)) +end + +minetest.register_tool("unifieddyes:airbrush", { + description = S("Dye Airbrush"), + inventory_image = "unifieddyes_airbrush.png", + use_texture_alpha = true, + tool_capabilities = { + full_punch_interval=0.1, + }, + range = 12, + on_use = unifieddyes.on_airbrush, + on_place = function(itemstack, placer, pointed_thing) + local keys = placer:get_player_control() + local player_name = placer:get_player_name() + local pos = minetest.get_pointed_thing_position(pointed_thing) + local node + local def + + if pos then node = minetest.get_node(pos) end + if node then def = minetest.registered_items[node.name] end + + unifieddyes.player_last_right_clicked[player_name] = {pos = pos, node = node, def = def} + + if not keys.sneak then + unifieddyes.show_airbrush_form(placer) + elseif keys.sneak then + + if not pos or not def then return end + local newcolor = unifieddyes.color_to_name(node.param2, def) + + if not newcolor then + minetest.chat_send_player(player_name, "*** That node is uncolored.") + return + end + minetest.chat_send_player(player_name, "*** Switching to "..newcolor.." for the airbrush, to match that node.") + unifieddyes.player_current_dye[player_name] = "dye:"..newcolor + end + end +}) + +minetest.register_craft( { + output = "unifieddyes:airbrush", + recipe = { + { "basic_materials:brass_ingot", "", "basic_materials:plastic_sheet" }, + { "", "default:steel_ingot", "" }, + { "", "", "default:steel_ingot" } + }, +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if formname == "unifieddyes:dye_select_form" then + + local player_name = player:get_player_name() + local nodepalette = "extended" + local showall = unifieddyes.player_showall[player_name] + + local last_right_click = unifieddyes.player_last_right_clicked[player_name] + if last_right_click and last_right_click.def then + if last_right_click.def.palette then + if last_right_click.def.palette == "unifieddyes_palette_colorwallmounted.png" then + nodepalette = "wallmounted" + elseif last_right_click.def.palette ~= "unifieddyes_palette_extended.png" then + nodepalette = "split" + end + end + end + + if fields.show_all then + unifieddyes.player_showall[player_name] = true + unifieddyes.show_airbrush_form(player) + return + elseif fields.show_avail then + unifieddyes.player_showall[player_name] = false + unifieddyes.show_airbrush_form(player) + return + elseif fields.quit then + if fields.accept then + local dye = unifieddyes.player_selected_dye[player_name] + if not dye then + minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but no color was selected!") + return + elseif not showall + and not unifieddyes.palette_has_color[nodepalette.."_"..string.sub(dye, 5)] then + minetest.chat_send_player(player_name, "*** Clicked \"Accept\", but the selected color can't be used on the") + minetest.chat_send_player(player_name, "*** node that was right-clicked (and \"Show All\" wasn't in effect).") + if unifieddyes.player_current_dye[player_name] then + minetest.chat_send_player(player_name, "*** Ignoring it and sticking with "..string.sub(unifieddyes.player_current_dye[player_name], 5)..".") + else + minetest.chat_send_player(player_name, "*** Ignoring it.") + end + return + else + unifieddyes.player_current_dye[player_name] = dye + unifieddyes.player_selected_dye[player_name] = nil + minetest.chat_send_player(player_name, "*** Selected "..string.sub(dye, 5).." for the airbrush.") + return + end + else -- assume "Cancel" or Esc. + unifieddyes.player_selected_dye[player_name] = nil + return + end + else + local s1 = string.sub(minetest.serialize(fields), 11) + local s3 = string.sub(s1,1, string.find(s1, '"')-1) + + local inv = player:get_inventory() + local creative = creative and creative.is_enabled_for(player_name) + local dye = "dye:"..s3 + + if (showall or unifieddyes.palette_has_color[nodepalette.."_"..s3]) and + (minetest.registered_items[dye] and (creative or inv:contains_item("main", dye))) then + unifieddyes.player_selected_dye[player_name] = dye + unifieddyes.show_airbrush_form(player) + end + end + end +end) + +-- Generate all dyes that are not part of the default minetest_game dyes mod + +for _, h in ipairs(unifieddyes.HUES_EXTENDED) do + local hue = h[1] + local r = h[2] + local g = h[3] + local b = h[4] + + for v = 0, 6 do + local val = unifieddyes.VALS_EXTENDED[v+1] + + local factor = 40 + if v > 3 then factor = 75 end + + local r2 = math.max(math.min(r + (4-v)*factor, 255), 0) + local g2 = math.max(math.min(g + (4-v)*factor, 255), 0) + local b2 = math.max(math.min(b + (4-v)*factor, 255), 0) + + -- full-sat color + + local desc = hue:gsub("%a", string.upper, 1).." Dye" + + if val ~= "" then + desc = val:sub(1, -2):gsub("%a", string.upper, 1) .." "..desc + end + + local color = string.format("%02x", r2)..string.format("%02x", g2)..string.format("%02x", b2) + if minetest.registered_items["dye:"..val..hue] then + minetest.override_item("dye:"..val..hue, { + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", + }) + else + if (val..hue) ~= "medium_orange" + and (val..hue) ~= "light_red" then + minetest.register_craftitem(":dye:"..val..hue, { + description = S(desc), + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + end + end + minetest.register_alias("unifieddyes:"..val..hue, "dye:"..val..hue) + + if v > 3 then -- also register the low-sat version + + local pr = 0.299 + local pg = 0.587 + local pb = 0.114 + + local p = math.sqrt(r2*r2*pr + g2*g2*pg + b2*b2*pb) + local r3 = math.floor(p+(r2-p)*0.5) + local g3 = math.floor(p+(g2-p)*0.5) + local b3 = math.floor(p+(b2-p)*0.5) + + local color = string.format("%02x", r3)..string.format("%02x", g3)..string.format("%02x", b3) + + minetest.register_craftitem(":dye:"..val..hue.."_s50", { + description = S(desc.." (low saturation)"), + inventory_image = "unifieddyes_dye.png^[colorize:#"..color..":128", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..val..hue.."_s50", "dye:"..val..hue.."_s50") + end + end +end + +-- register the greyscales too :P + +for y = 1, 14 do -- colors 0 and 15 are black and white, default dyes + + if y ~= 4 and y ~= 8 and y~= 11 then -- don't register the three greys, they're done separately. + + local rgb = string.format("%02x", y*17)..string.format("%02x", y*17)..string.format("%02x", y*17) + local name = "grey_"..y + local desc = "Grey Dye #"..y + + minetest.register_craftitem(":dye:"..name, { + description = S(desc), + inventory_image = "unifieddyes_dye.png^[colorize:#"..rgb..":128", + groups = { dye=1, not_in_creative_inventory=1 }, + }) + minetest.register_alias("unifieddyes:"..name, "dye:"..name) + end +end + +minetest.override_item("dye:grey", { + inventory_image = "unifieddyes_dye.png^[colorize:#888888:128", +}) + +minetest.override_item("dye:dark_grey", { + inventory_image = "unifieddyes_dye.png^[colorize:#444444:128", +}) + +minetest.register_craftitem(":dye:light_grey", { + description = S("Light grey Dye"), + inventory_image = "unifieddyes_dye.png^[colorize:#cccccc:128", + groups = { dye=1, not_in_creative_inventory=1 }, +}) + +-- build a table of color <-> palette associations to reduce the need for +-- realtime lookups with getpaletteidx() + +for _, palette in ipairs({"extended", "split", "wallmounted"}) do + local palette2 = palette + + for i in ipairs(unifieddyes.SATS) do + local sat = (palette == "wallmounted") and "" or unifieddyes.SATS[i] + for _, hue in ipairs(unifieddyes.HUES_EXTENDED) do + for _, val in ipairs(unifieddyes.VALS_EXTENDED) do + local color = val..hue[1]..sat + if unifieddyes.getpaletteidx("dye:"..color, palette2) then + unifieddyes.palette_has_color[palette.."_"..color] = true + end + end + end + end + + for y = 0, 15 do + local grey = "grey_"..y + + if y == 0 then grey = "black" + elseif y == 4 then grey = "dark_grey" + elseif y == 8 then grey = "grey" + elseif y == 11 then grey = "light_grey" + elseif y == 15 then grey = "white" + end + if unifieddyes.getpaletteidx("dye:"..grey, palette2) then + unifieddyes.palette_has_color[palette.."_"..grey] = true + end + end +end + +unifieddyes.palette_has_color["wallmounted_light_red"] = true + +-- crafting! + +unifieddyes.base_color_crafts = { + { "red", "flowers:rose", nil, nil, nil, nil, 4 }, + { "vermilion", "dye:red", "dye:orange", nil, nil, nil, 3 }, + { "orange", "flowers:tulip", nil, nil, nil, nil, 4 }, + { "orange", "dye:red", "dye:yellow", nil, nil, nil, 2 }, + { "amber", "dye:orange", "dye:yellow", nil, nil, nil, 2 }, + { "yellow", "flowers:dandelion_yellow", nil, nil, nil, nil, 4 }, + { "lime", "dye:yellow", "dye:chartreuse", nil, nil, nil, 2 }, + { "lime", "dye:yellow", "dye:yellow", "dye:green", nil, nil, 3 }, + { "chartreuse", "dye:yellow", "dye:green", nil, nil, nil, 2 }, + { "harlequin", "dye:chartreuse", "dye:green", nil, nil, nil, 2 }, + { "harlequin", "dye:yellow", "dye:green", "dye:green", nil, nil, 3 }, + { "green", "default:cactus", nil, nil, nil, nil, 4 }, + { "green", "dye:yellow", "dye:blue", nil, nil, nil, 2 }, + { "malachite", "dye:green", "dye:spring", nil, nil, nil, 2 }, + { "malachite", "dye:green", "dye:green", "dye:cyan", nil, nil, 3 }, + { "malachite", "dye:green", "dye:green", "dye:green", "dye:blue", nil, 4 }, + { "spring", "dye:green", "dye:cyan", nil, nil, nil, 2 }, + { "spring", "dye:green", "dye:green", "dye:blue", nil, nil, 3 }, + { "turquoise", "dye:spring", "dye:cyan", nil, nil, nil, 2 }, + { "turquoise", "dye:green", "dye:cyan", "dye:cyan", nil, nil, 3 }, + { "turquoise", "dye:green", "dye:green", "dye:green", "dye:blue", "dye:blue", 5 }, + { "cyan", "dye:green", "dye:blue", nil, nil, nil, 2 }, + { "cerulean", "dye:cyan", "dye:azure", nil, nil, nil, 2 }, + { "cerulean", "dye:cyan", "dye:cyan", "dye:blue", nil, nil, 3 }, + { "cerulean", "dye:green", "dye:green", "dye:blue", "dye:blue", "dye:blue", 5 }, + { "azure", "dye:cyan", "dye:blue", nil, nil, nil, 2 }, + { "azure", "dye:green", "dye:blue", "dye:blue", nil, nil, 3 }, + { "sapphire", "dye:azure", "dye:blue", nil, nil, nil, 2 }, + { "sapphire", "dye:cyan", "dye:blue", "dye:blue", nil, nil, 3 }, + { "sapphire", "dye:green", "dye:blue", "dye:blue", "dye:blue", nil, 4 }, + { "blue", "flowers:geranium", nil, nil, nil, nil, 4 }, + { "indigo", "dye:blue", "dye:violet", nil, nil, nil, 2 }, + { "violet", "flowers:viola", nil, nil, nil, nil, 4 }, + { "violet", "dye:blue", "dye:magenta", nil, nil, nil, 2 }, + { "mulberry", "dye:violet", "dye:magenta", nil, nil, nil, 2 }, + { "mulberry", "dye:violet", "dye:blue", "dye:red", nil, nil, 3 }, + { "magenta", "dye:blue", "dye:red", nil, nil, nil, 2 }, + { "fuchsia", "dye:magenta", "dye:rose", nil, nil, nil, 2 }, + { "fuchsia", "dye:blue", "dye:red", "dye:rose", nil, nil, 3 }, + { "fuchsia", "dye:red", "dye:violet", nil, nil, nil, 2 }, + { "rose", "dye:magenta", "dye:red", nil, nil, nil, 2 }, + { "rose", "dye:red", "dye:red", "dye:blue", nil, nil, 3 }, + { "crimson", "dye:rose", "dye:red", nil, nil, nil, 2 }, + { "crimson", "dye:magenta", "dye:red", "dye:red", nil, nil, 3 }, + { "crimson", "dye:red", "dye:red", "dye:red", "dye:blue", nil, 4 }, + + { "black", "default:coal_lump", nil, nil, nil, nil, 4 }, + { "white", "flowers:dandelion_white", nil, nil, nil, nil, 4 }, +} + +unifieddyes.shade_crafts = { + { "faint_", "", "dye:white", "dye:white", "dye:white", 4 }, + { "pastel_", "", "dye:white", "dye:white", nil, 3 }, + { "light_", "", "dye:white", nil, nil, 2 }, + { "bright_", "", "color", "dye:white", nil, 3 }, + { "", "_s50", "dye:light_grey", nil, nil, 2 }, + { "", "_s50", "dye:black", "dye:white", "dye:white", 3 }, + { "medium_", "", "dye:black", nil, nil, 2 }, + { "medium_", "_s50", "dye:grey", nil, nil, 2 }, + { "medium_", "_s50", "dye:black", "dye:white", nil, 3 }, + { "dark_", "", "dye:black", "dye:black", nil, 3 }, + { "dark_", "_s50", "dye:dark_grey", nil, nil, 2 }, + { "dark_", "_s50", "dye:black", "dye:black", "dye:white", 4 }, +} + +for _,i in ipairs(unifieddyes.base_color_crafts) do + local color = i[1] + local yield = i[7] + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..color.." "..yield, + recipe = { + i[2], + i[3], + i[4], + i[5], + i[6], + }, + }) + + for _,j in ipairs(unifieddyes.shade_crafts) do + local firstdye = j[3] + if firstdye == "color" then firstdye = "dye:"..color end + + -- ignore black, white, anything containing the word "grey" + + if color ~= "black" and color ~= "white" and not string.find(color, "grey") then + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..j[1]..color..j[2].." "..j[6], + recipe = { + "dye:"..color, + firstdye, + j[4], + j[5] + }, + }) + end + end +end + +-- greys + +unifieddyes.greymixes = { + { 1, "dye:black", "dye:black", "dye:black", "dye:dark_grey", 4 }, + { 2, "dye:black", "dye:black", "dye:dark_grey", nil, 3 }, + { 3, "dye:black", "dye:dark_grey", nil, nil, 2 }, + { 4, "dye:white", "dye:black", "dye:black", nil, 3 }, + { 5, "dye:dark_grey", "dye:dark_grey", "dye:grey", nil, 3 }, + { 6, "dye:dark_grey", "dye:grey", nil, nil, 2 }, + { 7, "dye:dark_grey", "dye:grey", "dye:grey", nil, 3 }, + { 8, "dye:white", "dye:black", nil, nil, 2 }, + { 9, "dye:grey", "dye:grey", "dye:light_grey", nil, 3 }, + { 10, "dye:grey", "dye:light_grey", "dye:light_grey", nil, 3 }, + { 11, "dye:white", "dye:white", "dye:black", nil, 3 }, + { 12, "dye:light_grey", "dye:light_grey", "dye:white", nil, 3 }, + { 13, "dye:light_grey", "dye:white", nil, nil, 2 }, + { 14, "dye:white", "dye:white", "dye:light_grey", nil, 3 }, +} + +for _, i in ipairs(unifieddyes.greymixes) do + local shade = i[1] + local dye1 = i[2] + local dye2 = i[3] + local dye3 = i[4] + local dye4 = i[5] + local yield = i[6] + local color = "grey_"..shade + if shade == 4 then + color = "dark_grey" + elseif shade == 8 then + color = "grey" + elseif shade == 11 then + color = "light_grey" + end + + minetest.register_craft( { + type = "shapeless", + output = "dye:"..color.." "..yield, + recipe = { + dye1, + dye2, + dye3, + dye4, + }, + }) +end + +-- we can't make dark orange anymore because brown/medium orange conflicts + +minetest.register_craft( { + type = "shapeless", + output = "dye:dark_orange", + recipe = { + "dye:brown", + "dye:brown" + }, +}) + +-- aliases + +minetest.register_alias("dye:light_red", "dye:pink") +minetest.register_alias("dye:medium_orange", "dye:brown") + +minetest.register_alias("unifieddyes:black", "dye:black") +minetest.register_alias("unifieddyes:dark_grey", "dye:dark_grey") +minetest.register_alias("unifieddyes:grey", "dye:grey") +minetest.register_alias("unifieddyes:light_grey", "dye:light_grey") +minetest.register_alias("unifieddyes:white", "dye:white") + +minetest.register_alias("unifieddyes:grey_0", "dye:black") +minetest.register_alias("unifieddyes:grey_4", "dye:dark_grey") +minetest.register_alias("unifieddyes:grey_8", "dye:grey") +minetest.register_alias("unifieddyes:grey_11", "dye:light_grey") +minetest.register_alias("unifieddyes:grey_15", "dye:white") + +minetest.register_alias("unifieddyes:white_paint", "dye:white") +minetest.register_alias("unifieddyes:titanium_dioxide", "dye:white") +minetest.register_alias("unifieddyes:lightgrey_paint", "dye:light_grey") +minetest.register_alias("unifieddyes:grey_paint", "dye:grey") +minetest.register_alias("unifieddyes:darkgrey_paint", "dye:dark_grey") +minetest.register_alias("unifieddyes:carbon_black", "dye:black") + +minetest.register_alias("unifieddyes:brown", "dye:brown") + +print(S("[UnifiedDyes] Loaded!")) + diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/oldcoder.txt b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/oldcoder.txt new file mode 100644 index 0000000..64882f8 --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/oldcoder.txt @@ -0,0 +1,17 @@ +Name: unifieddyes +Source: Slightly modified upstream mod +License: See "README.txt" + +---------------------------------------------------------------------- + +1. This is a slightly modified version of an upstream mod. The start- +ing point was obtained originally as follows: + + rm -fr unifieddyes + git clone https://gitlab.com/VanessaE/unifieddyes.git + +---------------------------------------------------------------------- + +2. Changes include: + +2a. Added the files "00README" and "oldcoder.txt" (this file). diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/textures/unifieddyes_dye.png b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/coderbuild/unifieddyes/textures/unifieddyes_dye.png new file mode 100644 index 0000000000000000000000000000000000000000..c86edf69feb36894acbc469f2cf97f0ee0bc96e8 GIT binary patch literal 1089 zcmV-H1it%;P)XX1I|fA zK~z}7?Uuhw^J)~wKk>boK}*4E2q_UdWYEc>CT=2K#HAp(^$&0eh)d_YxH$VCxC<_B z72MJvL$_K23JsP}saQh5OwV23=eg~xzW3F8x$uH#dCJMte9!ls?>Q&%WncEYS`Y+c zJRXa?yF2l3-ZS@^KS|Iq3>l3^RI63-zXcEkfv_x#jg1Wq!%+Uu1~K;MJhCwcuBbUojuh%~u#2>$Uu~w@I!!XFQjNxzyz-Tn$;^G3!vH%zkhj^YRn$4#6 zpJt#|s|nxt$>;N=X{x{_s61sLmSz2NCbWM7wk(VN{e2wAVPRo`G))P^5CFq47>!08 z9UZZ~y-mO02Oy4Py4@~?LIK;h`B_HZEy3B@nHUTP42MG;$C+U}4c_T=W}fA8IpR2` zP$)1Sj~S200OCEe+FL?vG#X4M6Alj#8I49WYL_O#2ZO;3^C*h2Z5u#kVLTp_Wf`95 z(d~B0vP^pwz}eZED3{BMQMp_O!1Fwwo}QRYCaUfLolb{xxy;eg5vFMp$Fa)P_4PHj zZO;VLY&I3$MMrpfN^F4byPfdkCd>vgfZx{6^K_`c6%GQltm^7;Im!jt7`G#UUnjzhcMRsxi# zWGzb($1wn|>ryBbRIARNo}OxZdwVLqrBaDfsl;S5A|SX^LSOq-m;@zp}Ez^71mpVv%C8$iu?}uIsYCzRu(0BlGj~ z6pKX`7Z=rgT-W8{;X(cG_xs%5-fG(SRuj!;QwxGXO!xdWds%|%^Z599hL!8O^m;wk z*4F6tdL&8mCi~0F%hz+@#DBRDC*ANPXxvqcn!A&%qV`@X7w zr_&(_0=BlcX4>&bmJ+ntY-*Ne3CZ|F+fbUW>*CXB9uIobAbzxbS&~;tN{qK36&~;s%U!Uz?_S@KBI(b45`Vhj200000NkvXX Hu0mjf=#L7O literal 0 HcmV?d00001 diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/license.txt b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/license.txt new file mode 100644 index 0000000..678089f --- /dev/null +++ b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/license.txt @@ -0,0 +1,60 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT + + +Licenses of media (textures) +---------------------------- + +Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +Copyright (c) 2012-2016 Perttu Ahola (celeron55) , Copyright (c) 2022 Jake "Poikilos" Gustafson (all dyes redrawn) + +You are free to: +Share — copy and redistribute the material in any medium or format. +Adapt — remix, transform, and build upon the material for any purpose, even commercially. +The licensor cannot revoke these freedoms as long as you follow the license terms. + +Under the following terms: + +Attribution — You must give appropriate credit, provide a link to the license, and +indicate if changes were made. You may do so in any reasonable manner, but not in any way +that suggests the licensor endorses you or your use. + +ShareAlike — If you remix, transform, or build upon the material, you must distribute +your contributions under the same license as the original. + +No additional restrictions — You may not apply legal terms or technological measures that +legally restrict others from doing anything the license permits. + +Notices: + +You do not have to comply with the license for elements of the material in the public +domain or where your use is permitted by an applicable exception or limitation. +No warranties are given. The license may not give you all of the permissions necessary +for your intended use. For example, other rights such as publicity, privacy, or moral +rights may limit how you use the material. + +For more details: +http://creativecommons.org/licenses/by-sa/3.0/ diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/projects/dye-poikilos.xcf b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/projects/dye-poikilos.xcf new file mode 100644 index 0000000000000000000000000000000000000000..6ec765527abadcc7fbd4ce9c5ce52ba9b7ecf724 GIT binary patch literal 52894 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 literal 0 HcmV?d00001 diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_black.png b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_black.png new file mode 100644 index 0000000000000000000000000000000000000000..193d24b961af6116e6a1ccdde28e4ec8f046dae3 GIT binary patch literal 940 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 Z_9wF!pX0DT1wa4*002ovPDHLkV1kof(gXki literal 0 HcmV?d00001 diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_green.png b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_dark_green.png new file mode 100644 index 0000000000000000000000000000000000000000..9fab3d2daea4534f5264d283aca6c26769ee5375 GIT binary patch literal 1021 zcmVTgO{%HrmmR+)LYRpQvt8_ z=Al!T4jD6~Q&$%V5ZIFhB@rq^21D^Alj3za9VJ?B_e;Mgx6DJI|MY_b7zG0oDdD?s)V~&hcX*&yimQnA&#;A< z{;^~bxsN4Z+pJ>SMbdFXekF%31pax9e;(sKeXRbm0Q}~jvV|a3Aj5!hoaz+3IYm}n zWW_~X1n}gM`s4xl%{?U>JLFe#B$pw8&OK<-$yruh{Xp}f`ZQhe7AY6t!~iE>!6Sl`XLl-C>7!Gh4s-6_{}}#t!^ML0t#*!fOvSx zI8HNifKsPB=Y)SA>lYMk7{$>40AGKl{=NhIyNY!OKeCA*+$WK8zS<`+DJXTivde?7#B)KSYHFD2&Zo~`AnhCIp95gta@&qT78Svf}<7MIf7wCJiN?^Te6F{ z)u4BFf*;vhd}D{+*$D`-=!Ch~51|)8xd5U7$FD5g3=yxkP4D6zwfYvLV8B?U2*)Li z(~LY*Y#;<}wDMl(R1+CO1LKAe`nb0VZ~uVfSC&q}gxnSauX2}hoMH=+**+Qs*}H5Z zsEevrfALPIF0yG8P7Cn7KP^PiE<{7^06^K%shPBDj%Uv;(@wS!2**V@F5@^QNrstn zvnHxlDRsJdmAg=OXx~}UBvNL9v`fjn111$Fh&$`kF7OTy)NES`$K`SqX63X<4QP+eg1x-r<3o?fF^tCWu+|I;V>yvoM5L@$9*^(1w0sS!Re@gT(vOo}QxiJQ{$pffx68rOAse}5;-GU~b}%QBvypD|4n(=@5;n(=tt{BZzDk~Co$VwxuV z{T_g#C;+JIT3=1m1Yk58HGf0}s8=hA5?2E|X{v*UVMv;$SeEsn65>-zk!2Z< z<6v19%jMEAWrz$012&rtQ50#J`Myt{=Q=pRdcD?wEz2U$b2^<4tJMn2vb0}JRAX5d zK@boG0lVE!x8Y2JyRJ*G*Q2g$T-Vi-5|Rn=`u#pp6tUTCblJDtttMce=Q?xo?e}}C zssg}q98A;HQazi^W`@YgbzOYlN0v-gRXTHd$MZatQuKN~9LLe6uBu7{$@BcE0s=@t zNZSC6>2%t(W##+6CS9BDZSt+x>!UKC+Gia2>K*gt_T zoqrYh+lSIPj+^$jTP~MI9LJ43xBWk7{vZ2a*k7R43U`7daoYd@002ovPDHLkV1n5| B$Qb|t literal 0 HcmV?d00001 diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_green.png b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_green.png new file mode 100644 index 0000000000000000000000000000000000000000..6b8a0ae943fc027e271c50c008e5ec3970ac4b2c GIT binary patch literal 1008 zcmVXPBMmeV+GY z7H;gu{$q2N{cvwT%+~5EOjKQ( z>w=1K?fSA#IPWa`dQ(p(2>_{@^71F`NG*_j`FZU8BMLlt6lE3Rk`+?Yvp-4Il#}6@ z?yrhkAgKkCq%U~-?A??oye)XNE%DqHoKyiYl6p+~!j82-p6`EqC$5$2=`%8?6wF^aX46G63>S zk*cW$2k3YGIVA?Y2+-i^7zW4i>1T@-x#Zc-E?K<^GKtvwL@|HgVPvoI> z*b@L9WD+sx#^-bF2v{{d0WATo525!)g98){ctyBWgOF5BsR-A~u9C4mtRh^BVuNr~ zJF5XApkoto(3>S9Xcc6l6#yvtIy9zK3-|Bgm~yHJ7q7ainX4&9MwYqR6SPn1cYUfs zNXdsrtAnT+fX+E+XHEeV3gbkhm8*ii{V>ayl~-MbNn*>*IAF}=KwjpHc2y26+EeJf z5OiM5c9=Gsw|vb9?Nf?kgOZPZ02=L(Mq8`m3C+?IGjOvn|Ni(Pj$=yj@xzX@w;yKt zn$NR0A;{aH8_&)2AOL@zUaipmd$a0u@_oRRlX2pzCX{bLLHpDu<08D{SbKPBF-lJ`48DAU?@KtiB zQUgACL}nN-^+U3=OXilNxe^;5>!xCunYoFvsq;m^OaGMa?COKvGN`fcXxc$N&#&M7 e^WWJ2!u|$;2EFSfP;J`)0000(^b1BppQ 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 literal 0 HcmV?d00001 diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_pink.png b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_pink.png new file mode 100644 index 0000000000000000000000000000000000000000..6a19bcddc913b7d1e5c88c386b646b0f3a8a04f1 GIT binary patch literal 1101 zcmV-T1hV^yP)a{mtxWECCLuuuNiiAd$P+M9X*x-1bT`yiw56g@eOrpk0TUFwbteqL} z&hx&{`!NG2IKh7mtHN__;!^icW#S+&4BV^ zQD{bjSoSY0c%0a%%u z5^p2~kEW-EG1yP?{5hhT99lGn@SFHn1%RlT!ndnb7M3vv`|&rof~eRo)@~KON5?b_ zuFTA6udP67eoh#J{nT4AqL~~3!l{GTP~-qk%{`=q`}R8k=sh~Folf)P`Z_mfXSHym9#Y`xw_l4cYn#ONPly=-=4_3*Ik5O4z zrd1dKAm5jzvapP9#@m#TYu0X+&B_+1%?zh{;@r4@Pm9PVQeG@7a^I>1r3UyfY(*|T zme9>Ok@XD#_EuKW&A3{ZqALu06!9?W@gY?4|c|Ej&MUE{R*)$J&0z=-s=TR$eTM za9KrCnV`)cl$#`#kU1dbJ`Ts_z{}o={rTHA0KJz}%JZX;4M%#;$S~UGhWg*F?UNoI z4#o$e$s8e#C%bTK`)cgjZlHiH!KWI2UnezXZ4mj|yR4SOyj>P)LjXK(L`JXfLHudg$5b^aJ!m^b7dx zb51$*)?yu;Lm{wDAR?qjvgFFGkZX3KN~NsX>0x%pD@!r9C@lp)5ZZmr%>TXr`@c5} z*LH3Hv59#%c70dM+f^71S$ViS_c_))n>t_DC4e|=AqIUKHu7H!pzFJm(oN(CHDqPU z_~#8mTopXIcVBJ%t*@M;A&vbL0G3}zeER(0N@wOSyKu)_m$Fhu#AEoir-B&tc{zB+ za=NCs;P43Kmsd#4x-59ziD9t_$Dsk&p!$FLb)?oK-YHm!>Xc}MWsq6`! zQ9@1x^8$-MfbU2|R;UvU{7_q!?{*GwzWM_Bp2|9T=N32iUqE<_81!kK=85(KJl`c~ zG!1Coi3u7_9DAAx?K{Gv4U_=~ct9d7Jw&>`Yrw@}3(;0WyYYM5fCEH(feF~Lp%gq- zj67E0#-DQmd(<@o7Pynk!~-v#^dJ1dlm!~)w9fxnLP(|J7sHrehAId!9}3u{IpNke`*fsDG1>C?qoNl_kb?X z&kuKTHa)62b^7^0f2d3@?anW6%pX*L+GCu#WfoIVj#R_l-A$7)ceUNNp z$%6N>YO!?i9ARgSW)p z2)}jA>*y7QphzJoa$+5DkH_MZ2e9l`#6nOeJ)#qaz4@C_2*8PTpw5M$2*6z`;*)g2 zJsyiGC(8^jc6OY!o+6Ik;kS+f$mu4{C}hLiV#>+lduaed0va5llfl5^IS;gtc3|19 zh$$z_iFJUT9S0z4b%?u>A_ws7dY==qyAOa)hKM!|4*7=f#0NXD#Hz@16T=NCpWUGu zg?-g7AyeSlbq;GNUA zkvXTtu6M{>$;EFS6L(GQ;waj0x+0f~B}^>B9WdO0ZLf}*Ae4}9m{^!tI85WQN0l`V zASKCjy2*?)LEMeV>87&1aeAgE%jqW5vlffaJiFc@&?7(IK^5Q;`>GHD3@qB`DFU#` zqmxmsntH;0O}0}`@2R$nqr}~aPLNj0Z_`}YMw(e|-WX~tn%OH~2_UZ#9 zNl3zrc*1>cpbeMZUQsLrWtEQ07NO(<CG=p&sx2dB&?U%rPfz)vH&mc3)m_c`F zt+8A#vD@vCWtnmdb)dlUc;vqCZ-RGShq|tjBnhgjg4P-U5QZVDswAN^v#xj+>yF*G8anmBLs%}lVTWRopA8p$XoVy^d67F8qA|kBUYo%TRuj_i? zbZk>KaP1oN0n*uwJj##T<|+C~bDH9T$rQeBZaykM0My=-j}@=Yo3V_zlBw zkbid-;3>I{F-X%?6-B|q_@z5xp68sVsg+MwckIeuax8s*4fy3tX`bio<~GYRmFGFj h-hKYL^MCBWuwMY@smrL_GNb?i002ovPDHLkV1il)H{1XK literal 0 HcmV?d00001 diff --git a/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_yellow.png b/Bucket_Game-branches/dye-redrawn-vs-220114/mods/codercore/dye/textures/dye_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..f9901a82705f229dad3f7712789f7b8445068d43 GIT binary patch literal 1009 zcmVe|O?W9V<8^Q_EJduq!))0z#q*-T;{u2(e&8*WK^{JPQxN8#Ifu zsF1R9)C$QGEGqs<8LM`%gDuy_7E;S_npt}XF8hS7 zx&^Inx`eGdne1sL%v`?*2OaR%A@dS^_!%l?n#fVc=UTeX@aY{ywQ&fEq{M9H0GWdW ztWNiAz?m#SgTrBs)TBOt$KF8)V&*bg*mwi>f70LpjsX|R@g($#2ocHQke<7=XEzhc z@!Z`eUDm-G+1FAHYrxLqVdcm?eXQ>sq+Cd!nPNRCKK`Xc0t`qMHuYrMQ- z+!vmNK3)M{-}vWlc+O&522+F{gCYLAhRpAM2Yo#x~Uju=H2Aj)cGRdrGH9ycl5@t3)89YXuCUzd5_Ou f{_|gs|Hb$REkn3>a<*1D00000NkvXXu0mjfcF)yZ literal 0 HcmV?d00001