diff --git a/build.gradle b/build.gradle
index 9a63aa1d..6a761c45 100644
--- a/build.gradle
+++ b/build.gradle
@@ -75,6 +75,16 @@ repositories {
url = 'https://maven.blamejared.com/'
content { includeGroup "mezz.jei" }
}
+ maven {
+ name = 'Architectury API'
+ url = "https://maven.architectury.dev"
+ content { includeGroup "dev.architectury" }
+ }
+ maven {
+ name = 'KubeJS and Rhino'
+ url = "https://maven.saps.dev/minecraft"
+ content { includeGroup "dev.latvian.mods" }
+ }
maven {
name = 'ModKit'
url 'https://jitpack.io'
@@ -85,17 +95,21 @@ repositories {
dependencies {
minecraft("net.minecraftforge:forge:${mc_version}-${forge_version}")
- // TOP
- implementation(fg.deobf("mcjty.theoneprobe:theoneprobe:1.20.0-${top_version}") {
+ // TOP OPTIONAL
+ implementation(fg.deobf("mcjty.theoneprobe:theoneprobe:1.20.1-${top_version}") {
transitive = false
})
// JEI OPTIONAL
compileOnly(fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}"))
compileOnly(fg.deobf("mezz.jei:jei-${mc_version}-forge-api:${jei_version}"))
- // at runtime, use the full JEI jar for Forge
runtimeOnly(fg.deobf("mezz.jei:jei-${mc_version}-forge:${jei_version}"))
- // not required for players
- implementation fg.deobf('com.github.thedarkcolour:ModKit:ea67392fd6')
+ // KubeJS OPTIONAL
+ //implementation fg.deobf("dev.latvian.mods:kubejs-forge:${kubejs_version}")
+ //implementation fg.deobf("dev.latvian.mods:rhino-forge:${rhino_version}")
+ //implementation fg.deobf("dev.architectury:architectury-forge:${architectury_version}")
+
+ // ModKit DEV ONLY
+ implementation fg.deobf('com.github.thedarkcolour:ModKit:0aab5a727b')
}
def replaceProperties = [ mc_version: mc_version, mod_version: version ]
diff --git a/gpl-3.0.txt b/gpl-3.0.txt
new file mode 100644
index 00000000..f288702d
--- /dev/null
+++ b/gpl-3.0.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/gradle.properties b/gradle.properties
index 3db35286..201c7e3f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,11 +5,15 @@ org.gradle.daemon=false
org.gradle.cache=true
mc_version=1.20.1
-forge_version=47.0.34
+forge_version=47.1.43
parchment_mappings=1.20.1-2023.06.26
geckolib_version=4.2
modonomicon_version=1.36.0
-jei_version=15.0.0.12
+jei_version=15.2.0.23
curios_version=5.2.0-beta.3
-top_version=9.0.0-1
\ No newline at end of file
+top_version=10.0.1-3
+
+kubejs_version=1902.6.1-build.349
+rhino_version=1902.2.2-build.269
+architectury_version=9.1.12
\ No newline at end of file
diff --git a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d
index 1f051af4..d474bd0c 100644
--- a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d
+++ b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d
@@ -1,16 +1,42 @@
-// 1.20.1 2023-07-27T10:58:18.8937589 Loot Tables
+// 1.20.1 2023-07-31T21:35:51.0164401 Loot Tables
326c04383bd2178850f0515fba6dc9c9bfce07cc data/exnihiloreborn/loot_tables/blocks/acacia_barrel.json
+6cb2acba921254f40fde2dc401e8d3d4d17c6763 data/exnihiloreborn/loot_tables/blocks/acacia_crucible.json
+46e54a49cc83124bed7676f3ea013428a0d14116 data/exnihiloreborn/loot_tables/blocks/acacia_sieve.json
+46b9870a77e6f4996fde0605c5b4f67ec19cf289 data/exnihiloreborn/loot_tables/blocks/bamboo_barrel.json
+c5265d5cc32c08c9818b54d04463f646e22e27f5 data/exnihiloreborn/loot_tables/blocks/bamboo_crucible.json
+86a2d86896055e9ddf2fba482ddce1060ca44df0 data/exnihiloreborn/loot_tables/blocks/bamboo_sieve.json
7239ee3a1d8ca43b6ac84a308a4af5063241db24 data/exnihiloreborn/loot_tables/blocks/birch_barrel.json
-55e7e691d4f48b13c4bbde87da7927e9bd983c3e data/exnihiloreborn/loot_tables/blocks/compressed_cobblestone.json
-0e7be00762d28aa5a28f564f232a18170a861a8a data/exnihiloreborn/loot_tables/blocks/compressed_dirt.json
-b5d0a1f20d7677abc42536c369b5702c67a676c1 data/exnihiloreborn/loot_tables/blocks/compressed_dust.json
-350a3a81e4141b346808c77cfa4e8a5dbc3a5a2f data/exnihiloreborn/loot_tables/blocks/compressed_sand.json
+a6a1f06aa0e46e1db326e2f7c760d810bcdf8736 data/exnihiloreborn/loot_tables/blocks/birch_crucible.json
+efdb072ac0167cb84c2f4c99f0d751e2882a77d8 data/exnihiloreborn/loot_tables/blocks/birch_sieve.json
+5b046dc403c76960518134a80abcd41e55817e0d data/exnihiloreborn/loot_tables/blocks/cherry_barrel.json
+94de9d3f2c85597f72933d91916ab18e79bead9c data/exnihiloreborn/loot_tables/blocks/cherry_crucible.json
+5b2c7686aa10bf68fc3e017b594392e2c48d1f72 data/exnihiloreborn/loot_tables/blocks/cherry_sieve.json
c10ee8c3fe5e00ee3362596a2f5ed9349ca5d6c1 data/exnihiloreborn/loot_tables/blocks/crimson_barrel.json
+a1357ed43b9f8f5d49f011b024a50ad10c29f4fb data/exnihiloreborn/loot_tables/blocks/crimson_crucible.json
+b50559a54e3229686397cf2eb8bf631564a31c0c data/exnihiloreborn/loot_tables/blocks/crimson_sieve.json
+d19ed769a379e164276a40db99e57245a51b7a79 data/exnihiloreborn/loot_tables/blocks/crushed_end_stone.json
+89afb6804eba5e6eb815491166f9b96bd6753765 data/exnihiloreborn/loot_tables/blocks/crushed_netherrack.json
05efa87a7fb08d988544756d596ebe53dd0584c8 data/exnihiloreborn/loot_tables/blocks/dark_oak_barrel.json
+152369c6ecb44f7b35e73e271b72fd1a18aacb34 data/exnihiloreborn/loot_tables/blocks/dark_oak_crucible.json
+b8ea657d0f5ced81be30958de78bdf7157084451 data/exnihiloreborn/loot_tables/blocks/dark_oak_sieve.json
9354ad853e29c5a051f3319b66c19b0649be43a1 data/exnihiloreborn/loot_tables/blocks/dust.json
eebb19a95fba75bb9abaaad7a7cd731f06351d9b data/exnihiloreborn/loot_tables/blocks/infested_leaves.json
da7317e6905aee49b47b9cf98d89d6a38379a34e data/exnihiloreborn/loot_tables/blocks/jungle_barrel.json
+2039b4bfd346f7fb4ddde00e93917711e51fab83 data/exnihiloreborn/loot_tables/blocks/jungle_crucible.json
+8a49d7530a5b76825066c14c0acc153d8c06ee10 data/exnihiloreborn/loot_tables/blocks/jungle_sieve.json
+bec066e549155dfab4b9d8b10969f68ff856f86d data/exnihiloreborn/loot_tables/blocks/mangrove_barrel.json
+8a90519c2f66d42f180815c4541e99fdf231fa3e data/exnihiloreborn/loot_tables/blocks/mangrove_crucible.json
+93c22058463f1eaf67377b15364353a10c33219e data/exnihiloreborn/loot_tables/blocks/mangrove_sieve.json
bd38cae64c70238e95529bd16f512f1a2ef2f69f data/exnihiloreborn/loot_tables/blocks/oak_barrel.json
+9c0d3237a137466dd9932c9ed0674091232b4c4c data/exnihiloreborn/loot_tables/blocks/oak_crucible.json
+53bc915538b94ca3e283fac0e4ea05b568afef19 data/exnihiloreborn/loot_tables/blocks/oak_sieve.json
+ba39872b9abcdd6a802384b767128791619d3071 data/exnihiloreborn/loot_tables/blocks/porcelain_crucible.json
93a2689c6f6fb689910982ddc9ac927c7432bfe2 data/exnihiloreborn/loot_tables/blocks/spruce_barrel.json
+20d4057ea0052a6a655970741277f25ce838778b data/exnihiloreborn/loot_tables/blocks/spruce_crucible.json
+886511787a83f7d4fe61d3d6428c9899d823f8c2 data/exnihiloreborn/loot_tables/blocks/spruce_sieve.json
5ab70649c89c6ab9d14fdd95e053d591d8941076 data/exnihiloreborn/loot_tables/blocks/stone_barrel.json
+8d754d5573180a44ef28d81dfd37c2b5c0540ded data/exnihiloreborn/loot_tables/blocks/unfired_crucible.json
611f523b7a6b5b323e07d5e8a76620858559e8b8 data/exnihiloreborn/loot_tables/blocks/warped_barrel.json
+8eb07e6ebd117eaebab367376b4f4249d77ca4ef data/exnihiloreborn/loot_tables/blocks/warped_crucible.json
+ebbeed42b18550f359595bf922f74aba6aa60d32 data/exnihiloreborn/loot_tables/blocks/warped_sieve.json
+9368ef21629743383c2f8f20580c3724cbb15e61 data/exnihiloreborn/loot_tables/blocks/witch_water.json
diff --git a/src/generated/resources/.cache/5f5ddf0caee48d851cd5055dbc7b23dfdcd4b8a5 b/src/generated/resources/.cache/5f5ddf0caee48d851cd5055dbc7b23dfdcd4b8a5
index 0952b63d..be074251 100644
--- a/src/generated/resources/.cache/5f5ddf0caee48d851cd5055dbc7b23dfdcd4b8a5
+++ b/src/generated/resources/.cache/5f5ddf0caee48d851cd5055dbc7b23dfdcd4b8a5
@@ -1,2 +1,2 @@
-// 1.20.1 2023-07-27T12:51:19.3141363 ModKit Language: en_us for mod 'exnihiloreborn'
-7883d6bd9bf13e07fe9b9dca3a2b85891c0a34fb assets/exnihiloreborn/lang/en_us.json
+// 1.20.1 2023-08-03T17:20:09.1082545 ModKit Language: en_us for mod 'exnihiloreborn'
+40c18b2dfd4feb7f50301c175737606df110b746 assets/exnihiloreborn/lang/en_us.json
diff --git a/src/generated/resources/.cache/86e8fad2261d20af97e8edef657773f7c7b2823e b/src/generated/resources/.cache/86e8fad2261d20af97e8edef657773f7c7b2823e
index 9e91412d..9a7a8f9a 100644
--- a/src/generated/resources/.cache/86e8fad2261d20af97e8edef657773f7c7b2823e
+++ b/src/generated/resources/.cache/86e8fad2261d20af97e8edef657773f7c7b2823e
@@ -1 +1,3 @@
-// 1.20.1 2023-07-24T13:27:44.3296716 Tags for minecraft:block mod id exnihiloreborn
+// 1.20.1 2023-07-31T21:25:34.8783191 Tags for minecraft:block mod id exnihiloreborn
+723f7e0bbd67dd36d5792d6579191914b86bae39 data/minecraft/tags/blocks/mineable/axe.json
+44b29639f893e2ce6c13400a7d594d7426b05ded data/minecraft/tags/blocks/mineable/pickaxe.json
diff --git a/src/generated/resources/.cache/88728e8b0aba78bc481ee96e4ac0a48656a2d2b8 b/src/generated/resources/.cache/88728e8b0aba78bc481ee96e4ac0a48656a2d2b8
index e2c86408..60755322 100644
--- a/src/generated/resources/.cache/88728e8b0aba78bc481ee96e4ac0a48656a2d2b8
+++ b/src/generated/resources/.cache/88728e8b0aba78bc481ee96e4ac0a48656a2d2b8
@@ -1,7 +1,8 @@
-// 1.20.1 2023-07-27T11:42:20.2188641 ModKit Item Models for mod 'exnihiloreborn'
+// 1.20.1 2023-08-03T17:20:09.109254 ModKit Item Models for mod 'exnihiloreborn'
b04ca14f505feb0c3145a0ec24e482f569fa1f8b assets/exnihiloreborn/models/item/acacia_barrel.json
a3c0b9510b70d74c0c5430d782d9582378143599 assets/exnihiloreborn/models/item/acacia_crucible.json
535cff3f576461aebe434a1ec8f9711776898e5f assets/exnihiloreborn/models/item/acacia_sieve.json
+4e80010d91a1d6afd3a590bef246b592e9ded9b9 assets/exnihiloreborn/models/item/andesite_pebble.json
a88334b623bd893eeb3068d6fb41879258a71043 assets/exnihiloreborn/models/item/bamboo_barrel.json
77e1e0a00a28bf81a6453ccd79ec2298bad6456d assets/exnihiloreborn/models/item/bamboo_crucible.json
96a8ac56018b941030e3723fd6c668d5e6f077b7 assets/exnihiloreborn/models/item/bamboo_sieve.json
@@ -13,7 +14,7 @@ d634e2fbb0b1149fcbbebbc45e619b4670f6703a assets/exnihiloreborn/models/item/birch
857e1c605e0c00e54ff9815933cf62399e360cac assets/exnihiloreborn/models/item/cherry_crucible.json
203704e4f975d9fb6a5883e47dc986d3f7ff05f6 assets/exnihiloreborn/models/item/cherry_sieve.json
24a5c572fd594b8e5acce55cf529be866f4e886a assets/exnihiloreborn/models/item/cooked_silk_worm.json
-039a1c59b83319648aba5daa1af2af2c9e73a505 assets/exnihiloreborn/models/item/copper_ore_pieces.json
+ae8ff39148346b364f4104316e9a0762f8ebc63b assets/exnihiloreborn/models/item/copper_ore_chunk.json
80502debe44d9fcb8c01b307939d32c47d6b87f1 assets/exnihiloreborn/models/item/crimson_barrel.json
ea89af27e1fe1cb2303b38d79159e8902f97f4a3 assets/exnihiloreborn/models/item/crimson_crucible.json
7af13e06a0c7cb8341b654a6f8ae4dc6f1192a43 assets/exnihiloreborn/models/item/crimson_sieve.json
@@ -26,13 +27,16 @@ ea89af27e1fe1cb2303b38d79159e8902f97f4a3 assets/exnihiloreborn/models/item/crims
eeb577a82f53d7402e319e885940c22dab7fc013 assets/exnihiloreborn/models/item/deepslate_pebble.json
1d9e7750ac92f1a7fb9eefefeabd88b007a418c9 assets/exnihiloreborn/models/item/diamond_hammer.json
6bfbf0110e79fc4a3d23f19c717b30fc0b802142 assets/exnihiloreborn/models/item/diamond_mesh.json
+11e2b9f314b00c78a7b8f2727975ef686d515b59 assets/exnihiloreborn/models/item/diorite_pebble.json
4c3b1319ea57598dad8c71f9aaa5676d2c37df57 assets/exnihiloreborn/models/item/dust.json
0c3725d74213d85a332226d2a2472a5c4a0f66cd assets/exnihiloreborn/models/item/flint_mesh.json
76282a4cd8b8f6aa0c5d72677be3173827eb3ff6 assets/exnihiloreborn/models/item/golden_hammer.json
-22c8f2d53b0473d9df577536b5f0270ae63bf5bd assets/exnihiloreborn/models/item/gold_ore_pieces.json
+92a10f91557166dad46417e6a2b107d3e4aca206 assets/exnihiloreborn/models/item/golden_mesh.json
+df2918f82a8ccdcfc8e2e39a01a8d9dbd187f537 assets/exnihiloreborn/models/item/gold_ore_chunk.json
+286f56e322262c2336950c87dc493f35a3f1794b assets/exnihiloreborn/models/item/granite_pebble.json
30f28bafa588f7c036744d4507718734d4c781e7 assets/exnihiloreborn/models/item/iron_hammer.json
de8a49ab10ece0aab2442e774dde8dc183783401 assets/exnihiloreborn/models/item/iron_mesh.json
-565691b30362d5c4587b9c7a4b3245f2f1023147 assets/exnihiloreborn/models/item/iron_ore_pieces.json
+78f75aeb34fef71e0d73a2fb3981e3e8b3a09f44 assets/exnihiloreborn/models/item/iron_ore_chunk.json
318d5f172fdb062a59953353de55d56ed9d76642 assets/exnihiloreborn/models/item/jungle_barrel.json
a4f6b856970f9f039deb71f07e02764be185a366 assets/exnihiloreborn/models/item/jungle_crucible.json
e449e5fab8da5d332373caa04929b901f83aeb78 assets/exnihiloreborn/models/item/jungle_sieve.json
@@ -55,6 +59,7 @@ ca863a6c57b74743105f20bd9e84bddde78b754b assets/exnihiloreborn/models/item/spruc
66b6eaeeb75466603a8aa9438b11fc73e5c77f2f assets/exnihiloreborn/models/item/stone_hammer.json
44481e3cbb4765019d9cde572a18e17d0b878f24 assets/exnihiloreborn/models/item/stone_pebble.json
1eba49433a0cb08b803369899e10795c949bc45a assets/exnihiloreborn/models/item/string_mesh.json
+c92fdc69afd163a6f4c8b3a0fe473da3b098d426 assets/exnihiloreborn/models/item/tuff_pebble.json
786bc050fc466f27c3ae77524c36ebfa1c3de611 assets/exnihiloreborn/models/item/unfired_crucible.json
e8a646e41fbdf8748b28bdee70d2e5674fab35f4 assets/exnihiloreborn/models/item/warped_barrel.json
1510e5ebe284711da4a8b83ee4e5d17daa75d7ca assets/exnihiloreborn/models/item/warped_crucible.json
diff --git a/src/generated/resources/.cache/9e63038493dc91d16be52c0edde554af2820040f b/src/generated/resources/.cache/9e63038493dc91d16be52c0edde554af2820040f
new file mode 100644
index 00000000..25d78fa3
--- /dev/null
+++ b/src/generated/resources/.cache/9e63038493dc91d16be52c0edde554af2820040f
@@ -0,0 +1,2 @@
+// 1.20.1 2023-08-02T19:12:05.2741196 Tags for minecraft:fluid mod id exnihiloreborn
+2eeaca82c985b533806e320dd8df746fb3d38a65 data/minecraft/tags/fluids/water.json
diff --git a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e
index fe1b3f64..4390af84 100644
--- a/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e
+++ b/src/generated/resources/.cache/9fb1092f32d4fcbf9e061ffd718d4ec689c6c95e
@@ -1,19 +1,26 @@
-// 1.20.1 2023-07-27T12:51:19.3161371 Recipes
+// 1.20.1 2023-08-03T17:55:15.053135 Recipes
a3e58be04205964a0b890880f040d2fc0b9249e0 data/exnihiloreborn/advancements/recipes/food/cooked_silk_worm.json
e370135e6c1584c360ab7f5595d363f66b6665cb data/exnihiloreborn/advancements/recipes/food/cooked_silk_worm_from_smoking.json
a997345e74cecf81d4ae9c38973630ce6edf00f5 data/exnihiloreborn/advancements/recipes/food/porcelain_crucible_from_campfire_cooking.json
54db00472cd9b30762b21263d721e91fae5c2858 data/exnihiloreborn/advancements/recipes/misc/acacia_barrel.json
90a26e2be958eb40c751a78360e606a681979075 data/exnihiloreborn/advancements/recipes/misc/acacia_crucible.json
+0f8059dc21077fcf21639074de161778d36ca122 data/exnihiloreborn/advancements/recipes/misc/andesite.json
460f1827f3870a74868c2fdc3109d21c848cd911 data/exnihiloreborn/advancements/recipes/misc/bamboo_barrel.json
81f0df6bd5f0291aeb1dc54ef6f3c600bcd57ad2 data/exnihiloreborn/advancements/recipes/misc/bamboo_crucible.json
9573f025a3fdd8b8c2fd10c80d71972cd3133a66 data/exnihiloreborn/advancements/recipes/misc/birch_barrel.json
61c0510138b5dc14f623c02e5cd99202e7292450 data/exnihiloreborn/advancements/recipes/misc/birch_crucible.json
528bb21007cc050a964654f8a437bc7bb4966e3b data/exnihiloreborn/advancements/recipes/misc/cherry_barrel.json
925e20e41534e50ba00ebfa5aaa0f3f171998a00 data/exnihiloreborn/advancements/recipes/misc/cherry_crucible.json
+c9091169b9382c14662b145efb356e0736cc9c3a data/exnihiloreborn/advancements/recipes/misc/cobblestone.json
+66516d099bcfeaecf4e9cf124a6fc32d23e62c9f data/exnihiloreborn/advancements/recipes/misc/copper_ore.json
fd717e6474c96f26c2d72641cb67c19ecf4026b1 data/exnihiloreborn/advancements/recipes/misc/crimson_barrel.json
6a23ae2d2c46c827d0b7934410ac0e82fb3292e1 data/exnihiloreborn/advancements/recipes/misc/crimson_crucible.json
93b9339aae694eb850981382b7e0a84171185448 data/exnihiloreborn/advancements/recipes/misc/dark_oak_barrel.json
0267d7b9f193d7fb328920b17ea2fa09425d8594 data/exnihiloreborn/advancements/recipes/misc/dark_oak_crucible.json
+3060de107a0b730f32b4cdd964f33b8f7808922a data/exnihiloreborn/advancements/recipes/misc/diorite.json
+301aa831ade913d56fe3bc4c62dd0c8225362db9 data/exnihiloreborn/advancements/recipes/misc/gold_ore.json
+dfe0d24255b0f96e6d51485aa0f47fe2c5ad7699 data/exnihiloreborn/advancements/recipes/misc/granite.json
+78487b1c36b9ac063ab0014c7f5bae37d5239799 data/exnihiloreborn/advancements/recipes/misc/iron_ore.json
37af38214d27787d743b0005e8feca0e0f100cea data/exnihiloreborn/advancements/recipes/misc/jungle_barrel.json
5360db4c3c1e92b4f158b6d8560d1d83ea164b9e data/exnihiloreborn/advancements/recipes/misc/jungle_crucible.json
fd9afece033aea82e8a3ee12d8ed45ca2ebf622d data/exnihiloreborn/advancements/recipes/misc/mangrove_barrel.json
@@ -24,6 +31,7 @@ fd9afece033aea82e8a3ee12d8ed45ca2ebf622d data/exnihiloreborn/advancements/recipe
92dedd042dac942b381704d4ea3c1f5d9e235fd9 data/exnihiloreborn/advancements/recipes/misc/spruce_barrel.json
7febca27399bf00babc090143c96b5eca4d76a4b data/exnihiloreborn/advancements/recipes/misc/spruce_crucible.json
cf0dba5dc3969ab76d3175b7a3df332d54952526 data/exnihiloreborn/advancements/recipes/misc/stone_barrel.json
+b27c1f5cd97c5bd0cf00cdb9e5c04d8c4726fbb9 data/exnihiloreborn/advancements/recipes/misc/string_mesh.json
fc59e8cfe5a982f669dd9a44bc2156b88a5ad559 data/exnihiloreborn/advancements/recipes/misc/unfired_crucible.json
f3f469f966cfc8c2e43cc9d49dd13f9085d48ec7 data/exnihiloreborn/advancements/recipes/misc/warped_barrel.json
8c329ca51865a225bb50dfe7642a33e91a2db68f data/exnihiloreborn/advancements/recipes/misc/warped_crucible.json
@@ -37,6 +45,7 @@ f1e5c3dcb58a67f20182260f90ab8345839bfa3a data/exnihiloreborn/advancements/recipe
c37bc0b1ac02ea202c2607d9b56d10e2adf8db1b data/exnihiloreborn/advancements/recipes/tools/wooden_hammer.json
15ab7f3a8fb33766ffcd0c479baad03464c84072 data/exnihiloreborn/recipes/acacia_barrel.json
1d052e4d187e6031475d152096231eb0b75b17e3 data/exnihiloreborn/recipes/acacia_crucible.json
+eac1636f1be17e497bfc5f41451360e450d58c8b data/exnihiloreborn/recipes/andesite.json
7a75cd85dd46fd082f0b9c10bc97dda93b00ea46 data/exnihiloreborn/recipes/bamboo_barrel.json
687a62eda344b5adace2469dab89d6da30006417 data/exnihiloreborn/recipes/bamboo_crucible.json
0dace1f83ca8735522f33f5efc40bf3e7e247ebb data/exnihiloreborn/recipes/barrel_compost/apple.json
@@ -79,29 +88,42 @@ a2890194aed3620c2a096d66853f7dfff134f33b data/exnihiloreborn/recipes/barrel_comp
1a93f6756bfabc23bc186fb8b2bfbbc48781b5ca data/exnihiloreborn/recipes/barrel_compost/tropical_fish.json
30617af84eef24a61805cef9f12f7df1819a2c28 data/exnihiloreborn/recipes/barrel_compost/vine.json
a1efb6dfadde94b73da785f3d9857eed2540c1f7 data/exnihiloreborn/recipes/barrel_compost/wheat.json
+3ed1a1c0ddbd858c5cdb9934601ea7a06d83d516 data/exnihiloreborn/recipes/barrel_mixing/end_stone.json
+b1abd39ac9a5d9d04a5870c7d753fc167bfa06e9 data/exnihiloreborn/recipes/barrel_mixing/ice.json
+ff6204014e3bc860e4a9ef3746a7ed817ba9ec12 data/exnihiloreborn/recipes/barrel_mixing/netherrack.json
+07e3d165c60296150f087f71276ac9be401f5bbe data/exnihiloreborn/recipes/barrel_mixing/obsidian.json
+2b3b95049085360930bc0c37a55a69e718ea9ae9 data/exnihiloreborn/recipes/barrel_mixing/slime_block.json
+10cb7f258ecb82fddc04710f611cad72b08b07f7 data/exnihiloreborn/recipes/barrel_mixing/soul_sand.json
+840208a4bbb44595783ee353513cbda548413b36 data/exnihiloreborn/recipes/barrel_mixing/stone.json
6e3df85650328bce42f118edb970947c33d21f87 data/exnihiloreborn/recipes/birch_barrel.json
b33e570733c5188df4e4fa23333688bbb41fd628 data/exnihiloreborn/recipes/birch_crucible.json
a77177a80976dadad475d076045ed0fe35ab728f data/exnihiloreborn/recipes/bone_crook.json
2262902695810de5890ea8eb49b1641007d46e53 data/exnihiloreborn/recipes/cherry_barrel.json
22abc7bc31f67b4e2242dc6686281a9b5c977713 data/exnihiloreborn/recipes/cherry_crucible.json
+c0f93396b9e7506018a5c7e55708b6e016b752d2 data/exnihiloreborn/recipes/cobblestone.json
de36f05633916a8fab54b6b7814165314a7c41c4 data/exnihiloreborn/recipes/cooked_silk_worm.json
809138aa3568b0b805306ec5134f62a260437831 data/exnihiloreborn/recipes/cooked_silk_worm_from_smoking.json
+bfa7fb09202a264f6e65f331831f03b3a4eb6a0a data/exnihiloreborn/recipes/copper_ore.json
ca5f097f3c474a582c54bd370897dea18a10daaa data/exnihiloreborn/recipes/crimson_barrel.json
6c6283ce04a0599f4e85f247e0e397f8ba5df8ee data/exnihiloreborn/recipes/crimson_crucible.json
ca5e9fd7400f3e44658911436d7e9e4da1095015 data/exnihiloreborn/recipes/crook.json
5bb2a9d487ebc80970caf29ecd3e528df01bbac4 data/exnihiloreborn/recipes/dark_oak_barrel.json
7eade02376b91508a564c06eed144104a0215869 data/exnihiloreborn/recipes/dark_oak_crucible.json
7a58ae52499005a8b194e406f31c1be4a223f483 data/exnihiloreborn/recipes/diamond_hammer.json
+1409ef29665177b2be9a57a38e9682af9c15cbee data/exnihiloreborn/recipes/diorite.json
13540d2f5bb66b2bd194dca5ad8175f36c3625ca data/exnihiloreborn/recipes/golden_hammer.json
-da98669d2e0d8a2b037498f63fdd534c4ad7f88c data/exnihiloreborn/recipes/hammer/crushed_netherrack.json
-041032a45125fd9f8915a928ec7524c276bea4a8 data/exnihiloreborn/recipes/hammer/crushing_red_sandstone.json
-968a3c7e89ec7c793bef9448eee61eb41c1e6292 data/exnihiloreborn/recipes/hammer/crushing_sandstone.json
-4fae674b4893d89c06ab7cea1374e3cb6beb8bdc data/exnihiloreborn/recipes/hammer/crushing_stone_bricks.json
-421e577d31ea9f29c94fc4accf2228cc82203fd1 data/exnihiloreborn/recipes/hammer/dust.json
-24d6e7ad05b49201dd0fbc7d947ee1c7eaa536c6 data/exnihiloreborn/recipes/hammer/gravel.json
-89e95a16b00d0fed6ded49c75573cd31dc636565 data/exnihiloreborn/recipes/hammer/sand.json
-cc0996112cbb3bea9edb1e130044df4db2b11c75 data/exnihiloreborn/recipes/hammer/stone_pebbles.json
+da2bf88f10b6fe054b6a13367cef6a36d420a6e1 data/exnihiloreborn/recipes/gold_ore.json
+4b1fbb11dd0acd219bc4ea9eb148685bce52e60e data/exnihiloreborn/recipes/granite.json
+1db6202ef25021d3c9a823904e1a3f91fada4c6f data/exnihiloreborn/recipes/hammer/crushed_netherrack.json
+f82f21f9c6628e363811e3f2721615b6cc12a908 data/exnihiloreborn/recipes/hammer/crushing_red_sandstone.json
+55a047c193301bf84514f339fab861e8c330ab7d data/exnihiloreborn/recipes/hammer/crushing_sandstone.json
+40bab0961e8b0d0dfd42cde84839784e6081fdab data/exnihiloreborn/recipes/hammer/crushing_stone_bricks.json
+375e55a9dcbba1f4c018ea4f8fe5668a269204f5 data/exnihiloreborn/recipes/hammer/dust.json
+3a8af83e7901805ea9c6eff82471f2c990703db7 data/exnihiloreborn/recipes/hammer/gravel.json
+3187bc4ba54086e69db19f265a17f3e3063a9256 data/exnihiloreborn/recipes/hammer/sand.json
+4996ce338f802fa9d60f6d4f1884940ebefc233e data/exnihiloreborn/recipes/hammer/stone_pebbles.json
f52d66bd356d8a087380bcba6d2ace5aefd20634 data/exnihiloreborn/recipes/iron_hammer.json
+320efefe394abc12d15f4095c961746b5a79df84 data/exnihiloreborn/recipes/iron_ore.json
f1c9f600738b54452c064fb87bfc2a7cd426fff8 data/exnihiloreborn/recipes/jungle_barrel.json
862ce48ca979cfe274b1c3ccb13d4b5a51ca9864 data/exnihiloreborn/recipes/jungle_crucible.json
4619cf9593d9c2703d4422614bce3e562ae91d76 data/exnihiloreborn/recipes/lava_crucible/cobblestone.json
@@ -115,15 +137,26 @@ e74887ddb09e78aee413ec63aaa25a9ab0f0ebbf data/exnihiloreborn/recipes/mangrove_cr
a0501465b356002e17328ff509eecfa93e952a08 data/exnihiloreborn/recipes/oak_crucible.json
6c9f7a6da776a73b0daf13e431c7d5ac73a58bed data/exnihiloreborn/recipes/porcelain_crucible.json
19a026d0e8c0614cbc2b11150da49688ac0d3b0c data/exnihiloreborn/recipes/porcelain_crucible_from_campfire_cooking.json
-884041f9ea725ca44ac80e9e111e63099c82f8df data/exnihiloreborn/recipes/sieve/beetroot_seeds.json
-a8aef540a3d6b2b4ba30fc9813bd3e5df1d50ce6 data/exnihiloreborn/recipes/sieve/melon_seeds.json
-de43f772121c76d9b86d38673be84816a067d7c1 data/exnihiloreborn/recipes/sieve/pumpkin_seeds.json
-f0afd639fc9238f4f23bd6f5a2066cf16101d39a data/exnihiloreborn/recipes/sieve/stone_pebble.json
-5dfd628e764284176dbfc024c1abdd753148845e data/exnihiloreborn/recipes/sieve/wheat_seeds.json
+caa0a248c8f6d397970de66bf28b202ce3557d05 data/exnihiloreborn/recipes/sieve/flint/andesite_pebble.json
+a291f0815afe152b2d68865704699448f8b74fe9 data/exnihiloreborn/recipes/sieve/flint/beetroot_seeds.json
+94560929016b1ababa51875aec11a73838b44816 data/exnihiloreborn/recipes/sieve/flint/diorite_pebble.json
+007204a8c4ba383ae6099b63cdd556376d9efe82 data/exnihiloreborn/recipes/sieve/flint/flint.json
+e3342d4dce65cec82e7b3beb5c4282d705ea4be0 data/exnihiloreborn/recipes/sieve/flint/granite_pebble.json
+445bf2ddad6e9a9a8f7e4e8835e72d0b8d9aefc0 data/exnihiloreborn/recipes/sieve/flint/melon_seeds.json
+b5128a31a9a613a8c0e5c96d137d4c98e80fab94 data/exnihiloreborn/recipes/sieve/flint/pumpkin_seeds.json
+ff4f4cddb407223d1b56bb3dc334cb44a4b3d9ed data/exnihiloreborn/recipes/sieve/flint/stone_pebble.json
+2167f7f6ef63ce1f36b5530f834b01e3929dd594 data/exnihiloreborn/recipes/sieve/flint/wheat_seeds.json
+2e71936f4a2a2c251dd887070f911db955a6d5db data/exnihiloreborn/recipes/sieve/string/beetroot_seeds.json
+53b6f54cc3e0c84faab81a1860e4ce9f9991325e data/exnihiloreborn/recipes/sieve/string/flint.json
+94dd692b0b73bc92d6158d0b4d4bca8176f261eb data/exnihiloreborn/recipes/sieve/string/melon_seeds.json
+64b2cffef78659cef8862cbfcf57ff5644d7feea data/exnihiloreborn/recipes/sieve/string/pumpkin_seeds.json
+85d4af1b464b4a1dbfbea34b34c0a0901f1cf2b7 data/exnihiloreborn/recipes/sieve/string/stone_pebble.json
+08bdc228a11b8273ffc81a07325026390292dd7c data/exnihiloreborn/recipes/sieve/string/wheat_seeds.json
ffb29840856a0e5feb21c6992bfccbd6cb177882 data/exnihiloreborn/recipes/spruce_barrel.json
4cadea3ddd3378b8eb3654f537b2355be053471b data/exnihiloreborn/recipes/spruce_crucible.json
1a1187987414031f287bf60ac07e2058f3795bd0 data/exnihiloreborn/recipes/stone_barrel.json
bdf1b94117a393d54bd291a41ab9d1f5d7828db0 data/exnihiloreborn/recipes/stone_hammer.json
+fc23351592c713c3d50f79d1a71b5110a1a36ea5 data/exnihiloreborn/recipes/string_mesh.json
8d8ef9f564035f52f3e4bc5ad04ba760721b43d6 data/exnihiloreborn/recipes/unfired_crucible.json
4fa9d5d6e61a8e318e861e76067d2f7b857d5d26 data/exnihiloreborn/recipes/warped_barrel.json
8f6e9c019bb9761a97a2287539e28dd4417261e2 data/exnihiloreborn/recipes/warped_crucible.json
diff --git a/src/generated/resources/.cache/adcb492c336614f4dabbf7b0ba1b80a1feec2905 b/src/generated/resources/.cache/adcb492c336614f4dabbf7b0ba1b80a1feec2905
index bf36d943..5425259c 100644
--- a/src/generated/resources/.cache/adcb492c336614f4dabbf7b0ba1b80a1feec2905
+++ b/src/generated/resources/.cache/adcb492c336614f4dabbf7b0ba1b80a1feec2905
@@ -1,6 +1,8 @@
-// 1.20.1 2023-07-27T10:58:18.8907585 Tags for minecraft:item mod id exnihiloreborn
+// 1.20.1 2023-08-03T17:20:09.1072536 Tags for minecraft:item mod id exnihiloreborn
3602c357ad3f65545614e0829504c3bd0e3b9925 data/exnihiloreborn/tags/items/barrels.json
d5441416296951ce5fd5ce14bc6d3753b4f26950 data/exnihiloreborn/tags/items/crooks.json
b08e46cd1efe72662e1fab1b90fe65ba31695695 data/exnihiloreborn/tags/items/hammers.json
+4339c19de1b03c49492cb85d282195db571c1148 data/exnihiloreborn/tags/items/pebbles.json
+21515ccfd7e68fc84be41b5a31420c76640c0ccd data/exnihiloreborn/tags/items/sieve_meshes.json
4d0a7706e14b16cfe3c6f98c535afc582d714578 data/exnihiloreborn/tags/items/stone_barrels.json
b24f3ab9d607e3257d78d3a754a1255507e245f8 data/exnihiloreborn/tags/items/wooden_barrels.json
diff --git a/src/generated/resources/.cache/d2a52f93f6a2dbbf9cb17e741383b71a5107d737 b/src/generated/resources/.cache/d2a52f93f6a2dbbf9cb17e741383b71a5107d737
index 025dc671..61b26bba 100644
--- a/src/generated/resources/.cache/d2a52f93f6a2dbbf9cb17e741383b71a5107d737
+++ b/src/generated/resources/.cache/d2a52f93f6a2dbbf9cb17e741383b71a5107d737
@@ -1,4 +1,4 @@
-// 1.20.1 2023-07-25T16:40:21.4007052 Tags for minecraft:worldgen/structure_set mod id exnihiloreborn
+// 1.20.1 2023-07-31T10:44:07.5040349 Tags for minecraft:worldgen/structure_set mod id exnihiloreborn
35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/exnihiloreborn/tags/worldgen/structure_set/overworld_void_structure_sets.json
-35133e95f1c8fdd7a1c21afcc231fc0bffefb9a8 data/exnihiloreborn/tags/worldgen/structure_set/the_end_void_structure_sets.json
+56ffeb3beb8ca3df4a20420bc56f6139ebf57ada data/exnihiloreborn/tags/worldgen/structure_set/the_end_void_structure_sets.json
14abefb27112e5ad3ebce0cb9618fb51c54e2f9d data/exnihiloreborn/tags/worldgen/structure_set/the_nether_void_structure_sets.json
diff --git a/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0 b/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0
index 10e6a87d..583fb227 100644
--- a/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0
+++ b/src/generated/resources/.cache/e5c5eb35b4ba40351ecb7d9f04c3527f2f5779b0
@@ -1,6 +1,6 @@
-// 1.20.1 2023-07-25T23:58:50.2136539 Advancements
+// 1.20.1 2023-07-31T10:44:07.5060349 Advancements
82b18f9cd2e795822f726a2228b8afbe0725ec92 data/exnihiloreborn/advancements/core/barrel.json
-a9e9465ae18de97071060c1e9bda17bf47951524 data/exnihiloreborn/advancements/core/crook.json
+f8000323ce5754fad2f610f9dd9ad4e8028d3bcf data/exnihiloreborn/advancements/core/crook.json
59a21529ea42ad657750110399ff1cabfead380f data/exnihiloreborn/advancements/core/root.json
7103c0d7631de60d10e77f1a87a3232a30005c26 data/exnihiloreborn/advancements/core/silk_worm.json
6a9f99474e987b4c6f9031f20a77508c00280217 data/exnihiloreborn/advancements/core/string_mesh.json
diff --git a/src/generated/resources/assets/exnihiloreborn/lang/en_us.json b/src/generated/resources/assets/exnihiloreborn/lang/en_us.json
index bc3040a8..e14a13f3 100644
--- a/src/generated/resources/assets/exnihiloreborn/lang/en_us.json
+++ b/src/generated/resources/assets/exnihiloreborn/lang/en_us.json
@@ -2,7 +2,7 @@
"advancements.exnihiloreborn.core.barrel.description": "Use a barrel to compost organic material into dirt",
"advancements.exnihiloreborn.core.barrel.title": "That Goes in the GreenWaste",
"advancements.exnihiloreborn.core.crook.description": "Craft a Crook to double sapling drops from leaves",
- "advancements.exnihiloreborn.core.crook.title": "This is a Robbery",
+ "advancements.exnihiloreborn.core.crook.title": "Give Him The Hook",
"advancements.exnihiloreborn.core.root.description": "Spawn into a SkyBlock void world",
"advancements.exnihiloreborn.core.root.title": "Don't Look Down...",
"advancements.exnihiloreborn.core.silk_worm.description": "Obtain a silk worm, then infest a tree with it to get string",
@@ -21,12 +21,6 @@
"block.exnihiloreborn.cherry_barrel": "Cherry Barrel",
"block.exnihiloreborn.cherry_crucible": "Cherry Crucible",
"block.exnihiloreborn.cherry_sieve": "Cherry Sieve",
- "block.exnihiloreborn.compressed_cobblestone": "Compressed Cobblestone",
- "block.exnihiloreborn.compressed_crushed_end_stone": "Compressed Crushed End Stone",
- "block.exnihiloreborn.compressed_crushed_netherrack": "Compressed Crushed Netherrack",
- "block.exnihiloreborn.compressed_dirt": "Compressed Dirt",
- "block.exnihiloreborn.compressed_dust": "Compressed Dust",
- "block.exnihiloreborn.compressed_sand": "Compressed Sand",
"block.exnihiloreborn.crimson_barrel": "Crimson Barrel",
"block.exnihiloreborn.crimson_crucible": "Crimson Crucible",
"block.exnihiloreborn.crimson_sieve": "Crimson Sieve",
@@ -56,29 +50,37 @@
"block.exnihiloreborn.warped_crucible": "Warped Crucible",
"block.exnihiloreborn.warped_sieve": "Warped Sieve",
"block.exnihiloreborn.witch_water": "Witch Water",
+ "fluid_type.exnihiloreborn.witch_water": "Witch Water",
"generator.exnihiloreborn.void_world": "Void World",
"gui.exnihiloreborn.category.barrel_compost": "Barrel Compost",
"gui.exnihiloreborn.category.barrel_compost.volume": "Compost: %s",
- "gui.exnihiloreborn.category.compressed_hammer": "Compressed Hammer",
- "gui.exnihiloreborn.category.compressed_sieve": "Heavy Sieve",
- "gui.exnihiloreborn.category.hammer": "Hammer Crucible",
+ "gui.exnihiloreborn.category.hammer": "Hammer",
"gui.exnihiloreborn.category.lava_crucible": "Lava Crucible",
"gui.exnihiloreborn.category.sieve": "Sieve",
+ "gui.exnihiloreborn.category.sieve.average_output": "Avg. Output: %s",
+ "gui.exnihiloreborn.category.sieve.chance": "Chance: %s%%",
+ "gui.exnihiloreborn.category.sieve.max_output": "Max: %s",
+ "gui.exnihiloreborn.category.sieve.min_output": "Min: %s",
"gui.exnihiloreborn.category.water_crucible": "Water Crucible",
+ "info.exnihiloreborn.sieve": "Sieves are used to filter out certain items from soft blocks like gravel and dirt. A mesh is required to use the sieve, and it can be enchanted with Fortune and Efficiency.",
"info.exnihiloreborn.silk_worm": "Silk worms have a 1 in 100 chance to drop from leaves harvested with a Crook. Using a silk worm on a tree's leaves will infest them, gradually spreading through the entire tree. 100% infested leaves can be harvested for string, but do not drop saplings.",
+ "item.exnihiloreborn.andesite_pebble": "Andesite Pebble",
"item.exnihiloreborn.bone_crook": "Bone Crook",
"item.exnihiloreborn.cooked_silk_worm": "Cooked Silk Worm",
- "item.exnihiloreborn.copper_ore_pieces": "Copper Ore Pieces",
+ "item.exnihiloreborn.copper_ore_chunk": "Copper Ore Chunk",
"item.exnihiloreborn.crook": "Crook",
"item.exnihiloreborn.deepslate_pebble": "Deepslate Pebble",
"item.exnihiloreborn.diamond_hammer": "Diamond Hammer",
"item.exnihiloreborn.diamond_mesh": "Diamond Mesh",
+ "item.exnihiloreborn.diorite_pebble": "Diorite Pebble",
"item.exnihiloreborn.flint_mesh": "Flint Mesh",
- "item.exnihiloreborn.gold_ore_pieces": "Gold Ore Pieces",
+ "item.exnihiloreborn.gold_ore_chunk": "Gold Ore Chunk",
"item.exnihiloreborn.golden_hammer": "Golden Hammer",
+ "item.exnihiloreborn.golden_mesh": "Golden Mesh",
+ "item.exnihiloreborn.granite_pebble": "Granite Pebble",
"item.exnihiloreborn.iron_hammer": "Iron Hammer",
"item.exnihiloreborn.iron_mesh": "Iron Mesh",
- "item.exnihiloreborn.iron_ore_pieces": "Iron Ore Pieces",
+ "item.exnihiloreborn.iron_ore_chunk": "Iron Ore Chunk",
"item.exnihiloreborn.netherite_hammer": "Netherite Hammer",
"item.exnihiloreborn.netherite_mesh": "Netherite Mesh",
"item.exnihiloreborn.porcelain_bucket": "Porcelain Bucket",
@@ -87,6 +89,7 @@
"item.exnihiloreborn.stone_hammer": "Stone Hammer",
"item.exnihiloreborn.stone_pebble": "Stone Pebble",
"item.exnihiloreborn.string_mesh": "String Mesh",
+ "item.exnihiloreborn.tuff_pebble": "Tuff Pebble",
"item.exnihiloreborn.witch_water_bucket": "Witch Water Bucket",
"item.exnihiloreborn.wooden_hammer": "Wooden Hammer",
"itemGroup.exnihiloreborn.main": "Ex Nihilo Reborn"
diff --git a/src/generated/resources/assets/exnihiloreborn/models/item/gold_ore_pieces.json b/src/generated/resources/assets/exnihiloreborn/models/item/andesite_pebble.json
similarity index 53%
rename from src/generated/resources/assets/exnihiloreborn/models/item/gold_ore_pieces.json
rename to src/generated/resources/assets/exnihiloreborn/models/item/andesite_pebble.json
index 96b356ad..2cd958cd 100644
--- a/src/generated/resources/assets/exnihiloreborn/models/item/gold_ore_pieces.json
+++ b/src/generated/resources/assets/exnihiloreborn/models/item/andesite_pebble.json
@@ -1,6 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
- "layer0": "exnihiloreborn:item/gold_ore_pieces"
+ "layer0": "exnihiloreborn:item/andesite_pebble"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/exnihiloreborn/models/item/copper_ore_pieces.json b/src/generated/resources/assets/exnihiloreborn/models/item/copper_ore_chunk.json
similarity index 52%
rename from src/generated/resources/assets/exnihiloreborn/models/item/copper_ore_pieces.json
rename to src/generated/resources/assets/exnihiloreborn/models/item/copper_ore_chunk.json
index e6b757d5..75049c41 100644
--- a/src/generated/resources/assets/exnihiloreborn/models/item/copper_ore_pieces.json
+++ b/src/generated/resources/assets/exnihiloreborn/models/item/copper_ore_chunk.json
@@ -1,6 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
- "layer0": "exnihiloreborn:item/copper_ore_pieces"
+ "layer0": "exnihiloreborn:item/copper_ore_chunk"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/exnihiloreborn/models/item/iron_ore_pieces.json b/src/generated/resources/assets/exnihiloreborn/models/item/diorite_pebble.json
similarity index 53%
rename from src/generated/resources/assets/exnihiloreborn/models/item/iron_ore_pieces.json
rename to src/generated/resources/assets/exnihiloreborn/models/item/diorite_pebble.json
index 9b0f1d79..355d4c96 100644
--- a/src/generated/resources/assets/exnihiloreborn/models/item/iron_ore_pieces.json
+++ b/src/generated/resources/assets/exnihiloreborn/models/item/diorite_pebble.json
@@ -1,6 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
- "layer0": "exnihiloreborn:item/iron_ore_pieces"
+ "layer0": "exnihiloreborn:item/diorite_pebble"
}
}
\ No newline at end of file
diff --git a/src/generated/resources/assets/exnihiloreborn/models/item/gold_ore_chunk.json b/src/generated/resources/assets/exnihiloreborn/models/item/gold_ore_chunk.json
new file mode 100644
index 00000000..693fea55
--- /dev/null
+++ b/src/generated/resources/assets/exnihiloreborn/models/item/gold_ore_chunk.json
@@ -0,0 +1,6 @@
+{
+ "parent": "minecraft:item/generated",
+ "textures": {
+ "layer0": "exnihiloreborn:item/gold_ore_chunk"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/exnihiloreborn/models/item/golden_mesh.json b/src/generated/resources/assets/exnihiloreborn/models/item/golden_mesh.json
new file mode 100644
index 00000000..c66681f7
--- /dev/null
+++ b/src/generated/resources/assets/exnihiloreborn/models/item/golden_mesh.json
@@ -0,0 +1,6 @@
+{
+ "parent": "minecraft:item/generated",
+ "textures": {
+ "layer0": "exnihiloreborn:item/golden_mesh"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/exnihiloreborn/models/item/granite_pebble.json b/src/generated/resources/assets/exnihiloreborn/models/item/granite_pebble.json
new file mode 100644
index 00000000..600c6171
--- /dev/null
+++ b/src/generated/resources/assets/exnihiloreborn/models/item/granite_pebble.json
@@ -0,0 +1,6 @@
+{
+ "parent": "minecraft:item/generated",
+ "textures": {
+ "layer0": "exnihiloreborn:item/granite_pebble"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/exnihiloreborn/models/item/iron_ore_chunk.json b/src/generated/resources/assets/exnihiloreborn/models/item/iron_ore_chunk.json
new file mode 100644
index 00000000..91961838
--- /dev/null
+++ b/src/generated/resources/assets/exnihiloreborn/models/item/iron_ore_chunk.json
@@ -0,0 +1,6 @@
+{
+ "parent": "minecraft:item/generated",
+ "textures": {
+ "layer0": "exnihiloreborn:item/iron_ore_chunk"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/assets/exnihiloreborn/models/item/tuff_pebble.json b/src/generated/resources/assets/exnihiloreborn/models/item/tuff_pebble.json
new file mode 100644
index 00000000..bafd7c4a
--- /dev/null
+++ b/src/generated/resources/assets/exnihiloreborn/models/item/tuff_pebble.json
@@ -0,0 +1,6 @@
+{
+ "parent": "minecraft:item/generated",
+ "textures": {
+ "layer0": "exnihiloreborn:item/tuff_pebble"
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/core/crook.json b/src/generated/resources/data/exnihiloreborn/advancements/core/crook.json
index fa331352..bb7d85f7 100644
--- a/src/generated/resources/data/exnihiloreborn/advancements/core/crook.json
+++ b/src/generated/resources/data/exnihiloreborn/advancements/core/crook.json
@@ -3,9 +3,13 @@
"criteria": {
"craft_crook": {
"conditions": {
- "recipe_id": "exnihiloreborn:crook"
+ "items": [
+ {
+ "tag": "exnihiloreborn:crooks"
+ }
+ ]
},
- "trigger": "minecraft:recipe_crafted"
+ "trigger": "minecraft:inventory_changed"
}
},
"display": {
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/andesite.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/andesite.json
new file mode 100644
index 00000000..28565357
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/andesite.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "exnihiloreborn:andesite_pebble"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:andesite"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:andesite"
+ ]
+ },
+ "sends_telemetry_event": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/cobblestone.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/cobblestone.json
new file mode 100644
index 00000000..fb3d3cb9
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/cobblestone.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "exnihiloreborn:stone_pebble"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:cobblestone"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:cobblestone"
+ ]
+ },
+ "sends_telemetry_event": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/copper_ore.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/copper_ore.json
new file mode 100644
index 00000000..ee071e59
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/copper_ore.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "exnihiloreborn:copper_ore_chunk"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:copper_ore"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:copper_ore"
+ ]
+ },
+ "sends_telemetry_event": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/diorite.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/diorite.json
new file mode 100644
index 00000000..8935262e
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/diorite.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "exnihiloreborn:diorite_pebble"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:diorite"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:diorite"
+ ]
+ },
+ "sends_telemetry_event": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/gold_ore.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/gold_ore.json
new file mode 100644
index 00000000..6e59bbf0
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/gold_ore.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "exnihiloreborn:gold_ore_chunk"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:gold_ore"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:gold_ore"
+ ]
+ },
+ "sends_telemetry_event": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/granite.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/granite.json
new file mode 100644
index 00000000..75be6394
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/granite.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "exnihiloreborn:granite_pebble"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:granite"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:granite"
+ ]
+ },
+ "sends_telemetry_event": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/iron_ore.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/iron_ore.json
new file mode 100644
index 00000000..148502de
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/iron_ore.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "exnihiloreborn:iron_ore_chunk"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:iron_ore"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:iron_ore"
+ ]
+ },
+ "sends_telemetry_event": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/string_mesh.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/string_mesh.json
new file mode 100644
index 00000000..8e5d65a2
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/misc/string_mesh.json
@@ -0,0 +1,33 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "tag": "forge:string"
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:string_mesh"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:string_mesh"
+ ]
+ },
+ "sends_telemetry_event": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/advancements/recipes/tools/netherite_hammer.json b/src/generated/resources/data/exnihiloreborn/advancements/recipes/tools/netherite_hammer.json
new file mode 100644
index 00000000..fff1c36d
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/advancements/recipes/tools/netherite_hammer.json
@@ -0,0 +1,35 @@
+{
+ "parent": "minecraft:recipes/root",
+ "criteria": {
+ "has_item": {
+ "conditions": {
+ "items": [
+ {
+ "items": [
+ "minecraft:netherite_ingot"
+ ]
+ }
+ ]
+ },
+ "trigger": "minecraft:inventory_changed"
+ },
+ "has_the_recipe": {
+ "conditions": {
+ "recipe": "exnihiloreborn:netherite_hammer"
+ },
+ "trigger": "minecraft:recipe_unlocked"
+ }
+ },
+ "requirements": [
+ [
+ "has_item",
+ "has_the_recipe"
+ ]
+ ],
+ "rewards": {
+ "recipes": [
+ "exnihiloreborn:netherite_hammer"
+ ]
+ },
+ "sends_telemetry_event": false
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/acacia_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/acacia_crucible.json
new file mode 100644
index 00000000..08197386
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/acacia_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:acacia_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/acacia_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_cobblestone.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/acacia_sieve.json
similarity index 73%
rename from src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_cobblestone.json
rename to src/generated/resources/data/exnihiloreborn/loot_tables/blocks/acacia_sieve.json
index 1d950281..6b22fd24 100644
--- a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_cobblestone.json
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/acacia_sieve.json
@@ -11,11 +11,11 @@
"entries": [
{
"type": "minecraft:item",
- "name": "minecraft:air"
+ "name": "exnihiloreborn:acacia_sieve"
}
],
"rolls": 1.0
}
],
- "random_sequence": "exnihiloreborn:blocks/compressed_cobblestone"
+ "random_sequence": "exnihiloreborn:blocks/acacia_sieve"
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_barrel.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_barrel.json
new file mode 100644
index 00000000..bdf76529
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_barrel.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:bamboo_barrel"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/bamboo_barrel"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_crucible.json
new file mode 100644
index 00000000..ad65cfc3
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:bamboo_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/bamboo_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_sieve.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_sieve.json
new file mode 100644
index 00000000..cf93b940
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/bamboo_sieve.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:bamboo_sieve"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/bamboo_sieve"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/birch_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/birch_crucible.json
new file mode 100644
index 00000000..56663096
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/birch_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:birch_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/birch_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_sand.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/birch_sieve.json
similarity index 73%
rename from src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_sand.json
rename to src/generated/resources/data/exnihiloreborn/loot_tables/blocks/birch_sieve.json
index acc1ab18..f53be318 100644
--- a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_sand.json
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/birch_sieve.json
@@ -11,11 +11,11 @@
"entries": [
{
"type": "minecraft:item",
- "name": "minecraft:air"
+ "name": "exnihiloreborn:birch_sieve"
}
],
"rolls": 1.0
}
],
- "random_sequence": "exnihiloreborn:blocks/compressed_sand"
+ "random_sequence": "exnihiloreborn:blocks/birch_sieve"
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_barrel.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_barrel.json
new file mode 100644
index 00000000..e17e792d
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_barrel.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:cherry_barrel"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/cherry_barrel"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_crucible.json
new file mode 100644
index 00000000..c07f3a30
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:cherry_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/cherry_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_sieve.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_sieve.json
new file mode 100644
index 00000000..506e5cc4
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/cherry_sieve.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:cherry_sieve"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/cherry_sieve"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crimson_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crimson_crucible.json
new file mode 100644
index 00000000..deff5da9
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crimson_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:crimson_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/crimson_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crimson_sieve.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crimson_sieve.json
new file mode 100644
index 00000000..1edaba93
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crimson_sieve.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:crimson_sieve"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/crimson_sieve"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crushed_end_stone.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crushed_end_stone.json
new file mode 100644
index 00000000..6f1c2d24
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crushed_end_stone.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:crushed_end_stone"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/crushed_end_stone"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crushed_netherrack.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crushed_netherrack.json
new file mode 100644
index 00000000..389e9c5b
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/crushed_netherrack.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:crushed_netherrack"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/crushed_netherrack"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/dark_oak_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/dark_oak_crucible.json
new file mode 100644
index 00000000..9dee7ff7
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/dark_oak_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:dark_oak_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/dark_oak_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/dark_oak_sieve.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/dark_oak_sieve.json
new file mode 100644
index 00000000..7cbcaf75
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/dark_oak_sieve.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:dark_oak_sieve"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/dark_oak_sieve"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/jungle_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/jungle_crucible.json
new file mode 100644
index 00000000..28e2d143
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/jungle_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:jungle_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/jungle_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/jungle_sieve.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/jungle_sieve.json
new file mode 100644
index 00000000..6d1bbf0e
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/jungle_sieve.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:jungle_sieve"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/jungle_sieve"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_barrel.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_barrel.json
new file mode 100644
index 00000000..1f85aebd
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_barrel.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:mangrove_barrel"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/mangrove_barrel"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_crucible.json
new file mode 100644
index 00000000..0228cddc
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:mangrove_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/mangrove_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_sieve.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_sieve.json
new file mode 100644
index 00000000..59428255
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/mangrove_sieve.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:mangrove_sieve"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/mangrove_sieve"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/oak_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/oak_crucible.json
new file mode 100644
index 00000000..a582a7b0
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/oak_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:oak_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/oak_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_dust.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/oak_sieve.json
similarity index 74%
rename from src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_dust.json
rename to src/generated/resources/data/exnihiloreborn/loot_tables/blocks/oak_sieve.json
index 366e4b43..a912dc90 100644
--- a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_dust.json
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/oak_sieve.json
@@ -11,11 +11,11 @@
"entries": [
{
"type": "minecraft:item",
- "name": "minecraft:air"
+ "name": "exnihiloreborn:oak_sieve"
}
],
"rolls": 1.0
}
],
- "random_sequence": "exnihiloreborn:blocks/compressed_dust"
+ "random_sequence": "exnihiloreborn:blocks/oak_sieve"
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/porcelain_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/porcelain_crucible.json
new file mode 100644
index 00000000..f35d5b7c
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/porcelain_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:porcelain_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/porcelain_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/spruce_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/spruce_crucible.json
new file mode 100644
index 00000000..07a84c37
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/spruce_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:spruce_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/spruce_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/spruce_sieve.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/spruce_sieve.json
new file mode 100644
index 00000000..95a4761d
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/spruce_sieve.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:spruce_sieve"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/spruce_sieve"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/unfired_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/unfired_crucible.json
new file mode 100644
index 00000000..1374f258
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/unfired_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:unfired_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/unfired_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/warped_crucible.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/warped_crucible.json
new file mode 100644
index 00000000..409bc1c9
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/warped_crucible.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:warped_crucible"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/warped_crucible"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/warped_sieve.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/warped_sieve.json
new file mode 100644
index 00000000..04ceca67
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/warped_sieve.json
@@ -0,0 +1,21 @@
+{
+ "type": "minecraft:block",
+ "pools": [
+ {
+ "bonus_rolls": 0.0,
+ "conditions": [
+ {
+ "condition": "minecraft:survives_explosion"
+ }
+ ],
+ "entries": [
+ {
+ "type": "minecraft:item",
+ "name": "exnihiloreborn:warped_sieve"
+ }
+ ],
+ "rolls": 1.0
+ }
+ ],
+ "random_sequence": "exnihiloreborn:blocks/warped_sieve"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_dirt.json b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/witch_water.json
similarity index 84%
rename from src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_dirt.json
rename to src/generated/resources/data/exnihiloreborn/loot_tables/blocks/witch_water.json
index 27cbc7ec..30c39b6d 100644
--- a/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/compressed_dirt.json
+++ b/src/generated/resources/data/exnihiloreborn/loot_tables/blocks/witch_water.json
@@ -17,5 +17,5 @@
"rolls": 1.0
}
],
- "random_sequence": "exnihiloreborn:blocks/compressed_dirt"
+ "random_sequence": "exnihiloreborn:blocks/witch_water"
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/andesite.json b/src/generated/resources/data/exnihiloreborn/recipes/andesite.json
new file mode 100644
index 00000000..06096b1c
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/andesite.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "#": {
+ "item": "exnihiloreborn:andesite_pebble"
+ }
+ },
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "result": {
+ "item": "minecraft:andesite"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/end_stone.json b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/end_stone.json
new file mode 100644
index 00000000..98c43fa2
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/end_stone.json
@@ -0,0 +1,9 @@
+{
+ "type": "exnihiloreborn:barrel_mixing",
+ "fluid_amount": 1000,
+ "fluid_type": "minecraft:lava",
+ "ingredient": {
+ "item": "minecraft:glowstone_dust"
+ },
+ "result": "minecraft:end_stone"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/ice.json b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/ice.json
new file mode 100644
index 00000000..68a58f85
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/ice.json
@@ -0,0 +1,9 @@
+{
+ "type": "exnihiloreborn:barrel_mixing",
+ "fluid_amount": 1000,
+ "fluid_type": "minecraft:water",
+ "ingredient": {
+ "item": "minecraft:snowball"
+ },
+ "result": "minecraft:ice"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/netherrack.json b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/netherrack.json
new file mode 100644
index 00000000..7b0f3596
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/netherrack.json
@@ -0,0 +1,9 @@
+{
+ "type": "exnihiloreborn:barrel_mixing",
+ "fluid_amount": 1000,
+ "fluid_type": "minecraft:lava",
+ "ingredient": {
+ "item": "minecraft:redstone"
+ },
+ "result": "minecraft:netherrack"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/obsidian.json b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/obsidian.json
new file mode 100644
index 00000000..1f753cf6
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/obsidian.json
@@ -0,0 +1,9 @@
+{
+ "type": "exnihiloreborn:barrel_mixing",
+ "fluid_amount": 1000,
+ "fluid_type": "minecraft:lava",
+ "ingredient": {
+ "item": "minecraft:water_bucket"
+ },
+ "result": "minecraft:obsidian"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/slime_block.json b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/slime_block.json
new file mode 100644
index 00000000..bc68954b
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/slime_block.json
@@ -0,0 +1,9 @@
+{
+ "type": "exnihiloreborn:barrel_mixing",
+ "fluid_amount": 1000,
+ "fluid_type": "minecraft:water",
+ "ingredient": {
+ "item": "minecraft:milk_bucket"
+ },
+ "result": "minecraft:slime_block"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/soul_sand.json b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/soul_sand.json
new file mode 100644
index 00000000..aa1e0895
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/soul_sand.json
@@ -0,0 +1,9 @@
+{
+ "type": "exnihiloreborn:barrel_mixing",
+ "fluid_amount": 1000,
+ "fluid_type": "exnihiloreborn:witch_water",
+ "ingredient": {
+ "item": "minecraft:sand"
+ },
+ "result": "minecraft:soul_sand"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/stone.json b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/stone.json
new file mode 100644
index 00000000..e98b6835
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/barrel_mixing/stone.json
@@ -0,0 +1,9 @@
+{
+ "type": "exnihiloreborn:barrel_mixing",
+ "fluid_amount": 1000,
+ "fluid_type": "minecraft:water",
+ "ingredient": {
+ "item": "minecraft:lava_bucket"
+ },
+ "result": "minecraft:stone"
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/cobblestone.json b/src/generated/resources/data/exnihiloreborn/recipes/cobblestone.json
new file mode 100644
index 00000000..77c7abe5
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/cobblestone.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "#": {
+ "item": "exnihiloreborn:stone_pebble"
+ }
+ },
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "result": {
+ "item": "minecraft:cobblestone"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/copper_ore.json b/src/generated/resources/data/exnihiloreborn/recipes/copper_ore.json
new file mode 100644
index 00000000..9226c1a2
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/copper_ore.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "#": {
+ "item": "exnihiloreborn:copper_ore_chunk"
+ }
+ },
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "result": {
+ "item": "minecraft:copper_ore"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/diorite.json b/src/generated/resources/data/exnihiloreborn/recipes/diorite.json
new file mode 100644
index 00000000..d9d4ef0b
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/diorite.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "#": {
+ "item": "exnihiloreborn:diorite_pebble"
+ }
+ },
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "result": {
+ "item": "minecraft:diorite"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/gold_ore.json b/src/generated/resources/data/exnihiloreborn/recipes/gold_ore.json
new file mode 100644
index 00000000..958b6d3a
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/gold_ore.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "#": {
+ "item": "exnihiloreborn:gold_ore_chunk"
+ }
+ },
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "result": {
+ "item": "minecraft:gold_ore"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/granite.json b/src/generated/resources/data/exnihiloreborn/recipes/granite.json
new file mode 100644
index 00000000..e6c8bb7f
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/granite.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "#": {
+ "item": "exnihiloreborn:granite_pebble"
+ }
+ },
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "result": {
+ "item": "minecraft:granite"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushed_netherrack.json b/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushed_netherrack.json
index 87476a67..ef160818 100644
--- a/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushed_netherrack.json
+++ b/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushed_netherrack.json
@@ -3,13 +3,6 @@
"ingredient": {
"item": "minecraft:netherrack"
},
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:crushed_netherrack"
- }
- }
- ]
+ "result": "exnihiloreborn:crushed_netherrack",
+ "result_amount": 1.0
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_red_sandstone.json b/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_red_sandstone.json
index ade16ed4..7b5b629e 100644
--- a/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_red_sandstone.json
+++ b/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_red_sandstone.json
@@ -14,13 +14,6 @@
"item": "minecraft:smooth_red_sandstone"
}
],
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "minecraft:red_sand"
- }
- }
- ]
+ "result": "minecraft:red_sand",
+ "result_amount": 1.0
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_sandstone.json b/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_sandstone.json
index d334e116..7dbfa327 100644
--- a/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_sandstone.json
+++ b/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_sandstone.json
@@ -14,13 +14,6 @@
"item": "minecraft:smooth_sandstone"
}
],
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "minecraft:sand"
- }
- }
- ]
+ "result": "minecraft:sand",
+ "result_amount": 1.0
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_stone_bricks.json b/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_stone_bricks.json
index 754b7231..538d3c76 100644
--- a/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_stone_bricks.json
+++ b/src/generated/resources/data/exnihiloreborn/recipes/hammer/crushing_stone_bricks.json
@@ -3,13 +3,6 @@
"ingredient": {
"item": "minecraft:stone_bricks"
},
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "minecraft:cracked_stone_bricks"
- }
- }
- ]
+ "result": "minecraft:cracked_stone_bricks",
+ "result_amount": 1.0
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/hammer/dust.json b/src/generated/resources/data/exnihiloreborn/recipes/hammer/dust.json
index 77feb08b..a5e60a7d 100644
--- a/src/generated/resources/data/exnihiloreborn/recipes/hammer/dust.json
+++ b/src/generated/resources/data/exnihiloreborn/recipes/hammer/dust.json
@@ -3,13 +3,6 @@
"ingredient": {
"item": "minecraft:sand"
},
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:dust"
- }
- }
- ]
+ "result": "exnihiloreborn:dust",
+ "result_amount": 1.0
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/hammer/gravel.json b/src/generated/resources/data/exnihiloreborn/recipes/hammer/gravel.json
index 9f3e3996..912404c9 100644
--- a/src/generated/resources/data/exnihiloreborn/recipes/hammer/gravel.json
+++ b/src/generated/resources/data/exnihiloreborn/recipes/hammer/gravel.json
@@ -3,13 +3,6 @@
"ingredient": {
"item": "minecraft:cobblestone"
},
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "minecraft:gravel"
- }
- }
- ]
+ "result": "minecraft:gravel",
+ "result_amount": 1.0
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/hammer/sand.json b/src/generated/resources/data/exnihiloreborn/recipes/hammer/sand.json
index 04868da5..35964db9 100644
--- a/src/generated/resources/data/exnihiloreborn/recipes/hammer/sand.json
+++ b/src/generated/resources/data/exnihiloreborn/recipes/hammer/sand.json
@@ -3,13 +3,6 @@
"ingredient": {
"item": "minecraft:gravel"
},
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "minecraft:sand"
- }
- }
- ]
+ "result": "minecraft:sand",
+ "result_amount": 1.0
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/hammer/stone_pebbles.json b/src/generated/resources/data/exnihiloreborn/recipes/hammer/stone_pebbles.json
index bd7b5675..b03176aa 100644
--- a/src/generated/resources/data/exnihiloreborn/recipes/hammer/stone_pebbles.json
+++ b/src/generated/resources/data/exnihiloreborn/recipes/hammer/stone_pebbles.json
@@ -4,52 +4,20 @@
{
"item": "minecraft:stone"
},
+ {
+ "item": "minecraft:stone_bricks"
+ },
+ {
+ "item": "minecraft:chiseled_stone_bricks"
+ },
{
"item": "minecraft:cracked_stone_bricks"
}
],
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.75,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.75,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.5,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.25,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.05,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- }
- ]
+ "result": "exnihiloreborn:stone_pebble",
+ "result_amount": {
+ "type": "minecraft:uniform",
+ "max": 6.0,
+ "min": 1.0
+ }
}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/iron_ore.json b/src/generated/resources/data/exnihiloreborn/recipes/iron_ore.json
new file mode 100644
index 00000000..34473533
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/iron_ore.json
@@ -0,0 +1,17 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "#": {
+ "item": "exnihiloreborn:iron_ore_chunk"
+ }
+ },
+ "pattern": [
+ "##",
+ "##"
+ ],
+ "result": {
+ "item": "minecraft:iron_ore"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/beetroot_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/beetroot_seeds.json
deleted file mode 100644
index 83c4dd43..00000000
--- a/src/generated/resources/data/exnihiloreborn/recipes/sieve/beetroot_seeds.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "type": "exnihiloreborn:sieve",
- "ingredient": {
- "item": "minecraft:dirt"
- },
- "mesh": "exnihiloreborn:string_mesh",
- "rewards": [
- {
- "chance": 0.35,
- "item": {
- "Count": 1,
- "id": "minecraft:beetroot_seeds"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/andesite_pebble.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/andesite_pebble.json
new file mode 100644
index 00000000..0ec827a6
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/andesite_pebble.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "exnihiloreborn:andesite_pebble",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 7.0,
+ "p": 0.4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/beetroot_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/beetroot_seeds.json
new file mode 100644
index 00000000..9dbe6ce5
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/beetroot_seeds.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "minecraft:beetroot_seeds",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.1
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/diorite_pebble.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/diorite_pebble.json
new file mode 100644
index 00000000..72f6c217
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/diorite_pebble.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "exnihiloreborn:diorite_pebble",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 7.0,
+ "p": 0.4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/flint.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/flint.json
new file mode 100644
index 00000000..0c449bd3
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/flint.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "minecraft:flint",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.2
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/granite_pebble.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/granite_pebble.json
new file mode 100644
index 00000000..2809d865
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/granite_pebble.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "exnihiloreborn:granite_pebble",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 7.0,
+ "p": 0.4
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/melon_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/melon_seeds.json
new file mode 100644
index 00000000..855ea1db
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/melon_seeds.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "minecraft:melon_seeds",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.1
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/pumpkin_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/pumpkin_seeds.json
new file mode 100644
index 00000000..f0295699
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/pumpkin_seeds.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "minecraft:pumpkin_seeds",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.1
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/stone_pebble.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/stone_pebble.json
new file mode 100644
index 00000000..fddfa532
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/stone_pebble.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "exnihiloreborn:stone_pebble",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 7.0,
+ "p": 0.6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/wheat_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/wheat_seeds.json
new file mode 100644
index 00000000..c5524df9
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/flint/wheat_seeds.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:flint_mesh",
+ "result": "minecraft:wheat_seeds",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.5
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/melon_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/melon_seeds.json
deleted file mode 100644
index e3756870..00000000
--- a/src/generated/resources/data/exnihiloreborn/recipes/sieve/melon_seeds.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "type": "exnihiloreborn:sieve",
- "ingredient": {
- "item": "minecraft:dirt"
- },
- "mesh": "exnihiloreborn:string_mesh",
- "rewards": [
- {
- "chance": 0.35,
- "item": {
- "Count": 1,
- "id": "minecraft:melon_seeds"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/pumpkin_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/pumpkin_seeds.json
deleted file mode 100644
index 0993a31a..00000000
--- a/src/generated/resources/data/exnihiloreborn/recipes/sieve/pumpkin_seeds.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "type": "exnihiloreborn:sieve",
- "ingredient": {
- "item": "minecraft:dirt"
- },
- "mesh": "exnihiloreborn:string_mesh",
- "rewards": [
- {
- "chance": 0.35,
- "item": {
- "Count": 1,
- "id": "minecraft:pumpkin_seeds"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/stone_pebble.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/stone_pebble.json
deleted file mode 100644
index 91f2db83..00000000
--- a/src/generated/resources/data/exnihiloreborn/recipes/sieve/stone_pebble.json
+++ /dev/null
@@ -1,58 +0,0 @@
-{
- "type": "exnihiloreborn:sieve",
- "ingredient": {
- "item": "minecraft:dirt"
- },
- "mesh": "exnihiloreborn:string_mesh",
- "rewards": [
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 1.0,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.5,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.5,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.1,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- },
- {
- "chance": 0.1,
- "item": {
- "Count": 1,
- "id": "exnihiloreborn:stone_pebble"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/beetroot_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/beetroot_seeds.json
new file mode 100644
index 00000000..554680fb
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/beetroot_seeds.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:string_mesh",
+ "result": "minecraft:beetroot_seeds",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.35
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/flint.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/flint.json
new file mode 100644
index 00000000..a9d4fce5
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/flint.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:string_mesh",
+ "result": "minecraft:flint",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.25
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/melon_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/melon_seeds.json
new file mode 100644
index 00000000..7537db58
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/melon_seeds.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:string_mesh",
+ "result": "minecraft:melon_seeds",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.35
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/pumpkin_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/pumpkin_seeds.json
new file mode 100644
index 00000000..697b5199
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/pumpkin_seeds.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:string_mesh",
+ "result": "minecraft:pumpkin_seeds",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.35
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/stone_pebble.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/stone_pebble.json
new file mode 100644
index 00000000..cd2e1897
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/stone_pebble.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:string_mesh",
+ "result": "exnihiloreborn:stone_pebble",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 7.0,
+ "p": 0.6
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/wheat_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/wheat_seeds.json
new file mode 100644
index 00000000..0e875504
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/sieve/string/wheat_seeds.json
@@ -0,0 +1,13 @@
+{
+ "type": "exnihiloreborn:sieve",
+ "ingredient": {
+ "item": "minecraft:dirt"
+ },
+ "mesh": "exnihiloreborn:string_mesh",
+ "result": "minecraft:wheat_seeds",
+ "result_amount": {
+ "type": "minecraft:binomial",
+ "n": 1.0,
+ "p": 0.7
+ }
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/sieve/wheat_seeds.json b/src/generated/resources/data/exnihiloreborn/recipes/sieve/wheat_seeds.json
deleted file mode 100644
index 615aabf2..00000000
--- a/src/generated/resources/data/exnihiloreborn/recipes/sieve/wheat_seeds.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "type": "exnihiloreborn:sieve",
- "ingredient": {
- "item": "minecraft:dirt"
- },
- "mesh": "exnihiloreborn:string_mesh",
- "rewards": [
- {
- "chance": 0.7,
- "item": {
- "Count": 1,
- "id": "minecraft:wheat_seeds"
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/recipes/string_mesh.json b/src/generated/resources/data/exnihiloreborn/recipes/string_mesh.json
new file mode 100644
index 00000000..f422f605
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/recipes/string_mesh.json
@@ -0,0 +1,18 @@
+{
+ "type": "minecraft:crafting_shaped",
+ "category": "misc",
+ "key": {
+ "s": {
+ "tag": "forge:string"
+ }
+ },
+ "pattern": [
+ "sss",
+ "sss",
+ "sss"
+ ],
+ "result": {
+ "item": "exnihiloreborn:string_mesh"
+ },
+ "show_notification": true
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/tags/items/pebbles.json b/src/generated/resources/data/exnihiloreborn/tags/items/pebbles.json
new file mode 100644
index 00000000..a5ac2823
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/tags/items/pebbles.json
@@ -0,0 +1,10 @@
+{
+ "values": [
+ "exnihiloreborn:stone_pebble",
+ "exnihiloreborn:diorite_pebble",
+ "exnihiloreborn:granite_pebble",
+ "exnihiloreborn:andesite_pebble",
+ "exnihiloreborn:deepslate_pebble",
+ "exnihiloreborn:tuff_pebble"
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/tags/items/sieve_meshes.json b/src/generated/resources/data/exnihiloreborn/tags/items/sieve_meshes.json
new file mode 100644
index 00000000..c16e5f40
--- /dev/null
+++ b/src/generated/resources/data/exnihiloreborn/tags/items/sieve_meshes.json
@@ -0,0 +1,10 @@
+{
+ "values": [
+ "exnihiloreborn:string_mesh",
+ "exnihiloreborn:flint_mesh",
+ "exnihiloreborn:iron_mesh",
+ "exnihiloreborn:golden_mesh",
+ "exnihiloreborn:diamond_mesh",
+ "exnihiloreborn:netherite_mesh"
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/exnihiloreborn/tags/worldgen/structure_set/the_end_void_structure_sets.json b/src/generated/resources/data/exnihiloreborn/tags/worldgen/structure_set/the_end_void_structure_sets.json
index f72d209d..84d8fdd4 100644
--- a/src/generated/resources/data/exnihiloreborn/tags/worldgen/structure_set/the_end_void_structure_sets.json
+++ b/src/generated/resources/data/exnihiloreborn/tags/worldgen/structure_set/the_end_void_structure_sets.json
@@ -1,3 +1,5 @@
{
- "values": []
+ "values": [
+ "minecraft:end_cities"
+ ]
}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json b/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json
new file mode 100644
index 00000000..14c17b08
--- /dev/null
+++ b/src/generated/resources/data/minecraft/tags/blocks/mineable/axe.json
@@ -0,0 +1,37 @@
+{
+ "values": [
+ "exnihiloreborn:oak_barrel",
+ "exnihiloreborn:spruce_barrel",
+ "exnihiloreborn:birch_barrel",
+ "exnihiloreborn:jungle_barrel",
+ "exnihiloreborn:acacia_barrel",
+ "exnihiloreborn:dark_oak_barrel",
+ "exnihiloreborn:mangrove_barrel",
+ "exnihiloreborn:cherry_barrel",
+ "exnihiloreborn:bamboo_barrel",
+ "exnihiloreborn:crimson_barrel",
+ "exnihiloreborn:warped_barrel",
+ "exnihiloreborn:oak_sieve",
+ "exnihiloreborn:spruce_sieve",
+ "exnihiloreborn:birch_sieve",
+ "exnihiloreborn:jungle_sieve",
+ "exnihiloreborn:acacia_sieve",
+ "exnihiloreborn:dark_oak_sieve",
+ "exnihiloreborn:mangrove_sieve",
+ "exnihiloreborn:cherry_sieve",
+ "exnihiloreborn:bamboo_sieve",
+ "exnihiloreborn:crimson_sieve",
+ "exnihiloreborn:warped_sieve",
+ "exnihiloreborn:warped_crucible",
+ "exnihiloreborn:crimson_crucible",
+ "exnihiloreborn:oak_crucible",
+ "exnihiloreborn:spruce_crucible",
+ "exnihiloreborn:birch_crucible",
+ "exnihiloreborn:jungle_crucible",
+ "exnihiloreborn:acacia_crucible",
+ "exnihiloreborn:dark_oak_crucible",
+ "exnihiloreborn:mangrove_crucible",
+ "exnihiloreborn:cherry_crucible",
+ "exnihiloreborn:bamboo_crucible"
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json
new file mode 100644
index 00000000..87a85aac
--- /dev/null
+++ b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json
@@ -0,0 +1,7 @@
+{
+ "values": [
+ "exnihiloreborn:stone_barrel",
+ "exnihiloreborn:porcelain_crucible",
+ "exnihiloreborn:unfired_crucible"
+ ]
+}
\ No newline at end of file
diff --git a/src/generated/resources/data/minecraft/tags/fluids/water.json b/src/generated/resources/data/minecraft/tags/fluids/water.json
new file mode 100644
index 00000000..52ebf9a9
--- /dev/null
+++ b/src/generated/resources/data/minecraft/tags/fluids/water.json
@@ -0,0 +1,6 @@
+{
+ "values": [
+ "exnihiloreborn:witch_water",
+ "exnihiloreborn:flowing_witch_water"
+ ]
+}
\ No newline at end of file
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/block/BarrelBlock.java b/src/main/java/thedarkcolour/exnihiloreborn/block/BarrelBlock.java
index f5409e5f..6e4d4fa8 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/block/BarrelBlock.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/block/BarrelBlock.java
@@ -48,7 +48,7 @@ public class BarrelBlock extends Block implements EntityBlock {
@Nullable
@Override
public BlockEntityTicker getTicker(Level level, BlockState pState, BlockEntityType type) {
- return !level.isClientSide && type == EBlockEntities.BARREL.get() ? (BlockEntityTicker) new BarrelBlockEntity.Ticker() : null;
+ return type == EBlockEntities.BARREL.get() ? (BlockEntityTicker) new BarrelBlockEntity.Ticker() : null;
}
@Override
@@ -73,7 +73,7 @@ public class BarrelBlock extends Block implements EntityBlock {
var item = barrel.getItem();
if (!item.isEmpty()) {
- Containers.dropContents(level, pos, NonNullList.of(ItemStack.EMPTY, item));
+ EBlock.dropItem(level, pos, item);
}
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/block/EBlock.java b/src/main/java/thedarkcolour/exnihiloreborn/block/EBlock.java
index c4fc4c44..cdb04ef8 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/block/EBlock.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/block/EBlock.java
@@ -1,9 +1,11 @@
package thedarkcolour.exnihiloreborn.block;
import net.minecraft.core.BlockPos;
+import net.minecraft.world.Containers;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
@@ -38,4 +40,8 @@ public abstract class EBlock extends Block implements EntityBlock {
return InteractionResult.PASS;
}
+
+ public static void dropItem(Level level, BlockPos pos, ItemStack stack) {
+ Containers.dropItemStack(level, pos.getX(), pos.getY(), pos.getZ(), stack);
+ }
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/block/InfestedLeavesBlock.java b/src/main/java/thedarkcolour/exnihiloreborn/block/InfestedLeavesBlock.java
index 33e2209d..5c84dfea 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/block/InfestedLeavesBlock.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/block/InfestedLeavesBlock.java
@@ -38,13 +38,14 @@ public class InfestedLeavesBlock extends LeavesBlock implements EntityBlock {
@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
- return !state.getValue(FULLY_INFESTED) ? new InfestedLeavesBlockEntity(pos, state) : null;
+ return new InfestedLeavesBlockEntity(pos, state);
}
+ @SuppressWarnings("unchecked")
@Nullable
@Override
public BlockEntityTicker getTicker(Level pLevel, BlockState state, BlockEntityType type) {
- return (type == EBlockEntities.INFESTED_LEAVES.get() && !state.getValue(FULLY_INFESTED)) ? (BlockEntityTicker) new InfestedLeavesBlockEntity.Ticker() : null;
+ return (type == EBlockEntities.INFESTED_LEAVES.get()) ? (BlockEntityTicker) new InfestedLeavesBlockEntity.Ticker() : null;
}
@Override
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/block/SieveBlock.java b/src/main/java/thedarkcolour/exnihiloreborn/block/SieveBlock.java
index 27189340..b9fca24a 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/block/SieveBlock.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/block/SieveBlock.java
@@ -2,26 +2,52 @@ package thedarkcolour.exnihiloreborn.block;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
+import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
+import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import thedarkcolour.exnihiloreborn.blockentity.SieveBlockEntity;
import thedarkcolour.exnihiloreborn.registry.EBlockEntities;
public class SieveBlock extends EBlock {
+ public static final VoxelShape SHAPE = Shapes.or(
+ box(0, 11, 0, 16, 16, 16),
+ box(1, 0, 1, 2, 11, 2),
+ box(14, 0, 1, 15, 11, 2),
+ box(1, 0, 14, 2, 11, 15),
+ box(14, 0, 14, 15, 11, 15)
+ );
+
public SieveBlock(Properties properties) {
super(properties, EBlockEntities.SIEVE);
}
- // todo
@Override
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
- return super.getShape(state, level, pos, context);
+ return SHAPE;
}
@Override
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
return new SieveBlockEntity(pos, state);
}
+
+ @Override
+ public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean pIsMoving) {
+ if (!level.isClientSide) {
+ if (!state.is(newState.getBlock())) {
+ if (level.getBlockEntity(pos) instanceof SieveBlockEntity sieve) {
+ var mesh = sieve.getMesh();
+
+ if (!mesh.isEmpty()) {
+ dropItem(level, pos, mesh);
+ }
+ }
+ }
+ }
+
+ super.onRemove(state, level, pos, newState, pIsMoving);
+ }
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/AbstractCrucibleBlockEntity.java b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/AbstractCrucibleBlockEntity.java
index c49ca684..c624a049 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/AbstractCrucibleBlockEntity.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/AbstractCrucibleBlockEntity.java
@@ -1,6 +1,5 @@
package thedarkcolour.exnihiloreborn.blockentity;
-import com.google.common.cache.Cache;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@@ -12,7 +11,6 @@ import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
-import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
@@ -111,22 +109,7 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
}
// Gets a crucible recipe, using the cache if possible
- public CrucibleRecipe getRecipe(ItemStack item) {
- var pair = new CacheKey(item.getItem(), item.getTag());
- var recipe = getRecipeCache().getIfPresent(pair);
-
- if (recipe != null) {
- return recipe;
- } else {
- CrucibleRecipe newRecipe = RecipeUtil.getRecipe(level.getServer(), getRecipeType(), item);
-
- if (newRecipe != null) {
- getRecipeCache().put(pair, newRecipe); // You can't put null values in a cache...
- }
-
- return newRecipe;
- }
- }
+ protected abstract CrucibleRecipe getRecipe(ItemStack item);
/**
* Tries to melt the specified item into the crucible.
@@ -167,7 +150,7 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
}
}
- public int getMelt() {
+ public int getMeltingRate() {
return 1;
}
@@ -179,12 +162,8 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
return tank;
}
- protected abstract RecipeType getRecipeType();
-
protected abstract Block getDefaultMeltBlock();
- protected abstract Cache getRecipeCache();
-
public Block getLastMelted() {
return lastMelted;
}
@@ -207,9 +186,6 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
overrides.put(Items.MANGROVE_PROPAGULE, Blocks.MANGROVE_LEAVES);
}
- public record CacheKey(Item item, CompoundTag tag) {
- }
-
private static class FluidHandler extends FluidTank {
public FluidHandler() {
super(4_000);
@@ -249,7 +225,7 @@ public abstract class AbstractCrucibleBlockEntity extends EBlockEntity {
public void tick(Level level, BlockPos pos, BlockState state, AbstractCrucibleBlockEntity crucible) {
// Update twice per tick
if ((level.getGameTime() % 10L) == 0L) {
- int delta = Math.min(crucible.solids, crucible.getMelt());
+ int delta = Math.min(crucible.solids, crucible.getMeltingRate());
// Skip if no heat
if (delta <= 0) return;
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/BarrelBlockEntity.java b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/BarrelBlockEntity.java
index 7e368e59..7a6df59f 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/BarrelBlockEntity.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/BarrelBlockEntity.java
@@ -4,41 +4,39 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
-import net.minecraft.util.Mth;
+import net.minecraft.sounds.SoundEvents;
+import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
-import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
-import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.state.BlockState;
-import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.Fluids;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemStackHandler;
+import org.jetbrains.annotations.NotNull;
import org.joml.Vector3i;
import thedarkcolour.exnihiloreborn.client.CompostColors;
+import thedarkcolour.exnihiloreborn.recipe.RecipeUtil;
import thedarkcolour.exnihiloreborn.registry.EBlockEntities;
import thedarkcolour.exnihiloreborn.registry.EFluids;
-import thedarkcolour.exnihiloreborn.registry.EItems;
-import thedarkcolour.exnihiloreborn.registry.ERecipeTypes;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-// todo test which refresh calls can be removed to avoid network spam
public class BarrelBlockEntity extends EBlockEntity {
private static final float PROGRESS_STEP = 1.0f / 300.0f;
@@ -99,15 +97,17 @@ public class BarrelBlockEntity extends EBlockEntity {
}
public boolean isBurning() {
- return hasHotFluid() && progress != 0.0f;
+ return isHotFluid(tank.getFluid().getFluid().getFluidType()) && progress != 0.0f;
}
+ // Composting is in progress if at 1000. When finished, compost is set back to 0
public boolean isComposting() {
return compost == 1000;
}
- public boolean hasContents() {
- return compost > 0 || !item.getStackInSlot(0).isEmpty();
+ // Returns true if there are no solid ingredients (can a fluid be inserted?)
+ public boolean isEmptySolids() {
+ return compost <= 0 && item.getStackInSlot(0).isEmpty();
}
public boolean hasFullWater() {
@@ -115,9 +115,9 @@ public class BarrelBlockEntity extends EBlockEntity {
}
// Burning temp of wood according to google is 300 C or ~575 kelvin
- // Molten Constantan from Thermal Expansion is only 650 kelvin, but this should be fine
- public boolean hasHotFluid() {
- return tank.getFluid().getFluid().getFluidType().getTemperature() > 575;
+ // Molten Constantan from Thermal Expansion is 650 kelvin, so this should be fine
+ public static boolean isHotFluid(FluidType fluidType) {
+ return fluidType.getTemperature() > 575;
}
private void spawnBurningParticles() {
@@ -142,132 +142,142 @@ public class BarrelBlockEntity extends EBlockEntity {
}
public InteractionResult use(Level level, BlockPos pos, Player player, InteractionHand hand) {
- var isClientSide = level.isClientSide;
-
// Collect an item
if (!getItem().isEmpty()) {
- return giveItem(level, pos, isClientSide);
+ return giveResultItem(level, pos, player);
}
// Handle item fluid interaction
- if (!hasContents()) {
+ if (isEmptySolids()) {
var wasBurning = isBurning();
if (FluidUtil.interactWithFluidHandler(player, hand, tank)) {
- if (wasBurning && !hasHotFluid()) {
+ if (wasBurning && !isHotFluid(tank.getFluid().getFluid().getFluidType())) {
progress = 0.0f;
}
- return InteractionResult.sidedSuccess(isClientSide);
+ return InteractionResult.sidedSuccess(level.isClientSide);
}
}
var playerItem = player.getItemInHand(hand);
-
- // Handle compost
- if (tank.isEmpty()) {
- var inventory = new SimpleContainer(playerItem);
-
- if (compost < 1000) {
- if (!level.isClientSide) {
- // todo cache items to recipe
- level.getServer().getRecipeManager().getRecipeFor(ERecipeTypes.BARREL_COMPOST.get(), inventory, level).ifPresent(recipe -> {
- if (!CompostColors.isLoaded()) {
- CompostColors.loadColors();
- }
-
- int oldCompost = compost;
- compost = (short) Math.min(1000, compost + recipe.getVolume());
-
- if (compost != 0) {
- float weightNew = (float) (compost - oldCompost) / compost;
- float weightOld = 1 - weightNew;
- var color = CompostColors.COLORS.getOrDefault(playerItem.getItem(), new Vector3i(53, 168, 42));
-
- r = (short) (weightNew * color.x + weightOld * r);
- g = (short) (weightNew * color.y + weightOld * g);
- b = (short) (weightNew * color.z + weightOld * b);
-
- markUpdated();
-
- // Consume item
- if (!player.getAbilities().instabuild) {
- playerItem.shrink(1);
- }
- }
- });
- }
-
- return InteractionResult.sidedSuccess(isClientSide);
+ if (!level.isClientSide) {
+ var remainder = item.insertItem(0, player.getAbilities().instabuild ? playerItem.copy() : playerItem, false);
+ if (!player.getAbilities().instabuild) {
+ player.setItemInHand(hand, remainder);
}
}
- // Mixing
- if (!playerItem.isEmpty()) {
- var fluid = tank.getFluid();
- var container = playerItem.getCraftingRemainingItem();
-
- if (fluid.getAmount() == 1000) {
- // todo custom mixing recipes
- if (doMix(playerItem, isClientSide)) {
- if (!isClientSide && playerItem.isEmpty()) {
- player.setItemInHand(hand, container);
- }
- return InteractionResult.sidedSuccess(isClientSide);
- }
- }
- }
-
- return InteractionResult.CONSUME;
+ return InteractionResult.sidedSuccess(level.isClientSide);
}
- private InteractionResult giveItem(Level level, BlockPos pos, boolean isClientSide) {
- if (!isClientSide) {
+ private void addCompost(ItemStack playerItem, int volume, boolean consume) {
+ int oldCompost = compost;
+ compost = (short) Math.min(1000, compost + volume);
+
+ if (compost != 0) {
+ if (!CompostColors.isLoaded()) {
+ CompostColors.loadColors();
+ }
+
+ float weightNew = (float) (compost - oldCompost) / compost;
+ float weightOld = 1 - weightNew;
+ var color = CompostColors.COLORS.getOrDefault(playerItem.getItem(), new Vector3i(53, 168, 42));
+
+ r = (short) (weightNew * color.x + weightOld * r);
+ g = (short) (weightNew * color.y + weightOld * g);
+ b = (short) (weightNew * color.z + weightOld * b);
+
+ // Consume item
+ if (consume) {
+ playerItem.shrink(1);
+ }
+ }
+
+ level.playSound(null, worldPosition, SoundEvents.COMPOSTER_FILL, SoundSource.BLOCKS);
+ }
+
+ // Pops the item out of the barrel (ex. dirt that has finished composting)
+ private InteractionResult giveResultItem(Level level, BlockPos pos, Player player) {
+ var rand = level.random;
+ if (!level.isClientSide) {
// Pop out item
var itemEntity = new ItemEntity(level, pos.getX() + 0.5, pos.getY() + 1.5, pos.getZ() + 0.5, item.extract(false));
- var rand = level.random;
itemEntity.setDeltaMovement(rand.nextGaussian() * 0.05, 0.2, rand.nextGaussian() * 0.05);
level.addFreshEntity(itemEntity);
// Empty contents
setItem(ItemStack.EMPTY);
+ markUpdated();
}
- return InteractionResult.sidedSuccess(isClientSide);
+ return InteractionResult.sidedSuccess(level.isClientSide);
}
/**
- * @param fluid Fluid in the barrel
- * @param catalyst Item to mix with the fluid
- * @param result Item (preferable a block) crafted by this mix
- * @param playerItem Player's item to check and consume (test item if simulated)
- * @param simulate Whether to simulate the mix
- * @return if the mix succeeded (if simulated, whether the mix is possible)
+ * @param input The input item to craft with
+ * @param simulate Whether the craft should actually take place
+ * @return The resulting item after crafting
*/
- private boolean mix(Fluid fluid, Item catalyst, Item result, ItemStack playerItem, boolean simulate) {
- if (tank.getFluid().getFluid() == fluid && playerItem.getItem() == catalyst) {
+ private ItemStack tryCrafting(ItemStack input, boolean simulate) {
+ boolean crafted = false;
+ var remainder = input.getCraftingRemainingItem();
+ if (!tank.isEmpty()) {
+ crafted = tryMixing(input, simulate);
+ } else if (!isComposting()) {
+ crafted = tryComposting(input, simulate);
+ }
+
+ if (crafted) {
+ if (!simulate) {
+ markUpdated();
+ }
+ return remainder;
+ } else {
+ return input;
+ }
+ }
+
+ /**
+ * @param playerItem The item to try to mix with this barrel's fluid
+ * @param simulate Whether this is a test or the player is actually mixing with the barrel
+ * @return Whether something was mixed (if simulated, whether the mix is possible)
+ */
+ private boolean tryMixing(ItemStack playerItem, boolean simulate) {
+ var recipe = RecipeUtil.getBarrelMixingRecipe(level.getRecipeManager(), playerItem, this.tank.getFluid());
+
+ if (recipe != null) {
+ if (isBurning()) {
+ return false;
+ }
if (!simulate) {
// Consumer player input
playerItem.shrink(1);
// Empty barrel
tank.setFluid(FluidStack.EMPTY);
// Replace fluid with result
- setItem(new ItemStack(result));
+ setItem(new ItemStack(recipe.result));
+ level.playSound(null, worldPosition, SoundEvents.AMBIENT_UNDERWATER_EXIT, SoundSource.BLOCKS, 0.8f, 0.8f);
}
-
+ // Mixing was successful, so return true
return true;
+ } else {
+ return false;
}
-
- return false;
}
- private boolean doMix(ItemStack playerItem, boolean simulate) {
- return mix(Fluids.WATER, EItems.DUST.get(), Items.CLAY, playerItem, simulate) ||
- mix(Fluids.WATER, Items.MILK_BUCKET, Items.SLIME_BLOCK, playerItem, simulate) ||
- mix(EFluids.WITCH_WATER_STILL.get(), Items.SAND, Items.SOUL_SAND, playerItem, simulate) ||
- mix(Fluids.LAVA, Items.REDSTONE, Items.NETHERRACK, playerItem, simulate) ||
- mix(Fluids.LAVA, Items.GLOWSTONE_DUST, Items.END_STONE, playerItem, simulate) ||
- mix(Fluids.LAVA, Items.WATER_BUCKET, Items.OBSIDIAN, playerItem, simulate);
+ private boolean tryComposting(ItemStack stack, boolean simulate) {
+ if (simulate) {
+ return RecipeUtil.isCompostable(stack);
+ } else {
+ var recipe = RecipeUtil.getBarrelCompostRecipe(stack);
+ if (recipe != null) {
+ addCompost(stack, recipe.getVolume(), true);
+ return true;
+ } else {
+ return false;
+ }
+ }
}
public static class Ticker implements BlockEntityTicker {
@@ -276,14 +286,7 @@ public class BarrelBlockEntity extends EBlockEntity {
if (!level.isClientSide) {
// Turn compost to dirt
if (barrel.isComposting()) {
- barrel.progress += PROGRESS_STEP;
- barrel.markUpdated();
-
- if (barrel.progress >= 1.0f) {
- barrel.progress = 0.0f;
- barrel.compost = 0;
- barrel.setItem(new ItemStack(Items.DIRT));
- }
+ barrel.doCompost();
} else if (barrel.hasFullWater()) {
var rand = level.random;
var mycelium = 0f;
@@ -318,7 +321,7 @@ public class BarrelBlockEntity extends EBlockEntity {
barrel.tank.setFluid(new FluidStack(EFluids.WITCH_WATER_STILL.get(), barrel.tank.getFluidAmount()));
}
- } else if (barrel.hasHotFluid()) {
+ } else if (isHotFluid(barrel.tank.getFluid().getFluid().getFluidType())) {
if (state.ignitedByLava()) {
if ((barrel.progress += PROGRESS_STEP) >= 1.0f) {
if (barrel.tank.getFluidAmount() == 1000) {
@@ -337,6 +340,18 @@ public class BarrelBlockEntity extends EBlockEntity {
}
}
+ private void doCompost() {
+ progress += PROGRESS_STEP;
+ markUpdated();
+
+ if (progress >= 1.0f) {
+ progress = 0.0f;
+ compost = 0;
+ setItem(new ItemStack(Items.DIRT));
+ level.playSound(null, worldPosition, SoundEvents.COMPOSTER_READY, SoundSource.BLOCKS);
+ }
+ }
+
// Inner class
private class ItemHandler extends ItemStackHandler {
@Override
@@ -346,23 +361,36 @@ public class BarrelBlockEntity extends EBlockEntity {
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
- FluidStack fluid = tank.getFluid();
+ // if the resulting item from crafting is different (ex. EMPTY or bucket) then we can craft with it
+ return !ItemStack.matches(tryCrafting(stack, true), stack);
+ }
- if (fluid.getAmount() == 1000) {
- return doMix(stack, true);
- }
+ // Copy of ItemStackHandler.insertItem which handles barrel crafting remainders better
+ @Override
+ public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) {
+ if (stack.isEmpty())
+ return ItemStack.EMPTY;
+ validateSlotIndex(slot);
+ if (!stacks.get(slot).isEmpty())
+ return stack;
- return false;
+ return tryCrafting(stack, simulate);
}
public ItemStack extract(boolean simulate) {
return extractItem(0, 1, simulate);
}
+ @Override
+ public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) {
+ return super.extractItem(slot, amount, simulate);
+ }
+
@Override
protected void onContentsChanged(int slot) {
- doMix(stacks.get(slot).copy(), level.isClientSide);
- markUpdated();
+ if (!level.isClientSide) {
+ markUpdated();
+ }
}
}
@@ -374,7 +402,7 @@ public class BarrelBlockEntity extends EBlockEntity {
@Override
public boolean isFluidValid(FluidStack stack) {
- return !isBrewing() && !hasContents();
+ return !isBrewing() && BarrelBlockEntity.this.isEmptySolids();
}
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/EBlockEntity.java b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/EBlockEntity.java
index d2a61b3a..7a7d61f0 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/EBlockEntity.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/EBlockEntity.java
@@ -1,16 +1,23 @@
package thedarkcolour.exnihiloreborn.blockentity;
import net.minecraft.core.BlockPos;
+import net.minecraft.core.SectionPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.Connection;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.chunk.ChunkStatus;
+import net.minecraft.world.level.chunk.LevelChunk;
+import net.minecraftforge.network.NetworkDirection;
+import thedarkcolour.exnihiloreborn.network.NetworkHandler;
+import thedarkcolour.exnihiloreborn.network.VoidWorldMessage;
import javax.annotation.Nullable;
@@ -39,7 +46,6 @@ public abstract class EBlockEntity extends BlockEntity {
}
}
- // todo replace with smaller PropertyUpdate packets so we don't send a bunch of data every tick
protected void markUpdated() {
setChanged();
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 2);
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/InfestedLeavesBlockEntity.java b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/InfestedLeavesBlockEntity.java
index 078b20c7..fb7f385a 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/InfestedLeavesBlockEntity.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/InfestedLeavesBlockEntity.java
@@ -10,12 +10,13 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.state.BlockState;
+import thedarkcolour.exnihiloreborn.block.InfestedLeavesBlock;
import thedarkcolour.exnihiloreborn.registry.EBlockEntities;
import thedarkcolour.exnihiloreborn.registry.EBlocks;
public class InfestedLeavesBlockEntity extends EBlockEntity {
public static final float PROGRESS_INTERVAL = 0.005f;
- public static final int SPREAD_INTERVAL = 100;
+ public static final int SPREAD_INTERVAL = 50;
// A percentage of how much this leaf is infested
private float progress;
@@ -93,6 +94,9 @@ public class InfestedLeavesBlockEntity extends EBlockEntity {
// Do progress
if (leaves.progress < 1.0f) {
leaves.progress = Math.min(1.0f, leaves.progress + PROGRESS_INTERVAL);
+ if (leaves.progress == 1.0f) {
+ level.setBlock(pos, state.setValue(InfestedLeavesBlock.FULLY_INFESTED, true), 3);
+ }
}
// If the leave is infested enough, advance the spread timer
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/LavaCrucibleBlockEntity.java b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/LavaCrucibleBlockEntity.java
index 69bdd91c..eaa4408d 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/LavaCrucibleBlockEntity.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/LavaCrucibleBlockEntity.java
@@ -1,21 +1,17 @@
package thedarkcolour.exnihiloreborn.blockentity;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.minecraft.core.BlockPos;
-import net.minecraft.world.item.crafting.RecipeType;
+import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
+import thedarkcolour.exnihiloreborn.recipe.RecipeUtil;
import thedarkcolour.exnihiloreborn.recipe.crucible.CrucibleRecipe;
import thedarkcolour.exnihiloreborn.registry.EBlockEntities;
-import thedarkcolour.exnihiloreborn.registry.ERecipeTypes;
public class LavaCrucibleBlockEntity extends AbstractCrucibleBlockEntity {
- public static final Cache RECIPES_CACHE = CacheBuilder.newBuilder().maximumSize(12).build();
-
// todo add KubeJS support for this
private static final Object2IntMap HEAT_REGISTRY = new Object2IntOpenHashMap<>();
@@ -34,24 +30,19 @@ public class LavaCrucibleBlockEntity extends AbstractCrucibleBlockEntity {
}
@Override
- public int getMelt() {
+ public int getMeltingRate() {
BlockState state = level.getBlockState(getBlockPos().below());
return HEAT_REGISTRY.getInt(state.getBlock());
}
@Override
- protected RecipeType getRecipeType() {
- return ERecipeTypes.LAVA_CRUCIBLE.get();
+ protected CrucibleRecipe getRecipe(ItemStack item) {
+ return RecipeUtil.getLavaCrucibleRecipe(item);
}
@Override
protected Block getDefaultMeltBlock() {
return Blocks.COBBLESTONE;
}
-
- @Override
- protected Cache getRecipeCache() {
- return RECIPES_CACHE;
- }
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/RecipeUtil.java b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/RecipeUtil.java
deleted file mode 100644
index 6e4ed79e..00000000
--- a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/RecipeUtil.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package thedarkcolour.exnihiloreborn.blockentity;
-
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.world.Container;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.Recipe;
-import net.minecraft.world.item.crafting.RecipeType;
-import thedarkcolour.exnihiloreborn.recipe.SingleIngredientRecipe;
-import thedarkcolour.exnihiloreborn.recipe.sieve.SieveRecipe;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-public final class RecipeUtil {
- public static List getSieveResults(MinecraftServer server, RecipeType type, ItemStack mesh, ItemStack item) {
- ArrayList recipes = new ArrayList<>();
-
- for (T recipe : byType(server, type)) {
- if (recipe.test(mesh.getItem(), item)) {
- recipes.add(recipe);
- }
- }
-
- return recipes.isEmpty() ? Collections.emptyList() : recipes;
- }
-
- public static T getRecipe(MinecraftServer server, RecipeType type, ItemStack item) {
- for (T recipe : byType(server, type)) {
- if (recipe.getIngredient().test(item)) {
- return recipe;
- }
- }
-
- return null;
- }
-
- public static > Collection byType(MinecraftServer server, RecipeType type) {
- return server.getRecipeManager().byType(type).values();
- }
-}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/SieveBlockEntity.java b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/SieveBlockEntity.java
index 2d3e4506..2012e6e7 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/SieveBlockEntity.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/SieveBlockEntity.java
@@ -1,67 +1,45 @@
package thedarkcolour.exnihiloreborn.blockentity;
import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.RecipeType;
+import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
-import net.minecraftforge.common.capabilities.Capability;
-import net.minecraftforge.common.capabilities.ForgeCapabilities;
-import net.minecraftforge.common.util.LazyOptional;
-import net.minecraftforge.items.IItemHandler;
-import net.minecraftforge.items.ItemStackHandler;
-import thedarkcolour.exnihiloreborn.recipe.Reward;
+import net.minecraft.world.level.storage.loot.LootContext;
+import net.minecraft.world.level.storage.loot.LootParams;
+import thedarkcolour.exnihiloreborn.recipe.RecipeUtil;
import thedarkcolour.exnihiloreborn.recipe.sieve.SieveRecipe;
import thedarkcolour.exnihiloreborn.registry.EBlockEntities;
-import thedarkcolour.exnihiloreborn.registry.EItems;
-import thedarkcolour.exnihiloreborn.registry.ERecipeTypes;
+import thedarkcolour.exnihiloreborn.tag.EItemTags;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import java.util.Collections;
-import java.util.List;
+import java.util.Map;
public class SieveBlockEntity extends EBlockEntity {
public static final short MAX_SIEVE_CAPACITY = 100;
public static final short SIEVE_INTERVAL = 10;
- private final SieveBlockEntity.ItemHandler item = new SieveBlockEntity.ItemHandler();
+ private ItemStack contents = ItemStack.EMPTY;
private ItemStack mesh = ItemStack.EMPTY;
private short progress = 0; // Max is 100
-
- // Does not persist in NBT, just a cache
- // todo invalidate on /reload
- private List extends SieveRecipe> currentRecipe = Collections.emptyList();
+ private float efficiency = 1f;
+ private float fortune = 1f;
public SieveBlockEntity(BlockPos pos, BlockState state) {
super(EBlockEntities.SIEVE.get(), pos, state);
}
- // Capabilities
- private final LazyOptional itemHandler = LazyOptional.of(() -> item);
-
- @Nonnull
- @Override
- public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) {
- if (cap == ForgeCapabilities.ITEM_HANDLER) {
- return itemHandler.cast();
- }
-
- return super.getCapability(cap, side);
- }
-
@Override
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
- nbt.put("item", item.serializeNBT());
- nbt.putShort("Progress", progress);
+ nbt.put("contents", contents.serializeNBT());
+ nbt.putShort("progress", progress);
if (!mesh.isEmpty()) {
nbt.put("mesh", mesh.save(new CompoundTag()));
}
@@ -69,10 +47,16 @@ public class SieveBlockEntity extends EBlockEntity {
@Override
public void load(CompoundTag nbt) {
- item.deserializeNBT(nbt.getCompound("item"));
- progress = nbt.getShort("progress");
+ if (nbt.contains("contents")) {
+ this.contents = ItemStack.of(nbt.getCompound("contents"));
+ } else {
+ this.contents = ItemStack.EMPTY;
+ }
+ this.progress = nbt.getShort("progress");
if (nbt.contains("mesh")) {
- mesh = ItemStack.of(nbt.getCompound("Mesh"));
+ setMesh(ItemStack.of(nbt.getCompound("mesh")));
+ } else {
+ setMesh(ItemStack.EMPTY);
}
super.load(nbt);
@@ -85,111 +69,183 @@ public class SieveBlockEntity extends EBlockEntity {
// Try insert mesh
if (mesh.isEmpty()) {
if (isMesh(playerItem)) {
- mesh = playerItem.copy();
- mesh.setCount(1);
+ if (!level.isClientSide) {
+ var meshCopy = playerItem.copy();
+ meshCopy.setCount(1);
+ setMesh(meshCopy);
- // Remove stack
- if (!player.isCreative()) {
- player.setItemInHand(hand, ItemStack.EMPTY);
+ markUpdated();
+
+ if (!player.getAbilities().instabuild) {
+ playerItem.shrink(1);
+ }
+ return InteractionResult.CONSUME;
+ } else {
+ return InteractionResult.SUCCESS;
}
}
+ } else if (contents.isEmpty()) {
+ // remove mesh with sneak right click
+ if (player.isShiftKeyDown() && player.getMainHandItem().isEmpty()) {
+ removeMesh();
+ }
}
- if (progress == 0) {
+ if (contents.isEmpty()) {
// Insert an item
if (!isClientSide) {
- // Check against cached recipe
- if (!currentRecipe.isEmpty()) {
- for (SieveRecipe recipe : currentRecipe) {
- if (!recipe.test(mesh.getItem(), playerItem)) {
- return InteractionResult.CONSUME;
- }
- }
+ if (RecipeUtil.hasSieveResult(level.getRecipeManager(), mesh.getItem(), playerItem)) {
+ playerItem = this.insertContents(player, hand);
+ markUpdated();
- player.setItemInHand(hand, fillWithItem(playerItem));
- markUpdated();
- } else if (!(currentRecipe = getResults(playerItem)).isEmpty()) {
- player.setItemInHand(hand, fillWithItem(playerItem));
- markUpdated();
+ var cursor = worldPosition.mutable().move(-1, 0, -1);
+
+ // Fill adjacent sieves
+ otherSieves:
+ for (int x = -1; x <= 1; x++) {
+ for (int z = -1; z <= 1; z++) {
+ if (playerItem.isEmpty()) {
+ break otherSieves;
+ }
+
+ if ((x | z) != 0) {
+ if (level.getBlockEntity(cursor) instanceof SieveBlockEntity other) {
+ if (other.contents.isEmpty()) {
+ if (this.mesh.getItem() == other.mesh.getItem()) {
+ playerItem = other.insertContents(player, hand);
+ other.markUpdated();
+ }
+ }
+ }
+ }
+
+ cursor.move(0, 0, 1);
+ }
+ cursor.move(1, 0, -3);
+ }
}
}
} else {
- // todo mesh efficiency enchantment
- progress -= SIEVE_INTERVAL;
+ var cursor = worldPosition.mutable().move(-1, 0, -1);
- if (progress <= 0) {
- progress = 0;
+ // Sieve with adjacent sieves
+ for (int x = -1; x <= 1; x++) {
+ for (int z = -1; z <= 1; z++) {
+ if (level.getBlockEntity(cursor) instanceof SieveBlockEntity other) {
+ if (!other.contents.isEmpty()) {
+ if (this.mesh.getItem() == other.mesh.getItem()) {
+ other.performSift(player);
+ }
+ }
+ }
- if (!isClientSide) {
- giveItems();
+ cursor.move(0, 0, 1);
}
+ cursor.move(1, 0, -3);
}
}
return InteractionResult.sidedSuccess(isClientSide);
}
- // Consumes an item and fills the sieve.
- private ItemStack fillWithItem(ItemStack stack) {
- progress = MAX_SIEVE_CAPACITY;
+ // Fills the sieve (assumes contents is EMPTY) and returns the remaining item, putting it in the player's hand
+ private ItemStack insertContents(Player player, InteractionHand hand) {
+ var consume = !player.getAbilities().instabuild;
+ var playerItem = player.getItemInHand(hand);
- return item.insertItem(0, stack, false);
+ if (consume) {
+ if (playerItem.getCount() == 1) {
+ this.contents = playerItem;
+ player.setItemInHand(hand, ItemStack.EMPTY);
+ playerItem = ItemStack.EMPTY;
+ } else {
+ this.contents = singleCopy(playerItem);
+ playerItem.shrink(1);
+ }
+ } else {
+ this.contents = singleCopy(playerItem);
+ }
+
+ this.progress = MAX_SIEVE_CAPACITY;
+
+ return playerItem;
}
- private void giveItems() {
- var pos = getBlockPos();
- var rand = level.random;
+ private static ItemStack singleCopy(ItemStack stack) {
+ var copy = stack.copy();
+ copy.setCount(1);
+ return copy;
+ }
- for (SieveRecipe recipe : currentRecipe) {
- for (Reward reward : recipe.getRewards()) {
- if (rand.nextFloat() < reward.getChance()) {
- var itemEntity = new ItemEntity(level, pos.getX() + 0.5, pos.getY() + 1.5, pos.getZ() + 0.5, reward.getItem().copy());
- itemEntity.setDeltaMovement(rand.nextGaussian() * 0.05, 0.2, rand.nextGaussian() * 0.05);
- level.addFreshEntity(itemEntity);
- }
+ private void performSift(Player player) {
+ progress -= efficiency * SIEVE_INTERVAL;
+
+ if (progress <= 0) {
+ progress = 0;
+
+ if (!level.isClientSide) {
+ giveItems(player);
+ }
+ }
+ }
+
+ private InteractionResult removeMesh() {
+ if (!level.isClientSide) {
+ // Pop out item
+ var itemEntity = new ItemEntity(level, worldPosition.getX() + 0.5, worldPosition.getY() + 1.5, worldPosition.getZ() + 0.5, mesh);
+ var rand = level.random;
+ itemEntity.setDeltaMovement(rand.nextGaussian() * 0.05, 0.2, rand.nextGaussian() * 0.05);
+ level.addFreshEntity(itemEntity);
+
+ // Empty contents
+ setMesh(ItemStack.EMPTY);
+ markUpdated();
+ }
+
+ return InteractionResult.sidedSuccess(level.isClientSide);
+ }
+
+ private void setMesh(ItemStack mesh) {
+ this.mesh = mesh;
+ this.efficiency = 1f + mesh.getEnchantmentLevel(Enchantments.BLOCK_EFFICIENCY) * 0.08f;
+ // Fortune III increases drops by 120% (you should enchant your meshes!)
+ this.fortune = 1f + mesh.getEnchantmentLevel(Enchantments.BLOCK_FORTUNE) * 0.4f;
+ }
+
+ private void giveItems(Player player) {
+ var pos = this.worldPosition;
+ var context = new LootContext.Builder(new LootParams((ServerLevel) this.level, Map.of(), Map.of(), player.getLuck())).create(null);
+ var rand = this.level.random;
+
+ for (SieveRecipe recipe : RecipeUtil.getSieveRecipes(level.getRecipeManager(), this.mesh.getItem(), this.contents)) {
+ var amount = recipe.resultAmount.getInt(context);
+
+ if (amount >= 1) {
+ var itemEntity = new ItemEntity(this.level, pos.getX() + 0.5, pos.getY() + 1.5, pos.getZ() + 0.5, new ItemStack(recipe.result, amount));
+ itemEntity.setDeltaMovement(rand.nextGaussian() * 0.05, 0.2, rand.nextGaussian() * 0.05);
+ this.level.addFreshEntity(itemEntity);
}
}
- item.setStackInSlot(0, ItemStack.EMPTY);
+ this.contents = ItemStack.EMPTY;
markUpdated();
}
private boolean isMesh(ItemStack stack) {
- var item = stack.getItem();
- return item == EItems.STRING_MESH.get() || item == EItems.FLINT_MESH.get() || item == EItems.IRON_MESH.get() || item == EItems.DIAMOND_MESH.get() || item == EItems.NETHERITE_MESH.get();
+ return stack.is(EItemTags.SIEVE_MESHES);
}
+ public ItemStack getMesh() {
+ return this.mesh;
+ }
+
+ // Used for rendering
public short getProgress() {
- return progress;
+ return this.progress;
}
- public ItemStack getItem() {
- return item.getStackInSlot(0);
- }
-
- public List extends SieveRecipe> getResults(ItemStack stack) {
- return RecipeUtil.getSieveResults(level.getServer(), getRecipeType(), mesh, stack);
- }
-
- public RecipeType extends SieveRecipe> getRecipeType() {
- return ERecipeTypes.SIEVE.get();
- }
-
- private class ItemHandler extends ItemStackHandler {
- @Override
- public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
- return !getResults(stack).isEmpty();
- }
-
- @Override
- protected int getStackLimit(int slot, @Nonnull ItemStack stack) {
- return 1;
- }
-
- @Nonnull
- @Override
- public ItemStack extractItem(int slot, int amount, boolean simulate) {
- return ItemStack.EMPTY;
- }
+ // Used for rendering
+ public ItemStack getContents() {
+ return this.contents;
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/WaterCrucibleBlockEntity.java b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/WaterCrucibleBlockEntity.java
index f37b3244..b7de627a 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/blockentity/WaterCrucibleBlockEntity.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/blockentity/WaterCrucibleBlockEntity.java
@@ -1,43 +1,26 @@
package thedarkcolour.exnihiloreborn.blockentity;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
import net.minecraft.core.BlockPos;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
+import thedarkcolour.exnihiloreborn.recipe.RecipeUtil;
import thedarkcolour.exnihiloreborn.recipe.crucible.CrucibleRecipe;
import thedarkcolour.exnihiloreborn.registry.EBlockEntities;
-import thedarkcolour.exnihiloreborn.registry.ERecipeTypes;
public class WaterCrucibleBlockEntity extends AbstractCrucibleBlockEntity {
- public static final Cache RECIPES_CACHE = CacheBuilder.newBuilder().maximumSize(12).build();
-
public WaterCrucibleBlockEntity(BlockPos pos, BlockState state) {
super(EBlockEntities.WATER_CRUCIBLE.get(), pos, state);
}
@Override
- public CrucibleRecipe getRecipe(ItemStack item) {
- return super.getRecipe(item);
- }
-
- @Override
- protected RecipeType getRecipeType() {
- return ERecipeTypes.WATER_CRUCIBLE.get();
+ protected CrucibleRecipe getRecipe(ItemStack item) {
+ return RecipeUtil.getWaterCrucibleRecipe(item);
}
@Override
protected Block getDefaultMeltBlock() {
return Blocks.OAK_LEAVES;
}
-
- @Override
- protected Cache getRecipeCache() {
- return RECIPES_CACHE;
- }
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/client/ClientHandler.java b/src/main/java/thedarkcolour/exnihiloreborn/client/ClientHandler.java
index 325de224..30086f84 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/client/ClientHandler.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/client/ClientHandler.java
@@ -5,6 +5,7 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.Mth;
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.client.event.EntityRenderersEvent;
+import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
@@ -17,6 +18,7 @@ import thedarkcolour.exnihiloreborn.registry.EBlockEntities;
import thedarkcolour.exnihiloreborn.registry.EFluids;
import java.awt.Color;
+import java.util.concurrent.CompletableFuture;
public class ClientHandler {
public static void register() {
@@ -25,10 +27,17 @@ public class ClientHandler {
modBus.addListener(ClientHandler::clientSetup);
modBus.addListener(ClientHandler::registerRenderers);
+ modBus.addListener(ClientHandler::addClientReloadListeners);
fmlBus.addListener(ClientHandler::onPlayerRespawn);
fmlBus.addListener(ClientHandler::onPlayerLogout);
}
+ private static void addClientReloadListeners(RegisterClientReloadListenersEvent event) {
+ event.registerReloadListener((prepBarrier, resourceManager, prepProfiler, reloadProfiler, backgroundExecutor, gameExecutor) -> {
+ return CompletableFuture.allOf().thenCompose(prepBarrier::wait).thenRunAsync(RenderUtil::reload, gameExecutor);
+ });
+ }
+
private static void clientSetup(FMLClientSetupEvent event) {
event.enqueueWork(ClientHandler::setRenderLayers);
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/client/CompostColors.java b/src/main/java/thedarkcolour/exnihiloreborn/client/CompostColors.java
index 0b96a9ff..c6411455 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/client/CompostColors.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/client/CompostColors.java
@@ -8,6 +8,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.registries.ForgeRegistries;
@@ -45,7 +46,7 @@ public class CompostColors {
}
public static boolean isLoaded() {
- return COLORS.isEmpty();
+ return !COLORS.isEmpty();
}
private static void loadVanilla() {
@@ -130,7 +131,15 @@ public class CompostColors {
}
if (pixels > 0 && (r | g | b) != 0) {
- Color c = new Color(r / pixels, g / pixels, b / pixels).brighter();
+ var tint = Minecraft.getInstance().getItemColors().getColor(new ItemStack(item), 0);
+ Color c = new Color(
+ r / pixels * (tint >> 16) & 0xff,
+ g / pixels * (tint >> 8) & 0xff,
+ b / pixels * tint & 0xff
+ );
+ // do not brighten a tinted texture
+ if (tint == 0) c = c.brighter();
+
Vector3i color = new Vector3i(c.getRed(), c.getGreen(), c.getBlue());
ExNihiloReborn.LOGGER.debug("Item '{}' has color ({}, {}, {})\n", entry.getKey().location(), color.x, color.y, color.z);
CompostColors.COLORS.put(item, color);
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/client/RenderUtil.java b/src/main/java/thedarkcolour/exnihiloreborn/client/RenderUtil.java
new file mode 100644
index 00000000..705b174b
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/client/RenderUtil.java
@@ -0,0 +1,97 @@
+package thedarkcolour.exnihiloreborn.client;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.mojang.blaze3d.vertex.PoseStack;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.RenderType;
+import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
+import net.minecraft.client.renderer.texture.TextureAtlas;
+import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.util.Mth;
+import net.minecraft.world.inventory.InventoryMenu;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.levelgen.LegacyRandomSource;
+import net.minecraftforge.client.model.data.ModelData;
+import net.minecraftforge.registries.ForgeRegistries;
+import org.joml.Vector3f;
+import thedarkcolour.exnihiloreborn.client.ter.SieveRenderer;
+
+public class RenderUtil {
+ public static final LoadingCache TOP_RENDER_TYPES;
+ public static final LoadingCache TOP_TEXTURES;
+ public static TextureAtlas blockAtlas;
+
+ static {
+ TOP_RENDER_TYPES = CacheBuilder.newBuilder().maximumSize(10).build(new CacheLoader<>() {
+ @Override
+ public RenderType load(Block key) {
+ var rand = new LegacyRandomSource(key.hashCode());
+ var blockTypes = Minecraft.getInstance().getBlockRenderer().getBlockModel(key.defaultBlockState()).getRenderTypes(key.defaultBlockState(), rand, ModelData.EMPTY);
+ return RenderType.chunkBufferLayers().stream().filter(blockTypes::contains).findFirst().get();
+ }
+ });
+ TOP_TEXTURES = CacheBuilder.newBuilder().weakValues().build(new CacheLoader<>() {
+ @Override
+ public TextureAtlasSprite load(Block key) {
+ ResourceLocation registryName = ForgeRegistries.BLOCKS.getKey(key);
+ var textureLoc = new ResourceLocation(registryName.getNamespace(), "block/" + registryName.getPath());
+ var sprite = blockAtlas.getSprite(textureLoc);
+ // for stuff like azalea bush, retry to get the top texture
+ if (sprite.contents().name() == MissingTextureAtlasSprite.getLocation()) {
+ textureLoc = new ResourceLocation(registryName.getNamespace(), "block/" + registryName.getPath() + "_top");
+ sprite = blockAtlas.getSprite(textureLoc);
+ }
+ return sprite;
+ }
+ });
+ }
+
+ public static void reload() {
+ invalidateCaches();
+ blockAtlas = Minecraft.getInstance().getModelManager().getAtlas(InventoryMenu.BLOCK_ATLAS);
+ }
+
+ public static void invalidateCaches() {
+ SieveRenderer.MESH_TEXTURES.invalidateAll();
+ blockAtlas = null;
+ }
+
+ // uses a RGB color instead of three color components
+ public static void renderFlatSpriteLerp(VertexConsumer builder, PoseStack stack, float percentage, int color, TextureAtlasSprite sprite, int light, float edge, float yMin, float yMax) {
+ renderFlatSpriteLerp(builder, stack, percentage, (color >> 16) & 0xff, (color >> 8) & 0xff, (color >> 0) & 0xff, sprite, light, edge, yMin, yMax);
+ }
+
+ // Renders a sprite inside the barrel with the height determined by how full the barrel is.
+ public static void renderFlatSpriteLerp(VertexConsumer builder, PoseStack stack, float percentage, int r, int g, int b, TextureAtlasSprite sprite, int light, float edge, float yMin, float yMax) {
+ float y = Mth.lerp(percentage, yMin, yMax) / 16f;
+
+ renderFlatSprite(builder, stack, y, r, g, b, sprite, light, edge);
+ }
+
+ // Renders a sprite (y should be between 0 and 1)
+ @SuppressWarnings("DuplicatedCode")
+ public static void renderFlatSprite(VertexConsumer builder, PoseStack stack, float y, int r, int g, int b, TextureAtlasSprite sprite, int light, float edge) {
+ var pose = stack.last().pose();
+ var normal = stack.last().normal().transform(new Vector3f(0, 1, 0));
+
+ // Position coordinates
+ float edgeMin = edge / 16.0f;
+ float edgeMax = (16.0f - edge) / 16.0f;
+
+ // Texture coordinates
+ float uMin = sprite.getU0();
+ float uMax = sprite.getU1();
+ float vMin = sprite.getV0();
+ float vMax = sprite.getV1();
+
+ // overlayCoords(0, 10) is NO_OVERLAY (0xA0000)
+ builder.vertex(pose, edgeMin, y, edgeMin).color(r, g, b, 255).overlayCoords(0, 10).uv(uMin, vMin).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
+ builder.vertex(pose, edgeMin, y, edgeMax).color(r, g, b, 255).overlayCoords(0, 10).uv(uMin, vMax).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
+ builder.vertex(pose, edgeMax, y, edgeMax).color(r, g, b, 255).overlayCoords(0, 10).uv(uMax, vMax).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
+ builder.vertex(pose, edgeMax, y, edgeMin).color(r, g, b, 255).overlayCoords(0, 10).uv(uMax, vMin).uv2(light).normal(normal.x, normal.y, normal.z).endVertex();
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/client/ter/BarrelRenderer.java b/src/main/java/thedarkcolour/exnihiloreborn/client/ter/BarrelRenderer.java
index 806c7cb8..97f9621a 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/client/ter/BarrelRenderer.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/client/ter/BarrelRenderer.java
@@ -1,7 +1,6 @@
package thedarkcolour.exnihiloreborn.client.ter;
import com.mojang.blaze3d.vertex.PoseStack;
-import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.MultiBufferSource;
@@ -9,7 +8,6 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
-import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.inventory.InventoryMenu;
@@ -21,6 +19,7 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities;
import thedarkcolour.exnihiloreborn.ExNihiloReborn;
import thedarkcolour.exnihiloreborn.blockentity.BarrelBlockEntity;
import thedarkcolour.exnihiloreborn.client.ClientHandler;
+import thedarkcolour.exnihiloreborn.client.RenderUtil;
public class BarrelRenderer implements BlockEntityRenderer {
public static final ResourceLocation COMPOST_DIRT_TEXTURE = new ResourceLocation(ExNihiloReborn.ID, "block/compost_dirt");
@@ -79,7 +78,7 @@ public class BarrelRenderer implements BlockEntityRenderer {
// Setup rendering
var builder = buffers.getBuffer(ItemBlockRenderTypes.getRenderLayer(fluid.defaultFluidState()));
- renderContents(builder, stack, fluidStack.getAmount() / 1000.0f, r, g, b, sprite, light, 2.0f, 1.0f, 14.0f);
+ RenderUtil.renderFlatSpriteLerp(builder, stack, fluidStack.getAmount() / 1000.0f, r, g, b, sprite, light, 2.0f, 1.0f, 14.0f);
}
});
@@ -107,44 +106,7 @@ public class BarrelRenderer implements BlockEntityRenderer {
g = (int) Mth.lerp(compostProgress, g, 169); // default green is
b = (int) Mth.lerp(compostProgress, b, 109); // default green is
- renderContents(builder, stack, barrel.compost / 1000.0f, r, g, b, sprite, light, 2.0f, 1.0f, 14.0f);
+ RenderUtil.renderFlatSpriteLerp(builder, stack, barrel.compost / 1000.0f, r, g, b, sprite, light, 2.0f, 1.0f, 14.0f);
}
}
-
- public static void renderContents(VertexConsumer builder, PoseStack stack, float percentage, int color, TextureAtlasSprite sprite, int light, float edge, float yMin, float yMax) {
- renderContents(builder, stack, percentage, (color >> 16) & 0xff, (color >> 8) & 0xff, (color >> 0) & 0xff, sprite, light, edge, yMin, yMax);
- }
-
- // Renders a sprite inside the barrel with the height determined by how full the barrel is.
- public static void renderContents(VertexConsumer builder, PoseStack stack, float percentage, int r, int g, int b, TextureAtlasSprite sprite, int light, float edge, float yMin, float yMax) {
- // Height
- float height = ((yMax - yMin) / 16.0f) * percentage;
-
- // Offset by specified number of pixels
- stack.pushPose();
- stack.translate(0.0, yMin / 16.0, 0.0);
-
- putQuad(builder, stack, height, r, g, b, sprite, light, edge);
-
- stack.popPose();
- }
-
- // Renders a sprite
- private static void putQuad(VertexConsumer builder, PoseStack stack, float quadHeight, int r, int g, int b, TextureAtlasSprite sprite, int light, float edge) {
- var pose = stack.last().pose();
-
- // Texture coordinates
- float uMin = sprite.getU0();
- float uMax = sprite.getU1();
- float vMin = sprite.getV0();
- float vMax = sprite.getV1();
-
- float edgeMin = edge / 16.0f;
- float edgeMax = (16.0f - edge) / 16.0f;
-
- builder.vertex(pose, edgeMin, quadHeight, edgeMin).color(r, g, b, 255).uv(uMin, vMin).uv2(light).normal(0.0f, 1.0f, 0.0f).endVertex();
- builder.vertex(pose, edgeMin, quadHeight, edgeMax).color(r, g, b, 255).uv(uMin, vMax).uv2(light).normal(0.0f, 1.0f, 0.0f).endVertex();
- builder.vertex(pose, edgeMax, quadHeight, edgeMax).color(r, g, b, 255).uv(uMax, vMax).uv2(light).normal(0.0f, 1.0f, 0.0f).endVertex();
- builder.vertex(pose, edgeMax, quadHeight, edgeMin).color(r, g, b, 255).uv(uMax, vMin).uv2(light).normal(0.0f, 1.0f, 0.0f).endVertex();
- }
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/client/ter/CrucibleRenderer.java b/src/main/java/thedarkcolour/exnihiloreborn/client/ter/CrucibleRenderer.java
index 771eb47c..541896e4 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/client/ter/CrucibleRenderer.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/client/ter/CrucibleRenderer.java
@@ -1,54 +1,18 @@
package thedarkcolour.exnihiloreborn.client.ter;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.MultiBufferSource;
-import net.minecraft.client.renderer.RenderType;
-import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
-import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
-import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.world.inventory.InventoryMenu;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.levelgen.LegacyRandomSource;
-import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
-import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
-import net.minecraftforge.registries.ForgeRegistries;
import thedarkcolour.exnihiloreborn.blockentity.AbstractCrucibleBlockEntity;
+import thedarkcolour.exnihiloreborn.client.RenderUtil;
public class CrucibleRenderer implements BlockEntityRenderer {
- public static final int TEXTURE_CACHE = 10;
- public static final LoadingCache TOP_TEXTURES = CacheBuilder.newBuilder().weakValues().maximumSize(30).build(new CacheLoader<>() {
- @Override
- public TextureAtlasSprite load(Block key) {
- ResourceLocation registryName = ForgeRegistries.BLOCKS.getKey(key);
- var textureLoc = new ResourceLocation(registryName.getNamespace(), "block/" + registryName.getPath());
- var sprite = Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(textureLoc);
- // for stuff like azalea bush
- if (sprite.contents().name() == MissingTextureAtlasSprite.getLocation()) {
- textureLoc = new ResourceLocation(registryName.getNamespace(), "block/" + registryName.getPath() + "_top");
- }
- return Minecraft.getInstance().getTextureAtlas(InventoryMenu.BLOCK_ATLAS).apply(textureLoc);
- }
- });
- public static final LoadingCache TOP_RENDER_TYPES = CacheBuilder.newBuilder().maximumSize(10).build(new CacheLoader<>() {
- @Override
- public RenderType load(Block key) {
- var rand = new LegacyRandomSource(key.hashCode());
- var blockTypes = Minecraft.getInstance().getBlockRenderer().getBlockModel(key.defaultBlockState()).getRenderTypes(key.defaultBlockState(), rand, ModelData.EMPTY);
- return RenderType.chunkBufferLayers().stream().filter(blockTypes::contains).findFirst().get();
- }
- });
-
@Override
public void render(AbstractCrucibleBlockEntity crucible, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) {
crucible.getCapability(ForgeCapabilities.FLUID_HANDLER).ifPresent(tank -> {
@@ -68,27 +32,28 @@ public class CrucibleRenderer implements BlockEntityRenderer> 16) & 0xff, 255.0f);
@@ -43,7 +44,7 @@ public class InfestedLeavesRenderer implements BlockEntityRenderer {
+ public static final LoadingCache- MESH_TEXTURES = CacheBuilder.newBuilder().build(new CacheLoader<>() {
+ @Override
+ public TextureAtlasSprite load(Item key) {
+ ResourceLocation registryName = ForgeRegistries.ITEMS.getKey(key);
+ var textureLoc = registryName.withPrefix("item/mesh/");
+ return RenderUtil.blockAtlas.getSprite(textureLoc);
+ }
+ });
+
public SieveRenderer(BlockEntityRendererProvider.Context ctx) {}
@Override
public void render(SieveBlockEntity sieve, float partialTicks, PoseStack stack, MultiBufferSource buffers, int light, int overlay) {
- var contents = sieve.getItem();
+ var contents = sieve.getContents();
if (!contents.isEmpty() && contents.getItem() instanceof BlockItem blockItem) {
var block = blockItem.getBlock();
var percentage = (float) sieve.getProgress() / 100.0f;
- var builder = buffers.getBuffer(CrucibleRenderer.TOP_RENDER_TYPES.getUnchecked(block));
- var sprite = CrucibleRenderer.TOP_TEXTURES.getUnchecked(block);
+ var builder = buffers.getBuffer(RenderUtil.TOP_RENDER_TYPES.getUnchecked(block));
+ var sprite = RenderUtil.TOP_TEXTURES.getUnchecked(block);
- BarrelRenderer.renderContents(builder, stack, percentage, 0xffffff, sprite, light, 1.0f, 11.0f, 15.0f);
+ RenderUtil.renderFlatSpriteLerp(builder, stack, percentage, 0xff, 0xff, 0xff, sprite, light, 1.0f, 13f, 15f);
+ }
+
+ var mesh = sieve.getMesh();
+
+ if (!mesh.isEmpty()) {
+ var builder = buffers.getBuffer(RenderType.cutoutMipped());
+ var sprite = MESH_TEXTURES.getUnchecked(mesh.getItem());
+ RenderUtil.renderFlatSprite(builder, stack, 0.75f, 0xff, 0xff, 0xff, sprite, light, 1f);
+
+ if (mesh.hasFoil()) {
+ RenderUtil.renderFlatSprite(buffers.getBuffer(RenderType.glint()), stack, 0.75f, 0xff, 0xff, 0xff, sprite, light, 1f);
+ }
}
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/BarrelCompostCategory.java b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/BarrelCompostCategory.java
index 62a8c479..8a0cb0f4 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/BarrelCompostCategory.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/BarrelCompostCategory.java
@@ -13,30 +13,24 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.level.block.Blocks;
-import thedarkcolour.exnihiloreborn.block.EBlock;
import thedarkcolour.exnihiloreborn.data.TranslationKeys;
import thedarkcolour.exnihiloreborn.recipe.barrel.BarrelCompostRecipe;
import thedarkcolour.exnihiloreborn.registry.EBlocks;
-import java.util.Arrays;
-
-public class BarrelCompostCategory implements IRecipeCategory {
+class BarrelCompostCategory implements IRecipeCategory {
public static final int WIDTH = 120;
public static final int HEIGHT = 18;
private final IDrawable background;
private final IDrawable slot;
private final IDrawable icon;
- private final Component localizedName;
+ private final Component title;
- public BarrelCompostCategory(IJeiHelpers helpers) {
- IGuiHelper guiHelpers = helpers.getGuiHelper();
-
- this.background = guiHelpers.createBlankDrawable(WIDTH, HEIGHT);
- this.slot = guiHelpers.getSlotDrawable();
- this.icon = guiHelpers.createDrawableItemStack(new ItemStack(EBlocks.OAK_BARREL.get()));
- this.localizedName = Component.translatable(TranslationKeys.BARREL_COMPOST_CATEGORY_TITLE);
+ public BarrelCompostCategory(IGuiHelper helper) {
+ this.background = helper.createBlankDrawable(WIDTH, HEIGHT);
+ this.slot = helper.getSlotDrawable();
+ this.icon = helper.createDrawableItemStack(new ItemStack(EBlocks.OAK_BARREL.get()));
+ this.title = Component.translatable(TranslationKeys.BARREL_COMPOST_CATEGORY_TITLE);
}
@Override
@@ -46,17 +40,17 @@ public class BarrelCompostCategory implements IRecipeCategory {
+ public CrucibleCategory(IGuiHelper helper, IDrawable arrow, Supplier extends Item> iconItem, String titleKey) {
+ super(helper, arrow, helper.createDrawableItemStack(new ItemStack(iconItem.get())), Component.translatable(titleKey));
+ }
+
+ @Override
+ protected void addInput(IRecipeSlotBuilder slot, CrucibleRecipe recipe) {
+ slot.addIngredients(recipe.getIngredient());
+ }
+
+ @Override
+ protected void addOutput(IRecipeSlotBuilder slot, CrucibleRecipe recipe) {
+ slot.addFluidStack(recipe.getResult().getFluid(), recipe.getResult().getAmount())
+ .setFluidRenderer(Math.max(1000, recipe.getResult().getAmount()), false, 16, 16);
+ }
+
+ static class LavaCrucible extends CrucibleCategory {
+ public LavaCrucible(IGuiHelper helper, IDrawable arrow) {
+ super(helper, arrow, EItems.PORCELAIN_CRUCIBLE, TranslationKeys.LAVA_CRUCIBLE_CATEGORY_TITLE);
+ }
+
+ @Override
+ public RecipeType getRecipeType() {
+ return ExNihiloRebornJeiPlugin.LAVA_CRUCIBLE;
+ }
+ }
+
+ static class WaterCrucible extends CrucibleCategory {
+ public WaterCrucible(IGuiHelper helper, IDrawable arrow) {
+ super(helper, arrow, EItems.OAK_CRUCIBLE, TranslationKeys.WATER_CRUCIBLE_CATEGORY_TITLE);
+ }
+
+ @Override
+ public RecipeType getRecipeType() {
+ return ExNihiloRebornJeiPlugin.WATER_CRUCIBLE;
+ }
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/ExNihiloRebornJeiPlugin.java b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/ExNihiloRebornJeiPlugin.java
index 6ad106ea..e83a727e 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/ExNihiloRebornJeiPlugin.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/ExNihiloRebornJeiPlugin.java
@@ -3,6 +3,8 @@ package thedarkcolour.exnihiloreborn.compat.jei;
import mezz.jei.api.IModPlugin;
import mezz.jei.api.JeiPlugin;
import mezz.jei.api.constants.VanillaTypes;
+import mezz.jei.api.gui.drawable.IDrawable;
+import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.registration.IRecipeCatalystRegistration;
import mezz.jei.api.registration.IRecipeCategoryRegistration;
@@ -10,19 +12,32 @@ import mezz.jei.api.registration.IRecipeRegistration;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.Container;
import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.crafting.Ingredient;
+import net.minecraft.world.item.crafting.Recipe;
import thedarkcolour.exnihiloreborn.ExNihiloReborn;
import thedarkcolour.exnihiloreborn.data.TranslationKeys;
import thedarkcolour.exnihiloreborn.recipe.barrel.BarrelCompostRecipe;
+import thedarkcolour.exnihiloreborn.recipe.crucible.CrucibleRecipe;
+import thedarkcolour.exnihiloreborn.recipe.hammer.HammerRecipe;
+import thedarkcolour.exnihiloreborn.registry.EBlocks;
import thedarkcolour.exnihiloreborn.registry.EItems;
import thedarkcolour.exnihiloreborn.registry.ERecipeTypes;
+import java.util.List;
import java.util.Objects;
+import java.util.function.Supplier;
@JeiPlugin
public class ExNihiloRebornJeiPlugin implements IModPlugin {
+ public static final ResourceLocation ENH_JEI_TEXTURE = new ResourceLocation(ExNihiloReborn.ID, "textures/gui/jei/enr_jei.png");
+
public static final RecipeType BARREL_COMPOST = RecipeType.create(ExNihiloReborn.ID, "barrel_compost", BarrelCompostRecipe.class);
+ public static final RecipeType> BARREL_MIXING = RecipeType.create(ExNihiloReborn.ID, "barrel_compost", Object.class);
+ public static final RecipeType LAVA_CRUCIBLE = RecipeType.create(ExNihiloReborn.ID, "lava_crucible", CrucibleRecipe.class);
+ public static final RecipeType WATER_CRUCIBLE = RecipeType.create(ExNihiloReborn.ID, "water_crucible", CrucibleRecipe.class);
+ public static final RecipeType SIEVE = RecipeType.create(ExNihiloReborn.ID, "sieve", JeiSieveRecipeGroup.class);
+ public static final RecipeType HAMMER = RecipeType.create(ExNihiloReborn.ID, "hammer", HammerRecipe.class);
@Override
public ResourceLocation getPluginUid() {
@@ -31,28 +46,84 @@ public class ExNihiloRebornJeiPlugin implements IModPlugin {
@Override
public void registerCategories(IRecipeCategoryRegistration registration) {
- registration.addRecipeCategories(new BarrelCompostCategory(registration.getJeiHelpers()));
+ IGuiHelper helper = registration.getJeiHelpers().getGuiHelper();
+ IDrawable arrow = helper.createDrawable(ExNihiloRebornJeiPlugin.ENH_JEI_TEXTURE, 0, 18, 22, 15);
+
+ registration.addRecipeCategories(new BarrelCompostCategory(helper));
+ registration.addRecipeCategories(new CrucibleCategory.LavaCrucible(helper, arrow));
+ registration.addRecipeCategories(new CrucibleCategory.WaterCrucible(helper, arrow));
+ registration.addRecipeCategories(new SieveCategory(helper));
+ registration.addRecipeCategories(new HammerCategory(helper, arrow));
}
@Override
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
- registration.addRecipeCatalyst(new ItemStack(EItems.OAK_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.SPRUCE_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.BIRCH_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.JUNGLE_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.ACACIA_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.DARK_OAK_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.MANGROVE_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.CHERRY_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.BAMBOO_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.CRIMSON_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.WARPED_BARREL.get()), BARREL_COMPOST);
- registration.addRecipeCatalyst(new ItemStack(EItems.STONE_BARREL.get()), BARREL_COMPOST);
+ var barrels = new ItemStack[]{
+ new ItemStack(EItems.OAK_BARREL.get()),
+ new ItemStack(EItems.SPRUCE_BARREL.get()),
+ new ItemStack(EItems.BIRCH_BARREL.get()),
+ new ItemStack(EItems.JUNGLE_BARREL.get()),
+ new ItemStack(EItems.ACACIA_BARREL.get()),
+ new ItemStack(EItems.DARK_OAK_BARREL.get()),
+ new ItemStack(EItems.MANGROVE_BARREL.get()),
+ new ItemStack(EItems.CHERRY_BARREL.get()),
+ new ItemStack(EItems.BAMBOO_BARREL.get()),
+ new ItemStack(EItems.CRIMSON_BARREL.get()),
+ new ItemStack(EItems.WARPED_BARREL.get()),
+ new ItemStack(EItems.STONE_BARREL.get()),
+ };
+ for (var barrel : barrels) {
+ registration.addRecipeCatalyst(barrel, BARREL_COMPOST);
+ registration.addRecipeCatalyst(barrel, BARREL_MIXING);
+ }
+
+ registration.addRecipeCatalyst(new ItemStack(EItems.PORCELAIN_CRUCIBLE.get()), LAVA_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.WARPED_CRUCIBLE.get()), LAVA_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.CRIMSON_CRUCIBLE.get()), LAVA_CRUCIBLE);
+
+ registration.addRecipeCatalyst(new ItemStack(EItems.OAK_CRUCIBLE.get()), WATER_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.SPRUCE_CRUCIBLE.get()), WATER_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.BIRCH_CRUCIBLE.get()), WATER_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.JUNGLE_CRUCIBLE.get()), WATER_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.ACACIA_CRUCIBLE.get()), WATER_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.DARK_OAK_CRUCIBLE.get()), WATER_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.MANGROVE_CRUCIBLE.get()), WATER_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.CHERRY_CRUCIBLE.get()), WATER_CRUCIBLE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.BAMBOO_CRUCIBLE.get()), WATER_CRUCIBLE);
+
+ registration.addRecipeCatalyst(new ItemStack(EItems.OAK_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.SPRUCE_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.BIRCH_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.JUNGLE_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.ACACIA_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.DARK_OAK_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.MANGROVE_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.CHERRY_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.BAMBOO_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.CRIMSON_SIEVE.get()), SIEVE);
+ registration.addRecipeCatalyst(new ItemStack(EItems.WARPED_SIEVE.get()), SIEVE);
+
+ registration.addRecipeCatalyst(new ItemStack(EItems.WOODEN_HAMMER.get()), HAMMER);
+ registration.addRecipeCatalyst(new ItemStack(EItems.STONE_HAMMER.get()), HAMMER);
+ registration.addRecipeCatalyst(new ItemStack(EItems.GOLDEN_HAMMER.get()), HAMMER);
+ registration.addRecipeCatalyst(new ItemStack(EItems.IRON_HAMMER.get()), HAMMER);
+ registration.addRecipeCatalyst(new ItemStack(EItems.DIAMOND_HAMMER.get()), HAMMER);
+ registration.addRecipeCatalyst(new ItemStack(EItems.NETHERITE_HAMMER.get()), HAMMER);
}
@Override
public void registerRecipes(IRecipeRegistration registration) {
registration.addIngredientInfo(new ItemStack(EItems.SILK_WORM.get()), VanillaTypes.ITEM_STACK, Component.translatable(TranslationKeys.SILK_WORM_JEI_INFO));
- registration.addRecipes(BARREL_COMPOST, Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().getAllRecipesFor(ERecipeTypes.BARREL_COMPOST.get()));
+ registration.addIngredientInfo(List.of(new ItemStack(EBlocks.OAK_SIEVE.get()), new ItemStack(EBlocks.SPRUCE_SIEVE.get()), new ItemStack(EBlocks.BIRCH_SIEVE.get()), new ItemStack(EBlocks.JUNGLE_SIEVE.get()), new ItemStack(EBlocks.ACACIA_SIEVE.get()), new ItemStack(EBlocks.DARK_OAK_SIEVE.get()), new ItemStack(EBlocks.MANGROVE_SIEVE.get()), new ItemStack(EBlocks.CHERRY_SIEVE.get()), new ItemStack(EBlocks.BAMBOO_SIEVE.get()), new ItemStack(EBlocks.CRIMSON_SIEVE.get()), new ItemStack(EBlocks.WARPED_SIEVE.get())), VanillaTypes.ITEM_STACK, Component.translatable(TranslationKeys.SIEVE_JEI_INFO));
+ addRecipes(registration, BARREL_COMPOST, ERecipeTypes.BARREL_COMPOST);
+ addRecipes(registration, LAVA_CRUCIBLE, ERecipeTypes.LAVA_CRUCIBLE);
+ addRecipes(registration, WATER_CRUCIBLE, ERecipeTypes.WATER_CRUCIBLE);
+ addRecipes(registration, HAMMER, ERecipeTypes.HAMMER);
+
+ JeiSieveRecipeGroup.addRecipes(registration, SIEVE);
+ }
+
+ private static > void addRecipes(IRecipeRegistration registration, RecipeType category, Supplier> type) {
+ registration.addRecipes(category, Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().getAllRecipesFor(type.get()));
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/HammerCategory.java b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/HammerCategory.java
new file mode 100644
index 00000000..436bca43
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/HammerCategory.java
@@ -0,0 +1,33 @@
+package thedarkcolour.exnihiloreborn.compat.jei;
+
+import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
+import mezz.jei.api.gui.drawable.IDrawable;
+import mezz.jei.api.helpers.IGuiHelper;
+import mezz.jei.api.recipe.RecipeType;
+import net.minecraft.network.chat.Component;
+import net.minecraft.world.item.ItemStack;
+import thedarkcolour.exnihiloreborn.data.TranslationKeys;
+import thedarkcolour.exnihiloreborn.recipe.hammer.HammerRecipe;
+import thedarkcolour.exnihiloreborn.registry.EItems;
+
+class HammerCategory extends OneToOneCategory {
+ public HammerCategory(IGuiHelper helper, IDrawable arrow) {
+ super(helper, arrow, helper.createDrawableItemStack(new ItemStack(EItems.DIAMOND_HAMMER.get())), Component.translatable(TranslationKeys.HAMMER_CATEGORY_TITLE));
+ }
+
+ @Override
+ public RecipeType getRecipeType() {
+ return ExNihiloRebornJeiPlugin.HAMMER;
+ }
+
+ @Override
+ protected void addInput(IRecipeSlotBuilder slot, HammerRecipe recipe) {
+ slot.addIngredients(recipe.getIngredient());
+ }
+
+ @Override
+ protected void addOutput(IRecipeSlotBuilder slot, HammerRecipe recipe) {
+ slot.addItemStack(new ItemStack(recipe.result));
+ SieveCategory.addTooltips(slot, recipe.resultAmount);
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/JeiSieveRecipeGroup.java b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/JeiSieveRecipeGroup.java
new file mode 100644
index 00000000..ff2d9396
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/JeiSieveRecipeGroup.java
@@ -0,0 +1,104 @@
+package thedarkcolour.exnihiloreborn.compat.jei;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Multimap;
+import mezz.jei.api.recipe.RecipeType;
+import mezz.jei.api.registration.IRecipeRegistration;
+import net.minecraft.client.Minecraft;
+import net.minecraft.util.Mth;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.crafting.Ingredient;
+import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
+import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
+import thedarkcolour.exnihiloreborn.recipe.RecipeUtil;
+import thedarkcolour.exnihiloreborn.recipe.sieve.SieveRecipe;
+import thedarkcolour.exnihiloreborn.registry.ERecipeTypes;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Objects;
+
+record JeiSieveRecipeGroup(Ingredient ingredient, ItemStack mesh, List results) {
+ public static int maxSieveRows;
+
+ public static void addRecipes(IRecipeRegistration registration, RecipeType recipeType) {
+ maxSieveRows = 1;
+
+ // copy the list so we can do removals
+ List recipes = new ArrayList<>(Objects.requireNonNull(Minecraft.getInstance().level).getRecipeManager().getAllRecipesFor(ERecipeTypes.SIEVE.get()));
+ Multimap ingredientGrouper = ArrayListMultimap.create();
+
+ for (int i = 0; i < recipes.size(); i++) {
+ var recipe = recipes.get(i);
+
+ ingredientGrouper.put(recipe.getIngredient(), recipe);
+
+ for (int j = i + 1; j < recipes.size(); j++) {
+ var other = recipes.get(j);
+
+ if (RecipeUtil.areIngredientsEqual(recipe.getIngredient(), other.getIngredient())) {
+ ingredientGrouper.put(recipe.getIngredient(), other);
+ recipes.remove(other);
+ j--;
+ }
+ }
+ }
+
+ ImmutableList.Builder jeiRecipes = new ImmutableList.Builder<>();
+ // Sort based on expected count of result
+ var sorter = Comparator.comparingDouble(Result::expectedCount).reversed();
+
+ // ingredients with common ingredients are grouped into lists (ex. dirt)
+ for (var ingredient : ingredientGrouper.keySet()) {
+ Multimap
- meshGrouper = ArrayListMultimap.create();
+ var values = ingredientGrouper.get(ingredient);
+
+ // these lists are grouped into sub lists based on their meshes (ex. dirt with string mesh)
+ for (var recipe : values) {
+ meshGrouper.put(recipe.mesh, recipe);
+ }
+
+ // the sub lists have their results combined for displaying in JEI
+ for (var mesh : meshGrouper.keySet()) {
+ var meshRecipes = meshGrouper.get(mesh);
+ var results = new ArrayList(meshRecipes.size());
+
+ for (var recipe : meshRecipes) {
+ int resultCount = recipe.resultAmount instanceof ConstantValue constant ? Math.round(constant.value) : 1;
+ results.add(new Result(new ItemStack(recipe.result, resultCount), recipe.resultAmount));
+ }
+
+ results.sort(sorter);
+
+ var jeiRecipe = new JeiSieveRecipeGroup(ingredient, new ItemStack(mesh), results);
+ jeiRecipes.add(jeiRecipe);
+
+ var rows = Mth.ceil((float) meshRecipes.size() / 9f);
+ if (rows > maxSieveRows) {
+ maxSieveRows = rows;
+ }
+ }
+ }
+
+ registration.addRecipes(recipeType, jeiRecipes.build());
+ }
+
+ static final class Result {
+ final ItemStack item;
+ final NumberProvider provider;
+ final double expectedCount;
+
+ Result(ItemStack item, NumberProvider provider) {
+ this.item = item;
+ this.provider = provider;
+ this.expectedCount = RecipeUtil.getExpectedValue(this.provider);
+ }
+
+ public double expectedCount() {
+ return this.expectedCount;
+ }
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/OneToOneCategory.java b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/OneToOneCategory.java
new file mode 100644
index 00000000..84593b77
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/OneToOneCategory.java
@@ -0,0 +1,62 @@
+package thedarkcolour.exnihiloreborn.compat.jei;
+
+import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
+import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
+import mezz.jei.api.gui.drawable.IDrawable;
+import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
+import mezz.jei.api.helpers.IGuiHelper;
+import mezz.jei.api.recipe.IFocusGroup;
+import mezz.jei.api.recipe.RecipeIngredientRole;
+import mezz.jei.api.recipe.category.IRecipeCategory;
+import net.minecraft.client.gui.GuiGraphics;
+import net.minecraft.network.chat.Component;
+
+abstract class OneToOneCategory implements IRecipeCategory {
+ public static final int WIDTH = 72;
+ public static final int HEIGHT = 18;
+
+ private final IDrawable background;
+ private final IDrawable arrow;
+ private final IDrawable icon;
+ private final IDrawable slot;
+ private final Component title;
+
+ public OneToOneCategory(IGuiHelper helper, IDrawable arrow, IDrawable icon, Component title) {
+ this.background = helper.createBlankDrawable(WIDTH, HEIGHT);
+ this.arrow = arrow;
+ this.icon = icon;
+ this.slot = helper.getSlotDrawable();
+ this.title = title;
+ }
+
+ protected abstract void addInput(IRecipeSlotBuilder slot, T recipe);
+ protected abstract void addOutput(IRecipeSlotBuilder slot, T recipe);
+
+ @Override
+ public Component getTitle() {
+ return this.title;
+ }
+
+ @Override
+ public void setRecipe(IRecipeLayoutBuilder builder, T recipe, IFocusGroup focuses) {
+ addInput(builder.addSlot(RecipeIngredientRole.INPUT, 1, 1), recipe);
+ addOutput(builder.addSlot(RecipeIngredientRole.OUTPUT, 55, 1), recipe);
+ }
+
+ @Override
+ public IDrawable getBackground() {
+ return this.background;
+ }
+
+ @Override
+ public IDrawable getIcon() {
+ return this.icon;
+ }
+
+ @Override
+ public void draw(T recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) {
+ slot.draw(graphics);
+ arrow.draw(graphics, 25, 1);
+ slot.draw(graphics, 54, 0);
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/SieveCategory.java b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/SieveCategory.java
new file mode 100644
index 00000000..aa42d606
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/compat/jei/SieveCategory.java
@@ -0,0 +1,134 @@
+package thedarkcolour.exnihiloreborn.compat.jei;
+
+import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
+import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
+import mezz.jei.api.gui.drawable.IDrawable;
+import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
+import mezz.jei.api.helpers.IGuiHelper;
+import mezz.jei.api.recipe.IFocusGroup;
+import mezz.jei.api.recipe.RecipeIngredientRole;
+import mezz.jei.api.recipe.RecipeType;
+import mezz.jei.api.recipe.category.IRecipeCategory;
+import net.minecraft.ChatFormatting;
+import net.minecraft.client.gui.GuiGraphics;
+import net.minecraft.client.gui.screens.Screen;
+import net.minecraft.network.chat.Component;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator;
+import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
+import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
+import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
+import net.minecraftforge.common.util.Lazy;
+import thedarkcolour.exnihiloreborn.data.TranslationKeys;
+import thedarkcolour.exnihiloreborn.recipe.RecipeUtil;
+import thedarkcolour.exnihiloreborn.registry.EBlocks;
+
+import java.text.DecimalFormat;
+
+class SieveCategory implements IRecipeCategory {
+ private static final DecimalFormat FORMATTER = new DecimalFormat();
+ public static final int WIDTH = 162;
+ public static final int ROW_START = 28;
+
+ static {
+ FORMATTER.setMinimumFractionDigits(0);
+ FORMATTER.setMaximumFractionDigits(3);
+ }
+
+ private final Lazy background;
+ private final IDrawable slot;
+ private final IDrawable row;
+ private final IDrawable icon;
+ private final Component title;
+
+ public SieveCategory(IGuiHelper helper) {
+ this.background = Lazy.of(() -> helper.createBlankDrawable(WIDTH, ROW_START + 18 * JeiSieveRecipeGroup.maxSieveRows));
+ this.slot = helper.getSlotDrawable();
+ this.row = helper.createDrawable(ExNihiloRebornJeiPlugin.ENH_JEI_TEXTURE, 0, 0, 162, 18);
+ this.icon = helper.createDrawableItemStack(new ItemStack(EBlocks.OAK_SIEVE.get()));
+ this.title = Component.translatable(TranslationKeys.SIEVE_CATEGORY_TITLE);
+ }
+
+ @Override
+ public RecipeType getRecipeType() {
+ return ExNihiloRebornJeiPlugin.SIEVE;
+ }
+
+ @Override
+ public Component getTitle() {
+ return this.title;
+ }
+
+ @Override
+ public IDrawable getBackground() {
+ return this.background.get();
+ }
+
+ @Override
+ public IDrawable getIcon() {
+ return this.icon;
+ }
+
+ @Override
+ public void setRecipe(IRecipeLayoutBuilder builder, JeiSieveRecipeGroup recipe, IFocusGroup focuses) {
+ builder.addSlot(RecipeIngredientRole.INPUT, 59, 1).addIngredients(recipe.ingredient());
+ builder.addSlot(RecipeIngredientRole.CATALYST, 87, 1).addItemStack(recipe.mesh());
+
+ for (int i = 0; i < recipe.results().size(); i++) {
+ var result = recipe.results().get(i);
+ var slot = builder.addSlot(RecipeIngredientRole.OUTPUT, 1 + (i % 9) * 18, 1 + ROW_START + 18 * (i / 9)).addItemStack(result.item);
+
+ addTooltips(slot, result.provider);
+ }
+ }
+
+ public static void addTooltips(IRecipeSlotBuilder slot, NumberProvider provider) {
+ if (provider instanceof BinomialDistributionGenerator binomial) {
+ if (binomial.n instanceof ConstantValue constant && constant.value == 1) {
+ var chance = FORMATTER.format(RecipeUtil.getExpectedValue(binomial.p) * 100);
+ slot.addTooltipCallback((slotView, tooltip) -> tooltip.add(Component.translatable(TranslationKeys.SIEVE_RECIPE_CHANCE, chance).withStyle(ChatFormatting.GRAY)));
+ } else {
+ addAvgOutput(slot, RecipeUtil.getExpectedValue(provider));
+ }
+
+ addMinMaxes(slot, ConstantValue.exactly(0), binomial.n);
+ } else if (provider.getClass() != ConstantValue.class) {
+ var val = RecipeUtil.getExpectedValue(provider);
+ if (val != -1.0) {
+ addAvgOutput(slot, val);
+
+ if (provider instanceof UniformGenerator uniform) {
+ addMinMaxes(slot, uniform.min, uniform.max);
+ }
+ }
+ }
+ }
+
+ private static void addAvgOutput(IRecipeSlotBuilder slot, double avgValue) {
+ String avgOutput = FORMATTER.format(avgValue);
+ slot.addTooltipCallback((slotView, tooltip) -> tooltip.add(Component.translatable(TranslationKeys.SIEVE_RECIPE_AVERAGE_OUTPUT, avgOutput).withStyle(ChatFormatting.GRAY)));
+ }
+
+ // when the player holds shift, they can see the min/max amounts of a drop
+ private static void addMinMaxes(IRecipeSlotBuilder slot, NumberProvider min, NumberProvider max) {
+ var minFormatted = FORMATTER.format(RecipeUtil.getExpectedValue(min));
+ var maxFormatted = FORMATTER.format(RecipeUtil.getExpectedValue(max));
+
+ slot.addTooltipCallback((slotView, tooltip) -> {
+ if (Screen.hasShiftDown()) {
+ tooltip.add(Component.translatable(TranslationKeys.SIEVE_RECIPE_MIN_OUTPUT, minFormatted).withStyle(ChatFormatting.GRAY));
+ tooltip.add(Component.translatable(TranslationKeys.SIEVE_RECIPE_MAX_OUTPUT, maxFormatted).withStyle(ChatFormatting.GRAY));
+ }
+ });
+ }
+
+ @Override
+ public void draw(JeiSieveRecipeGroup recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics graphics, double mouseX, double mouseY) {
+ slot.draw(graphics, 58, 0);
+ slot.draw(graphics, 86, 0);
+
+ for (int i = 0; i < JeiSieveRecipeGroup.maxSieveRows; i++) {
+ row.draw(graphics, 0, 28 + i * 18);
+ }
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/compat/top/InfestedLeavesInfoProvider.java b/src/main/java/thedarkcolour/exnihiloreborn/compat/top/ExNihiloRebornInfoProvider.java
similarity index 92%
rename from src/main/java/thedarkcolour/exnihiloreborn/compat/top/InfestedLeavesInfoProvider.java
rename to src/main/java/thedarkcolour/exnihiloreborn/compat/top/ExNihiloRebornInfoProvider.java
index 13c54fe6..978e9a83 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/compat/top/InfestedLeavesInfoProvider.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/compat/top/ExNihiloRebornInfoProvider.java
@@ -16,10 +16,10 @@ import thedarkcolour.exnihiloreborn.blockentity.BarrelBlockEntity;
import thedarkcolour.exnihiloreborn.blockentity.InfestedLeavesBlockEntity;
import thedarkcolour.exnihiloreborn.registry.EBlocks;
-public class InfestedLeavesInfoProvider implements IProbeInfoProvider {
+public class ExNihiloRebornInfoProvider implements IProbeInfoProvider {
@Override
public ResourceLocation getID() {
- return new ResourceLocation(ExNihiloReborn.ID, "infested_leaves");
+ return new ResourceLocation(ExNihiloReborn.ID, "info_provider");
}
@Override
@@ -49,8 +49,7 @@ public class InfestedLeavesInfoProvider implements IProbeInfoProvider {
info.text(CompoundText.create().style(TextStyleClass.ERROR).text("Burning! ").style(TextStyleClass.WARNING).text(progress / 20 + "s"));
}
} else if (te instanceof AbstractCrucibleBlockEntity crucible) {
- info.tankHandler(crucible.getTank());
- info.text(CompoundText.create().style(TextStyleClass.LABEL).text("Rate: ").style(TextStyleClass.WARNING).text(crucible.getMelt() + "x"));
+ info.text(CompoundText.create().style(TextStyleClass.LABEL).text("Rate: ").style(TextStyleClass.WARNING).text(crucible.getMeltingRate() + "x"));
}
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/compat/top/TopCompatExNihiloReborn.java b/src/main/java/thedarkcolour/exnihiloreborn/compat/top/TopCompatExNihiloReborn.java
index ffb00de3..627b7c4d 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/compat/top/TopCompatExNihiloReborn.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/compat/top/TopCompatExNihiloReborn.java
@@ -7,7 +7,7 @@ import java.util.function.Function;
public class TopCompatExNihiloReborn implements Function {
@Override
public Void apply(ITheOneProbe top) {
- top.registerProvider(new InfestedLeavesInfoProvider());
+ top.registerProvider(new ExNihiloRebornInfoProvider());
return null;
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/Advancements.java b/src/main/java/thedarkcolour/exnihiloreborn/data/Advancements.java
index 44009b8d..091d5f85 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/Advancements.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/data/Advancements.java
@@ -64,7 +64,7 @@ class Advancements extends ForgeAdvancementProvider {
true,
false
)
- .addCriterion("craft_crook", RecipeCraftedTrigger.TriggerInstance.craftedItem(EItems.CROOK.getId()))
+ .addCriterion("craft_crook", hasItems(item().of(EItemTags.CROOKS).build()))
.save(saver, modLoc("core/crook"), helper);
var barrel = advancement()
.parent(root)
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/BlockLoot.java b/src/main/java/thedarkcolour/exnihiloreborn/data/BlockLoot.java
index b7f1b782..49861750 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/BlockLoot.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/data/BlockLoot.java
@@ -1,5 +1,6 @@
package thedarkcolour.exnihiloreborn.data;
+import net.minecraft.core.registries.Registries;
import net.minecraft.data.loot.BlockLootSubProvider;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.flag.FeatureFlagSet;
@@ -10,8 +11,11 @@ import net.minecraft.world.level.storage.loot.LootPool;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.entries.LootItem;
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
+import net.minecraftforge.registries.ForgeRegistries;
+import thedarkcolour.exnihiloreborn.ExNihiloReborn;
import thedarkcolour.exnihiloreborn.loot.InfestedStringCount;
import thedarkcolour.exnihiloreborn.registry.EBlocks;
+import thedarkcolour.modkit.MKUtils;
import java.util.ArrayList;
import java.util.List;
@@ -27,35 +31,12 @@ class BlockLoot extends BlockLootSubProvider {
@Override
protected void generate() {
+ MKUtils.forModRegistry(Registries.BLOCK, ExNihiloReborn.ID, (id, block) -> dropSelf(block));
+
add(EBlocks.INFESTED_LEAVES.get(), new LootTable.Builder()
.withPool(new LootPool.Builder()
.setRolls(ConstantValue.exactly(1))
.add(LootItem.lootTableItem(Items.STRING).apply(InfestedStringCount.infestedString()))));
-
- addSelfDrops();
- }
-
- private void dropSelf(Supplier extends Block> item) {
- this.dropSelf(item.get());
- }
-
- private void addSelfDrops() {
- dropSelf(EBlocks.DUST);
-
- dropSelf(EBlocks.COMPRESSED_COBBLESTONE);
- dropSelf(EBlocks.COMPRESSED_DIRT);
- dropSelf(EBlocks.COMPRESSED_SAND);
- dropSelf(EBlocks.COMPRESSED_DUST);
-
- dropSelf(EBlocks.OAK_BARREL);
- dropSelf(EBlocks.SPRUCE_BARREL);
- dropSelf(EBlocks.BIRCH_BARREL);
- dropSelf(EBlocks.JUNGLE_BARREL);
- dropSelf(EBlocks.ACACIA_BARREL);
- dropSelf(EBlocks.DARK_OAK_BARREL);
- dropSelf(EBlocks.CRIMSON_BARREL);
- dropSelf(EBlocks.WARPED_BARREL);
- dropSelf(EBlocks.STONE_BARREL);
}
@Override
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/BlockTags.java b/src/main/java/thedarkcolour/exnihiloreborn/data/BlockTags.java
deleted file mode 100644
index 954ca1f2..00000000
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/BlockTags.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package thedarkcolour.exnihiloreborn.data;
-
-import net.minecraft.core.HolderLookup;
-import net.minecraft.data.PackOutput;
-import net.minecraftforge.common.data.BlockTagsProvider;
-import net.minecraftforge.common.data.ExistingFileHelper;
-import thedarkcolour.exnihiloreborn.ExNihiloReborn;
-
-import javax.annotation.Nullable;
-import java.util.concurrent.CompletableFuture;
-
-class BlockTags extends BlockTagsProvider {
- public BlockTags(PackOutput output, CompletableFuture lookup, @Nullable ExistingFileHelper helper) {
- super(output, lookup, ExNihiloReborn.ID, helper);
- }
-
- @Override
- protected void addTags(HolderLookup.Provider lookup) {
- }
-}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/Data.java b/src/main/java/thedarkcolour/exnihiloreborn/data/Data.java
index cc0732c0..2474226d 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/Data.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/data/Data.java
@@ -1,7 +1,5 @@
package thedarkcolour.exnihiloreborn.data;
-import net.minecraft.core.RegistryAccess;
-import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraftforge.data.event.GatherDataEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
@@ -9,7 +7,7 @@ import net.minecraftforge.fml.common.Mod;
import thedarkcolour.exnihiloreborn.ExNihiloReborn;
import thedarkcolour.modkit.data.DataHelper;
-// these two annotations basically mean modEventBus.addListener(Data::generateData)
+// these two annotations are equivalent to modEventBus.addListener(Data::generateData)
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class Data {
@SubscribeEvent
@@ -18,7 +16,8 @@ public class Data {
var gen = event.getGenerator(); // writes to json
var output = gen.getPackOutput();
var lookup = event.getLookupProvider();
- var helper = event.getExistingFileHelper(); // reads existing files like pngs and parent models
+ // reads existing files like pngs and parent models
+ var helper = event.getExistingFileHelper();
var dataHelper = new DataHelper(ExNihiloReborn.ID, event);
dataHelper.createEnglish(true, English::addTranslations);
@@ -26,14 +25,13 @@ public class Data {
dataHelper.createItemModels(true, true, false, ItemModels::addItemModels);
dataHelper.createRecipes(Recipes::addRecipes);
-
- var blockTags = new BlockTags(output, lookup, helper);
+ dataHelper.createTags(Registries.BLOCK, ModTags::createBlockTags);
+ dataHelper.createTags(Registries.ITEM, ModTags::createItemTags);
+ dataHelper.createTags(Registries.FLUID, ModTags::createFluidTags);
+ dataHelper.createTags(Registries.STRUCTURE_SET, ModTags::createStructureSetTags);
+ dataHelper.createTags(Registries.WORLD_PRESET, ModTags::createWorldPresetTags);
gen.addProvider(true, new LootTables(output));
- gen.addProvider(true, blockTags);
- gen.addProvider(true, new ItemTags(output, lookup, blockTags.contentsGetter(), helper));
- gen.addProvider(true, new StructureTags(output, lookup, helper));
- gen.addProvider(true, new WorldPresetTags(output, lookup, helper));
gen.addProvider(true, new Advancements(output, lookup, helper));
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/English.java b/src/main/java/thedarkcolour/exnihiloreborn/data/English.java
index 6589157b..05d718de 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/English.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/data/English.java
@@ -1,15 +1,18 @@
package thedarkcolour.exnihiloreborn.data;
+import thedarkcolour.exnihiloreborn.ExNihiloReborn;
import thedarkcolour.modkit.data.MKEnglishProvider;
class English {
static void addTranslations(MKEnglishProvider english) {
+ english.add("fluid_type." + ExNihiloReborn.ID + ".witch_water", "Witch Water");
+
english.add(TranslationKeys.MAIN_CREATIVE_TAB, "Ex Nihilo Reborn");
english.add(TranslationKeys.VOID_WORLD_TYPE, "Void World");
english.add(TranslationKeys.ROOT_ADVANCEMENT_TITLE, "Don't Look Down...");
english.add(TranslationKeys.ROOT_ADVANCEMENT_DESCRIPTION, "Spawn into a SkyBlock void world");
- english.add(TranslationKeys.CROOK_ADVANCEMENT_TITLE, "This is a Robbery");
+ english.add(TranslationKeys.CROOK_ADVANCEMENT_TITLE, "Give Him The Hook");
english.add(TranslationKeys.CROOK_ADVANCEMENT_DESCRIPTION, "Craft a Crook to double sapling drops from leaves");
english.add(TranslationKeys.BARREL_ADVANCEMENT_TITLE, "That Goes in the GreenWaste");
english.add(TranslationKeys.BARREL_ADVANCEMENT_DESCRIPTION, "Use a barrel to compost organic material into dirt");
@@ -19,13 +22,16 @@ class English {
english.add(TranslationKeys.STRING_MESH_ADVANCEMENT_DESCRIPTION, "Craft a string mesh to use in a sieve");
english.add(TranslationKeys.SILK_WORM_JEI_INFO, "Silk worms have a 1 in 100 chance to drop from leaves harvested with a Crook. Using a silk worm on a tree's leaves will infest them, gradually spreading through the entire tree. 100% infested leaves can be harvested for string, but do not drop saplings.");
+ english.add(TranslationKeys.SIEVE_JEI_INFO, "Sieves are used to filter out certain items from soft blocks like gravel and dirt. A mesh is required to use the sieve, and it can be enchanted with Fortune and Efficiency.");
english.add(TranslationKeys.BARREL_COMPOST_CATEGORY_TITLE, "Barrel Compost");
english.add(TranslationKeys.BARREL_COMPOST_RECIPE_VOLUME, "Compost: %s");
english.add(TranslationKeys.WATER_CRUCIBLE_CATEGORY_TITLE, "Water Crucible");
english.add(TranslationKeys.LAVA_CRUCIBLE_CATEGORY_TITLE, "Lava Crucible");
- english.add(TranslationKeys.HAMMER_CATEGORY_TITLE, "Hammer Crucible");
- english.add(TranslationKeys.COMPRESSED_HAMMER_CATEGORY_TITLE, "Compressed Hammer");
+ english.add(TranslationKeys.HAMMER_CATEGORY_TITLE, "Hammer");
english.add(TranslationKeys.SIEVE_CATEGORY_TITLE, "Sieve");
- english.add(TranslationKeys.COMPRESSED_SIEVE_CATEGORY_TITLE, "Heavy Sieve");
+ english.add(TranslationKeys.SIEVE_RECIPE_CHANCE, "Chance: %s%%");
+ english.add(TranslationKeys.SIEVE_RECIPE_AVERAGE_OUTPUT, "Avg. Output: %s");
+ english.add(TranslationKeys.SIEVE_RECIPE_MIN_OUTPUT, "Min: %s");
+ english.add(TranslationKeys.SIEVE_RECIPE_MAX_OUTPUT, "Max: %s");
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/FluidTags.java b/src/main/java/thedarkcolour/exnihiloreborn/data/FluidTags.java
deleted file mode 100644
index 63e9f3f3..00000000
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/FluidTags.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package thedarkcolour.exnihiloreborn.data;
-
-public class FluidTags {
-}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/ItemTags.java b/src/main/java/thedarkcolour/exnihiloreborn/data/ItemTags.java
deleted file mode 100644
index 316fff57..00000000
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/ItemTags.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package thedarkcolour.exnihiloreborn.data;
-
-import net.minecraft.core.HolderLookup;
-import net.minecraft.data.PackOutput;
-import net.minecraft.data.tags.ItemTagsProvider;
-import net.minecraft.world.level.block.Block;
-import net.minecraftforge.common.data.ExistingFileHelper;
-import org.jetbrains.annotations.Nullable;
-import thedarkcolour.exnihiloreborn.ExNihiloReborn;
-import thedarkcolour.exnihiloreborn.tag.EItemTags;
-import thedarkcolour.exnihiloreborn.registry.EItems;
-
-import java.util.concurrent.CompletableFuture;
-
-class ItemTags extends ItemTagsProvider {
- public ItemTags(PackOutput output, CompletableFuture lookupProvider, CompletableFuture> blockTags, @Nullable ExistingFileHelper existingFileHelper) {
- super(output, lookupProvider, blockTags, ExNihiloReborn.ID, existingFileHelper);
- }
-
- @SuppressWarnings("unchecked")
- @Override
- protected void addTags(HolderLookup.Provider lookup) {
- tag(EItemTags.HAMMERS).add(EItems.WOODEN_HAMMER.get(), EItems.STONE_HAMMER.get(), EItems.GOLDEN_HAMMER.get(), EItems.IRON_HAMMER.get(), EItems.DIAMOND_HAMMER.get(), EItems.NETHERITE_HAMMER.get());
- tag(EItemTags.CROOKS).add(EItems.CROOK.get(), EItems.BONE_CROOK.get());
- tag(EItemTags.WOODEN_BARRELS).add(EItems.OAK_BARREL.get(), EItems.SPRUCE_BARREL.get(), EItems.BIRCH_BARREL.get(), EItems.JUNGLE_BARREL.get(), EItems.ACACIA_BARREL.get(), EItems.DARK_OAK_BARREL.get(), EItems.MANGROVE_BARREL.get(), EItems.CHERRY_BARREL.get(), EItems.BAMBOO_BARREL.get());
- tag(EItemTags.STONE_BARRELS).add(EItems.STONE_BARREL.get());
- tag(EItemTags.BARRELS).addTags(EItemTags.WOODEN_BARRELS, EItemTags.STONE_BARRELS);
- }
-}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/ModTags.java b/src/main/java/thedarkcolour/exnihiloreborn/data/ModTags.java
new file mode 100644
index 00000000..daf8adef
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/data/ModTags.java
@@ -0,0 +1,51 @@
+package thedarkcolour.exnihiloreborn.data;
+
+import net.minecraft.core.registries.Registries;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.tags.BlockTags;
+import net.minecraft.tags.FluidTags;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.level.block.Block;
+import net.minecraft.world.level.levelgen.presets.WorldPreset;
+import net.minecraft.world.level.levelgen.structure.BuiltinStructureSets;
+import net.minecraft.world.level.levelgen.structure.StructureSet;
+import net.minecraft.world.level.material.Fluid;
+import thedarkcolour.exnihiloreborn.ExNihiloReborn;
+import thedarkcolour.exnihiloreborn.registry.EBlocks;
+import thedarkcolour.exnihiloreborn.registry.EFluids;
+import thedarkcolour.exnihiloreborn.registry.EItems;
+import thedarkcolour.exnihiloreborn.tag.EItemTags;
+import thedarkcolour.exnihiloreborn.tag.EStructureSetTags;
+import thedarkcolour.modkit.data.MKTagsProvider;
+
+class ModTags {
+ public static void createBlockTags(MKTagsProvider tags) {
+ tags.tag(BlockTags.MINEABLE_WITH_AXE).add(EBlocks.OAK_BARREL.get(), EBlocks.SPRUCE_BARREL.get(), EBlocks.BIRCH_BARREL.get(), EBlocks.JUNGLE_BARREL.get(), EBlocks.ACACIA_BARREL.get(), EBlocks.DARK_OAK_BARREL.get(), EBlocks.MANGROVE_BARREL.get(), EBlocks.CHERRY_BARREL.get(), EBlocks.BAMBOO_BARREL.get(), EBlocks.CRIMSON_BARREL.get(), EBlocks.WARPED_BARREL.get(), EBlocks.OAK_SIEVE.get(), EBlocks.SPRUCE_SIEVE.get(), EBlocks.BIRCH_SIEVE.get(), EBlocks.JUNGLE_SIEVE.get(), EBlocks.ACACIA_SIEVE.get(), EBlocks.DARK_OAK_SIEVE.get(), EBlocks.MANGROVE_SIEVE.get(), EBlocks.CHERRY_SIEVE.get(), EBlocks.BAMBOO_SIEVE.get(), EBlocks.CRIMSON_SIEVE.get(), EBlocks.WARPED_SIEVE.get(), EBlocks.WARPED_CRUCIBLE.get(), EBlocks.CRIMSON_CRUCIBLE.get(), EBlocks.OAK_CRUCIBLE.get(), EBlocks.SPRUCE_CRUCIBLE.get(), EBlocks.BIRCH_CRUCIBLE.get(), EBlocks.JUNGLE_CRUCIBLE.get(), EBlocks.ACACIA_CRUCIBLE.get(), EBlocks.DARK_OAK_CRUCIBLE.get(), EBlocks.MANGROVE_CRUCIBLE.get(), EBlocks.CHERRY_CRUCIBLE.get(), EBlocks.BAMBOO_CRUCIBLE.get());
+ tags.tag(BlockTags.MINEABLE_WITH_PICKAXE).add(EBlocks.STONE_BARREL.get(), EBlocks.PORCELAIN_CRUCIBLE.get(), EBlocks.UNFIRED_CRUCIBLE.get());
+ }
+
+ public static void createItemTags(MKTagsProvider
- tags) {
+ tags.tag(EItemTags.HAMMERS).add(EItems.WOODEN_HAMMER, EItems.STONE_HAMMER, EItems.GOLDEN_HAMMER, EItems.IRON_HAMMER, EItems.DIAMOND_HAMMER, EItems.NETHERITE_HAMMER);
+ tags.tag(EItemTags.CROOKS).add(EItems.CROOK, EItems.BONE_CROOK);
+ tags.tag(EItemTags.SIEVE_MESHES).add(EItems.STRING_MESH, EItems.FLINT_MESH, EItems.IRON_MESH, EItems.GOLDEN_MESH, EItems.DIAMOND_MESH, EItems.NETHERITE_MESH);
+ tags.tag(EItemTags.PEBBLES).add(EItems.STONE_PEBBLE, EItems.DIORITE_PEBBLE, EItems.GRANITE_PEBBLE, EItems.ANDESITE_PEBBLE, EItems.DEEPSLATE_PEBBLE, EItems.TUFF_PEBBLE);
+ tags.tag(EItemTags.WOODEN_BARRELS).add(EItems.OAK_BARREL.get(), EItems.SPRUCE_BARREL.get(), EItems.BIRCH_BARREL.get(), EItems.JUNGLE_BARREL.get(), EItems.ACACIA_BARREL.get(), EItems.DARK_OAK_BARREL.get(), EItems.MANGROVE_BARREL.get(), EItems.CHERRY_BARREL.get(), EItems.BAMBOO_BARREL.get());
+ tags.tag(EItemTags.STONE_BARRELS).add(EItems.STONE_BARREL.get());
+ tags.tag(EItemTags.BARRELS).addTags(EItemTags.WOODEN_BARRELS, EItemTags.STONE_BARRELS);
+ }
+
+ public static void createStructureSetTags(MKTagsProvider tags) {
+ tags.tag(EStructureSetTags.OVERWORLD_VOID_STRUCTURES);
+ tags.tag(EStructureSetTags.THE_NETHER_VOID_STRUCTURES).add(BuiltinStructureSets.NETHER_COMPLEXES);
+ tags.tag(EStructureSetTags.THE_END_VOID_STRUCTURES).add(BuiltinStructureSets.END_CITIES);
+ }
+
+ public static void createWorldPresetTags(MKTagsProvider tags) {
+ tags.tag(net.minecraft.tags.WorldPresetTags.NORMAL).add(ResourceKey.create(Registries.WORLD_PRESET, new ResourceLocation(ExNihiloReborn.ID, "void_world")));
+ }
+
+ public static void createFluidTags(MKTagsProvider tags) {
+ tags.tag(FluidTags.WATER).add(EFluids.WITCH_WATER_STILL.get(), EFluids.WITCH_WATER_FLOWING.get());
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/Recipes.java b/src/main/java/thedarkcolour/exnihiloreborn/data/Recipes.java
index 10299c5c..02bb4a96 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/Recipes.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/data/Recipes.java
@@ -1,46 +1,56 @@
package thedarkcolour.exnihiloreborn.data;
-import com.google.common.collect.ImmutableList;
import net.minecraft.data.recipes.FinishedRecipe;
import net.minecraft.data.recipes.RecipeBuilder;
import net.minecraft.data.recipes.RecipeCategory;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.ItemTags;
-import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.material.Fluids;
+import net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator;
+import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
+import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
+import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
+import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.common.Tags;
+import net.minecraftforge.fluids.FluidType;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
import thedarkcolour.exnihiloreborn.ExNihiloReborn;
-import thedarkcolour.exnihiloreborn.recipe.Reward;
import thedarkcolour.exnihiloreborn.recipe.barrel.FinishedBarrelCompostRecipe;
+import thedarkcolour.exnihiloreborn.recipe.barrel.FinishedBarrelMixingRecipe;
import thedarkcolour.exnihiloreborn.recipe.crucible.FinishedCrucibleRecipe;
import thedarkcolour.exnihiloreborn.recipe.hammer.FinishedHammerRecipe;
import thedarkcolour.exnihiloreborn.recipe.sieve.FinishedSieveRecipe;
import thedarkcolour.exnihiloreborn.registry.EBlocks;
+import thedarkcolour.exnihiloreborn.registry.EFluids;
import thedarkcolour.exnihiloreborn.registry.EItems;
import thedarkcolour.exnihiloreborn.registry.ERecipeSerializers;
import thedarkcolour.modkit.data.MKRecipeProvider;
+import java.util.Objects;
+import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import static net.minecraft.data.recipes.SimpleCookingRecipeBuilder.*;
import static net.minecraft.data.recipes.SmithingTransformRecipeBuilder.smithing;
+import static net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator.binomial;
+import static thedarkcolour.modkit.data.MKRecipeProvider.unlockedByHaving;
class Recipes {
public static void addRecipes(Consumer writer, MKRecipeProvider recipes) {
craftingRecipes(writer, recipes);
- smeltingRecipes(writer, recipes);
- sieveRecipes(writer, recipes);
+ smeltingRecipes(writer);
+ sieveRecipes(writer);
crucibleRecipes(writer);
hammerRecipes(writer);
barrelCompostRecipes(writer);
+ barrelMixingRecipes(writer);
}
private static void craftingRecipes(Consumer writer, MKRecipeProvider recipes) {
@@ -54,7 +64,7 @@ class Recipes {
shapedHammer(recipes, EItems.GOLDEN_HAMMER, Ingredient.of(Tags.Items.INGOTS_GOLD));
shapedHammer(recipes, EItems.IRON_HAMMER, Ingredient.of(Tags.Items.INGOTS_IRON));
shapedHammer(recipes, EItems.DIAMOND_HAMMER, Ingredient.of(Tags.Items.GEMS_DIAMOND));
- MKRecipeProvider.unlockedByHaving(smithing(
+ unlockedByHaving(smithing(
Ingredient.of(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE),
Ingredient.of(EItems.DIAMOND_HAMMER.get()),
Ingredient.of(Tags.Items.INGOTS_NETHERITE),
@@ -91,6 +101,20 @@ class Recipes {
uShaped(recipes, EItems.CRIMSON_BARREL, Ingredient.of(Items.CRIMSON_PLANKS), Ingredient.of(Items.CRIMSON_SLAB));
uShaped(recipes, EItems.WARPED_BARREL, Ingredient.of(Items.WARPED_PLANKS), Ingredient.of(Items.WARPED_SLAB));
uShaped(recipes, EItems.STONE_BARREL, Ingredient.of(Items.STONE), Ingredient.of(Items.STONE_SLAB));
+
+ twoByTwo(recipes, Items.COBBLESTONE, Ingredient.of(EItems.STONE_PEBBLE.get()));
+ twoByTwo(recipes, Items.ANDESITE, Ingredient.of(EItems.ANDESITE_PEBBLE.get()));
+ twoByTwo(recipes, Items.DIORITE, Ingredient.of(EItems.DIORITE_PEBBLE.get()));
+ twoByTwo(recipes, Items.GRANITE, Ingredient.of(EItems.GRANITE_PEBBLE.get()));
+ twoByTwo(recipes, Items.IRON_ORE, Ingredient.of(EItems.IRON_ORE_CHUNK.get()));
+ twoByTwo(recipes, Items.GOLD_ORE, Ingredient.of(EItems.GOLD_ORE_CHUNK.get()));
+ twoByTwo(recipes, Items.COPPER_ORE, Ingredient.of(EItems.COPPER_ORE_CHUNK.get()));
+ recipes.shapedCrafting(RecipeCategory.MISC, EItems.STRING_MESH.get(), recipe -> {
+ recipe.define('s', Tags.Items.STRING);
+ recipe.pattern("sss");
+ recipe.pattern("sss");
+ recipe.pattern("sss");
+ });
}
private static void shapedCrook(MKRecipeProvider recipes, RegistryObject extends Item> crook, Ingredient stick) {
@@ -122,40 +146,72 @@ class Recipes {
});
}
+ private static void twoByTwo(MKRecipeProvider recipes, Item result, Ingredient ingredient) {
+ recipes.shapedCrafting(RecipeCategory.MISC, result, recipe -> {
+ recipe.define('#', ingredient);
+ recipe.pattern("##");
+ recipe.pattern("##");
+ });
+ }
+
// todo add support in modkit
- private static void smeltingRecipes(Consumer writer, MKRecipeProvider recipes) {
- MKRecipeProvider.unlockedByHaving(
+ private static void smeltingRecipes(Consumer writer) {
+ unlockedByHaving(
smelting(Ingredient.of(EItems.UNFIRED_CRUCIBLE.get()), RecipeCategory.MISC, EItems.PORCELAIN_CRUCIBLE.get(), 0.1f, 200),
EItems.UNFIRED_CRUCIBLE.get()
).save(writer, EItems.PORCELAIN_CRUCIBLE.getId());
- MKRecipeProvider.unlockedByHaving(
+ unlockedByHaving(
smelting(Ingredient.of(EItems.SILK_WORM.get()), RecipeCategory.FOOD, EItems.COOKED_SILK_WORM.get(), 0.1f, 200),
EItems.SILK_WORM.get()
).save(writer, EItems.COOKED_SILK_WORM.getId());
- MKRecipeProvider.unlockedByHaving(
+ unlockedByHaving(
smoking(Ingredient.of(EItems.SILK_WORM.get()), RecipeCategory.FOOD, EItems.COOKED_SILK_WORM.get(), 0.1f, 100),
EItems.SILK_WORM.get()
).save(writer, EItems.COOKED_SILK_WORM.getId().withSuffix("_from_smoking"));
- MKRecipeProvider.unlockedByHaving(
+ unlockedByHaving(
campfireCooking(Ingredient.of(EItems.SILK_WORM.get()), RecipeCategory.FOOD, EItems.COOKED_SILK_WORM.get(), 0.1f, 600),
EItems.SILK_WORM.get()
).save(writer, EItems.PORCELAIN_CRUCIBLE.getId().withSuffix("_from_campfire_cooking"));
}
- private static void sieveRecipes(Consumer writer, MKRecipeProvider recipes) {
- sieveRecipe(writer, "stone_pebble", Ingredient.of(Items.DIRT), EItems.STRING_MESH, Reward.withExtraChances(EItems.STONE_PEBBLE, new float[] {1.0f, 1.0f, 0.5f, 0.5f, 0.1f, 0.1f }));
- sieveRecipe(writer, "wheat_seeds", Ingredient.of(Items.DIRT), EItems.STRING_MESH, Reward.of(Items.WHEAT_SEEDS, 0.7f));
- sieveRecipe(writer, "beetroot_seeds", Ingredient.of(Items.DIRT), EItems.STRING_MESH, Reward.of(Items.BEETROOT_SEEDS, 0.35f));
- sieveRecipe(writer, "melon_seeds", Ingredient.of(Items.DIRT), EItems.STRING_MESH, Reward.of(Items.MELON_SEEDS, 0.35f));
- sieveRecipe(writer, "pumpkin_seeds", Ingredient.of(Items.DIRT), EItems.STRING_MESH, Reward.of(Items.PUMPKIN_SEEDS, 0.35f));
+ private static void sieveRecipes(Consumer writer) {
+ // Dirt -> String mesh
+ forMesh(writer, Ingredient.of(Items.DIRT), EItems.STRING_MESH, addDrop -> {
+ addDrop.accept(EItems.STONE_PEBBLE.get(), binomial(7, 0.6f));
+ addDrop.accept(Items.WHEAT_SEEDS, chance(0.7f));
+ addDrop.accept(Items.BEETROOT_SEEDS, chance(0.35f));
+ addDrop.accept(Items.MELON_SEEDS, chance(0.35f));
+ addDrop.accept(Items.PUMPKIN_SEEDS, chance(0.35f));
+ addDrop.accept(Items.FLINT, chance(0.25f));
+ });
+
+ // Flint mesh will be used to get a larger variety of outputs from dirt, and
+ // is the lowest mesh tier where ore will start to drop.
+ // Gravel -> String mesh
+ forMesh(writer, Ingredient.of(Items.DIRT), EItems.FLINT_MESH, addDrop -> {
+ addDrop.accept(EItems.STONE_PEBBLE.get(), binomial(7, 0.6f));
+ addDrop.accept(EItems.ANDESITE_PEBBLE.get(), binomial(7, 0.4f));
+ addDrop.accept(EItems.GRANITE_PEBBLE.get(), binomial(7, 0.4f));
+ addDrop.accept(EItems.DIORITE_PEBBLE.get(), binomial(7, 0.4f));
+ addDrop.accept(Items.WHEAT_SEEDS, chance(0.5f));
+ addDrop.accept(Items.BEETROOT_SEEDS, chance(0.1f));
+ addDrop.accept(Items.MELON_SEEDS, chance(0.1f));
+ addDrop.accept(Items.PUMPKIN_SEEDS, chance(0.1f));
+ addDrop.accept(Items.FLINT, chance(0.2f));
+ });
}
- private static void sieveRecipe(Consumer consumer, String name, Ingredient block, Supplier
- mesh, ImmutableList rewards) {
- consumer.accept(new FinishedSieveRecipe(ERecipeSerializers.SIEVE.get(), new ResourceLocation(ExNihiloReborn.ID, "sieve/" + name), mesh.get(), block, rewards));
+ private static BinomialDistributionGenerator chance(float p) {
+ return binomial(1, p);
}
- private static void sieveRecipe(Consumer consumer, String name, Ingredient block, Supplier
- mesh, Reward rewards) {
- consumer.accept(new FinishedSieveRecipe(ERecipeSerializers.SIEVE.get(), new ResourceLocation(ExNihiloReborn.ID, "sieve/" + name), mesh.get(), block, ImmutableList.of(rewards)));
+ private static void forMesh(Consumer writer, Ingredient block, RegistryObject extends Item> mesh, Consumer> addDrops) {
+ var folder = mesh.getId().getPath().replace("_mesh", "/");
+ addDrops.accept((result, resultAmount) -> sieveRecipe(writer, folder + path(result), block, mesh, result, resultAmount));
+ }
+
+ private static void sieveRecipe(Consumer consumer, String name, Ingredient block, Supplier extends Item> mesh, Item result, NumberProvider chance) {
+ consumer.accept(new FinishedSieveRecipe(new ResourceLocation(ExNihiloReborn.ID, "sieve/" + name), mesh.get(), block, result, chance));
}
private static void crucibleRecipes(Consumer writer) {
@@ -190,31 +246,25 @@ class Recipes {
private static void hammerRecipes(Consumer writer) {
// Cobblestone -> Gravel -> Sand -> Dust
- hammerRecipe(writer, "gravel", Blocks.COBBLESTONE, new Reward(Blocks.GRAVEL));
- hammerRecipe(writer, "sand", Blocks.GRAVEL, new Reward(Blocks.SAND));
- hammerRecipe(writer, "dust", Blocks.SAND, new Reward(EBlocks.DUST.get()));
+ hammerRecipe(writer, "gravel", Ingredient.of(Items.COBBLESTONE), Blocks.GRAVEL);
+ hammerRecipe(writer, "sand", Ingredient.of(Items.GRAVEL), Blocks.SAND);
+ hammerRecipe(writer, "dust", Ingredient.of(Items.SAND), EBlocks.DUST.get());
- hammerRecipe(writer, "crushed_netherrack", Blocks.NETHERRACK, new Reward(EBlocks.CRUSHED_NETHERRACK.get()));
+ hammerRecipe(writer, "crushed_netherrack", Ingredient.of(Blocks.NETHERRACK), EBlocks.CRUSHED_NETHERRACK.get());
- hammerRecipe(writer, "crushing_sandstone", Ingredient.of(Items.SANDSTONE, Items.CUT_SANDSTONE, Items.CHISELED_SANDSTONE, Items.SMOOTH_SANDSTONE), ImmutableList.of(new Reward(Items.SAND)));
- hammerRecipe(writer, "crushing_red_sandstone", Ingredient.of(Items.RED_SANDSTONE, Items.CUT_RED_SANDSTONE, Items.CHISELED_RED_SANDSTONE, Items.SMOOTH_RED_SANDSTONE), ImmutableList.of(new Reward(Items.RED_SAND)));
- hammerRecipe(writer, "crushing_stone_bricks", Items.STONE_BRICKS, new Reward(Items.CRACKED_STONE_BRICKS));
+ hammerRecipe(writer, "crushing_sandstone", Ingredient.of(Items.SANDSTONE, Items.CUT_SANDSTONE, Items.CHISELED_SANDSTONE, Items.SMOOTH_SANDSTONE), Items.SAND);
+ hammerRecipe(writer, "crushing_red_sandstone", Ingredient.of(Items.RED_SANDSTONE, Items.CUT_RED_SANDSTONE, Items.CHISELED_RED_SANDSTONE, Items.SMOOTH_RED_SANDSTONE), Items.RED_SAND);
+ hammerRecipe(writer, "crushing_stone_bricks", Ingredient.of(Items.STONE_BRICKS), Items.CRACKED_STONE_BRICKS);
- hammerRecipe(writer, "stone_pebbles",
- Ingredient.of(Items.STONE, Items.CRACKED_STONE_BRICKS),
- Reward.withExtraChances(EItems.STONE_PEBBLE, new float[] { 0.75f, 0.75f, 0.5f, 0.25f, 0.05f }));
+ hammerRecipe(writer, "stone_pebbles", Ingredient.of(Items.STONE, Items.STONE_BRICKS, Items.CHISELED_STONE_BRICKS, Items.CRACKED_STONE_BRICKS), EItems.STONE_PEBBLE.get(), new UniformGenerator(ConstantValue.exactly(1), ConstantValue.exactly(6)));
}
- private static void hammerRecipe(Consumer consumer, String name, Ingredient block, ImmutableList rewards) {
- consumer.accept(new FinishedHammerRecipe(ERecipeSerializers.HAMMER.get(), new ResourceLocation(ExNihiloReborn.ID, "hammer/" + name), block, rewards));
+ private static void hammerRecipe(Consumer writer, String name, Ingredient block, ItemLike result) {
+ hammerRecipe(writer, name, block, result, ConstantValue.exactly(1f));
}
- private static void hammerRecipe(Consumer consumer, String name, ItemLike block, Reward... rewards) {
- hammerRecipe(consumer, name, Ingredient.of(block), ImmutableList.builder().add(rewards).build());
- }
-
- private static void hammerRecipe(Consumer consumer, TagKey
- tag, Reward rewards) {
- consumer.accept(new FinishedHammerRecipe(ERecipeSerializers.HAMMER.get(), new ResourceLocation(ExNihiloReborn.ID, tag.location().getPath() + "_to_" + ForgeRegistries.ITEMS.getKey(rewards.getItem().getItem()).getPath()), Ingredient.of(tag), ImmutableList.of(rewards)));
+ private static void hammerRecipe(Consumer consumer, String name, Ingredient block, ItemLike result, NumberProvider resultAmount) {
+ consumer.accept(new FinishedHammerRecipe(new ResourceLocation(ExNihiloReborn.ID, "hammer/" + name), block, result.asItem(), resultAmount));
}
private static void barrelCompostRecipes(Consumer writer) {
@@ -264,7 +314,25 @@ class Recipes {
barrelCompost(writer, "pumpkin_pie", Ingredient.of(Items.PUMPKIN_PIE), 150);
}
- private static void barrelCompost(Consumer consumer, String id, Ingredient ingredient, int volume) {
- consumer.accept(new FinishedBarrelCompostRecipe(new ResourceLocation(ExNihiloReborn.ID, "barrel_compost/" + id), ingredient, volume));
+ private static void barrelCompost(Consumer writer, String id, Ingredient ingredient, int volume) {
+ writer.accept(new FinishedBarrelCompostRecipe(new ResourceLocation(ExNihiloReborn.ID, "barrel_compost/" + id), ingredient, volume));
+ }
+
+ private static void barrelMixingRecipes(Consumer writer) {
+ barrelMixing(writer, Ingredient.of(Items.MILK_BUCKET), ForgeMod.WATER_TYPE, Items.SLIME_BLOCK);
+ barrelMixing(writer, Ingredient.of(Items.SNOWBALL), ForgeMod.WATER_TYPE, Items.ICE);
+ barrelMixing(writer, Ingredient.of(Items.SAND), EFluids.WITCH_WATER_TYPE, Items.SOUL_SAND);
+ barrelMixing(writer, Ingredient.of(Items.REDSTONE), ForgeMod.LAVA_TYPE, Items.NETHERRACK);
+ barrelMixing(writer, Ingredient.of(Items.GLOWSTONE_DUST), ForgeMod.LAVA_TYPE, Items.END_STONE);
+ barrelMixing(writer, Ingredient.of(Items.WATER_BUCKET), ForgeMod.LAVA_TYPE, Items.OBSIDIAN);
+ barrelMixing(writer, Ingredient.of(Items.LAVA_BUCKET), ForgeMod.WATER_TYPE, Items.STONE);
+ }
+
+ private static void barrelMixing(Consumer writer, Ingredient ingredient, Supplier fluidType, Item result) {
+ writer.accept(new FinishedBarrelMixingRecipe(new ResourceLocation(ExNihiloReborn.ID, "barrel_mixing/" + path(result)), ingredient, fluidType.get(), 1000, result));
+ }
+
+ private static String path(Item item) {
+ return Objects.requireNonNull(ForgeRegistries.ITEMS.getKey(item).getPath());
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/StructureTags.java b/src/main/java/thedarkcolour/exnihiloreborn/data/StructureTags.java
deleted file mode 100644
index 25aa71d2..00000000
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/StructureTags.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package thedarkcolour.exnihiloreborn.data;
-
-import net.minecraft.core.HolderLookup;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.data.PackOutput;
-import net.minecraft.data.tags.StructureTagsProvider;
-import net.minecraft.data.tags.TagsProvider;
-import net.minecraft.data.worldgen.StructureSets;
-import net.minecraft.world.level.levelgen.structure.BuiltinStructureSets;
-import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
-import net.minecraft.world.level.levelgen.structure.Structure;
-import net.minecraft.world.level.levelgen.structure.StructureSet;
-import net.minecraftforge.common.data.ExistingFileHelper;
-import org.jetbrains.annotations.Nullable;
-import thedarkcolour.exnihiloreborn.ExNihiloReborn;
-import thedarkcolour.exnihiloreborn.tag.EStructureSetTags;
-
-import java.util.concurrent.CompletableFuture;
-
-class StructureTags extends TagsProvider {
- public StructureTags(PackOutput output, CompletableFuture lookup, @Nullable ExistingFileHelper helper) {
- super(output, Registries.STRUCTURE_SET, lookup, ExNihiloReborn.ID, helper);
- }
-
- @Override
- protected void addTags(HolderLookup.Provider lookup) {
- tag(EStructureSetTags.OVERWORLD_VOID_STRUCTURES);
- tag(EStructureSetTags.THE_NETHER_VOID_STRUCTURES).add(BuiltinStructureSets.NETHER_COMPLEXES);
- tag(EStructureSetTags.THE_END_VOID_STRUCTURES);
- }
-}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/TranslationKeys.java b/src/main/java/thedarkcolour/exnihiloreborn/data/TranslationKeys.java
index 55a8da91..8ca8906d 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/TranslationKeys.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/data/TranslationKeys.java
@@ -18,14 +18,19 @@ public class TranslationKeys {
public static final String STRING_MESH_ADVANCEMENT_TITLE = "advancements." + ExNihiloReborn.ID + ".core.string_mesh.title";
public static final String STRING_MESH_ADVANCEMENT_DESCRIPTION = "advancements." + ExNihiloReborn.ID + ".core.string_mesh.description";
- // JEI
+ // JEI descriptions
public static final String SILK_WORM_JEI_INFO = "info." + ExNihiloReborn.ID + ".silk_worm";
+ public static final String SIEVE_JEI_INFO = "info." + ExNihiloReborn.ID + ".sieve";
+
+ // JEI recipe categories
public static final String BARREL_COMPOST_CATEGORY_TITLE = "gui." + ExNihiloReborn.ID + ".category.barrel_compost";
public static final String BARREL_COMPOST_RECIPE_VOLUME = "gui." + ExNihiloReborn.ID + ".category.barrel_compost.volume";
public static final String WATER_CRUCIBLE_CATEGORY_TITLE = "gui." + ExNihiloReborn.ID + ".category.water_crucible";
public static final String LAVA_CRUCIBLE_CATEGORY_TITLE = "gui." + ExNihiloReborn.ID + ".category.lava_crucible";
public static final String HAMMER_CATEGORY_TITLE = "gui." + ExNihiloReborn.ID + ".category.hammer";
- public static final String COMPRESSED_HAMMER_CATEGORY_TITLE = "gui." + ExNihiloReborn.ID + ".category.compressed_hammer";
public static final String SIEVE_CATEGORY_TITLE = "gui." + ExNihiloReborn.ID + ".category.sieve";
- public static final String COMPRESSED_SIEVE_CATEGORY_TITLE = "gui." + ExNihiloReborn.ID + ".category.compressed_sieve";
+ public static final String SIEVE_RECIPE_CHANCE = "gui." + ExNihiloReborn.ID + ".category.sieve.chance";
+ public static final String SIEVE_RECIPE_AVERAGE_OUTPUT = "gui." + ExNihiloReborn.ID + ".category.sieve.average_output";
+ public static final String SIEVE_RECIPE_MIN_OUTPUT = "gui." + ExNihiloReborn.ID + ".category.sieve.min_output";
+ public static final String SIEVE_RECIPE_MAX_OUTPUT = "gui." + ExNihiloReborn.ID + ".category.sieve.max_output";
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/data/WorldPresetTags.java b/src/main/java/thedarkcolour/exnihiloreborn/data/WorldPresetTags.java
deleted file mode 100644
index d6a19ce8..00000000
--- a/src/main/java/thedarkcolour/exnihiloreborn/data/WorldPresetTags.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package thedarkcolour.exnihiloreborn.data;
-
-import net.minecraft.core.HolderLookup;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.data.PackOutput;
-import net.minecraft.data.tags.WorldPresetTagsProvider;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraftforge.common.data.ExistingFileHelper;
-import org.jetbrains.annotations.Nullable;
-import thedarkcolour.exnihiloreborn.ExNihiloReborn;
-
-import java.util.concurrent.CompletableFuture;
-
-public class WorldPresetTags extends WorldPresetTagsProvider {
- public WorldPresetTags(PackOutput output, CompletableFuture lookup, @Nullable ExistingFileHelper helper) {
- super(output, lookup, ExNihiloReborn.ID, helper);
- }
-
- @Override
- protected void addTags(HolderLookup.Provider lookup) {
- tag(net.minecraft.tags.WorldPresetTags.NORMAL).add(ResourceKey.create(Registries.WORLD_PRESET, new ResourceLocation(ExNihiloReborn.ID, "void_world")));
- }
-}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/event/EventHandler.java b/src/main/java/thedarkcolour/exnihiloreborn/event/EventHandler.java
index 6d07292f..ac11dc69 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/event/EventHandler.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/event/EventHandler.java
@@ -21,8 +21,7 @@ import net.minecraftforge.fml.InterModComms;
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import thedarkcolour.exnihiloreborn.ExNihiloReborn;
-import thedarkcolour.exnihiloreborn.blockentity.LavaCrucibleBlockEntity;
-import thedarkcolour.exnihiloreborn.blockentity.WaterCrucibleBlockEntity;
+import thedarkcolour.exnihiloreborn.recipe.RecipeUtil;
import thedarkcolour.exnihiloreborn.client.CompostColors;
import thedarkcolour.exnihiloreborn.voidworld.VoidChunkGenerator;
import thedarkcolour.exnihiloreborn.compat.top.TopCompatExNihiloReborn;
@@ -99,13 +98,12 @@ public final class EventHandler {
InterModComms.sendTo("theoneprobe", "getTheOneProbe", TopCompatExNihiloReborn::new);
}
- public static void addReloadListeners(AddReloadListenerEvent event) {
+ private static void addReloadListeners(AddReloadListenerEvent event) {
var recipes = event.getServerResources().getRecipeManager();
event.addListener((prepBarrier, resourceManager, prepProfiler, reloadProfiler, backgroundExecutor, gameExecutor) -> {
return CompletableFuture.allOf().thenCompose(prepBarrier::wait).thenRunAsync(() -> {
- LavaCrucibleBlockEntity.RECIPES_CACHE.invalidateAll();
- WaterCrucibleBlockEntity.RECIPES_CACHE.invalidateAll();
HammerItem.refreshValidBlocks(recipes);
+ RecipeUtil.reload(recipes);
}, gameExecutor);
});
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/fluid/WitchWaterFluid.java b/src/main/java/thedarkcolour/exnihiloreborn/fluid/WitchWaterFluid.java
index 83bd2b27..a83eef92 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/fluid/WitchWaterFluid.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/fluid/WitchWaterFluid.java
@@ -19,7 +19,7 @@ public class WitchWaterFluid extends FluidType {
private static final ResourceLocation OVERLAY_TEXTURE = new ResourceLocation("block/water_overlay");
public static ForgeFlowingFluid.Properties properties() {
- return new ForgeFlowingFluid.Properties(EFluids.WITCH_WATER, EFluids.WITCH_WATER_STILL, EFluids.WITCH_WATER_FLOWING).block(EBlocks.WITCH_WATER).bucket(EItems.WITCH_WATER_BUCKET);
+ return new ForgeFlowingFluid.Properties(EFluids.WITCH_WATER_TYPE, EFluids.WITCH_WATER_STILL, EFluids.WITCH_WATER_FLOWING).block(EBlocks.WITCH_WATER).bucket(EItems.WITCH_WATER_BUCKET);
}
public WitchWaterFluid() {
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/item/GrassSpreaderItem.java b/src/main/java/thedarkcolour/exnihiloreborn/item/GrassSpreaderItem.java
new file mode 100644
index 00000000..f375d9a1
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/item/GrassSpreaderItem.java
@@ -0,0 +1,42 @@
+package thedarkcolour.exnihiloreborn.item;
+
+import net.minecraft.world.InteractionResult;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.context.UseOnContext;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.block.state.BlockState;
+
+import java.util.function.Supplier;
+
+public class GrassSpreaderItem extends Item {
+ private final Supplier grassState;
+
+ public GrassSpreaderItem(Properties pProperties, Supplier grassState) {
+ super(pProperties);
+ this.grassState = grassState;
+ }
+
+ @Override
+ public InteractionResult useOn(UseOnContext ctx) {
+ var level = ctx.getLevel();
+ var pos = ctx.getClickedPos();
+ var player = ctx.getPlayer();
+
+ if (level.getBlockState(pos).is(Blocks.DIRT)) {
+ if (!level.isClientSide) {
+ level.setBlock(pos, grassState.get(), 3);
+
+ return InteractionResult.CONSUME;
+ }
+
+ // apparently shrinking is done on both sides?
+ if (player == null || !player.getAbilities().instabuild) {
+ ctx.getItemInHand().shrink(1);
+ }
+
+ return InteractionResult.SUCCESS;
+ }
+
+ return InteractionResult.PASS;
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/item/HammerItem.java b/src/main/java/thedarkcolour/exnihiloreborn/item/HammerItem.java
index 7631cb58..776d9228 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/item/HammerItem.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/item/HammerItem.java
@@ -24,6 +24,7 @@ public class HammerItem extends DiggerItem {
}
public static void refreshValidBlocks(RecipeManager recipes) {
+ VALID_BLOCKS.clear();
for (var recipe : recipes.byType(ERecipeTypes.HAMMER.get()).values()) {
for (var item : recipe.getIngredient().getItems()) {
if (item.getItem() instanceof BlockItem blockItem) {
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/item/MeshItem.java b/src/main/java/thedarkcolour/exnihiloreborn/item/MeshItem.java
new file mode 100644
index 00000000..3cbeec1c
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/item/MeshItem.java
@@ -0,0 +1,17 @@
+package thedarkcolour.exnihiloreborn.item;
+
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.enchantment.Enchantment;
+import net.minecraft.world.item.enchantment.Enchantments;
+
+public class MeshItem extends Item {
+ public MeshItem(Properties properties) {
+ super(properties);
+ }
+
+ @Override
+ public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
+ return enchantment == Enchantments.BLOCK_EFFICIENCY || enchantment == Enchantments.BLOCK_FORTUNE;
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/loot/HammerLootModifier.java b/src/main/java/thedarkcolour/exnihiloreborn/loot/HammerLootModifier.java
index 98fc0d83..e451590f 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/loot/HammerLootModifier.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/loot/HammerLootModifier.java
@@ -6,25 +6,20 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
-import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraftforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.common.loot.LootModifier;
-import net.minecraftforge.registries.ForgeRegistries;
-import thedarkcolour.exnihiloreborn.recipe.RewardRecipe;
+import thedarkcolour.exnihiloreborn.registry.ERecipeTypes;
import javax.annotation.Nonnull;
public class HammerLootModifier extends LootModifier {
- public static final Codec CODEC = RecordCodecBuilder.create(inst -> LootModifier.codecStart(inst).and(ForgeRegistries.RECIPE_TYPES.getCodec().fieldOf("reward_recipe_type").forGetter(modifier -> modifier.type)).apply(inst, HammerLootModifier::new));
- private final RecipeType extends RewardRecipe> type;
+ public static final Codec CODEC = RecordCodecBuilder.create(inst -> LootModifier.codecStart(inst).apply(inst, HammerLootModifier::new));
- @SuppressWarnings("unchecked")
- protected HammerLootModifier(LootItemCondition[] conditionsIn, RecipeType> type) {
+ protected HammerLootModifier(LootItemCondition[] conditionsIn) {
super(conditionsIn);
- this.type = (RecipeType extends RewardRecipe>) type;
}
@Nonnull
@@ -35,18 +30,15 @@ public class HammerLootModifier extends LootModifier {
if (state != null && state.getBlock().asItem() != Items.AIR) {
var temporaryItem = new SimpleContainer(new ItemStack(state.getBlock().asItem()));
- var recipe = level.getRecipeManager().getRecipeFor(type, temporaryItem, level);
+ var recipe = level.getRecipeManager().getRecipeFor(ERecipeTypes.HAMMER.get(), temporaryItem, level);
if (recipe.isPresent()) {
- var rand = level.random;
ObjectArrayList newLoot = new ObjectArrayList<>();
+ var resultAmount = recipe.get().resultAmount.getInt(context);
- for (var reward : recipe.get().getRewards()) {
- if (rand.nextFloat() < reward.getChance()) {
- newLoot.add(reward.getItem().copy());
- }
+ if (resultAmount > 0) {
+ newLoot.add(new ItemStack(recipe.get().result, resultAmount));
}
-
return newLoot;
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/network/ClientMessageHandler.java b/src/main/java/thedarkcolour/exnihiloreborn/network/ClientMessageHandler.java
index f72c1eaf..172e2cdc 100644
--- a/src/main/java/thedarkcolour/exnihiloreborn/network/ClientMessageHandler.java
+++ b/src/main/java/thedarkcolour/exnihiloreborn/network/ClientMessageHandler.java
@@ -1,53 +1,17 @@
package thedarkcolour.exnihiloreborn.network;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.multiplayer.ClientLevel;
-import net.minecraftforge.fml.unsafe.UnsafeHacks;
-import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
-import sun.misc.Unsafe;
-import thedarkcolour.exnihiloreborn.ExNihiloReborn;
-
-import java.lang.reflect.Field;
public class ClientMessageHandler {
- private static final Field CLIENT_LEVEL_DATA_FIELD;
- private static final Field IS_FLAT_FIELD;
- private static final boolean PATCH_VOID;
- private static final Unsafe UNSAFE;
-
public static boolean isInVoidWorld;
- static {
- Field clientLevelDataField = null;
- Field isFlatField = null;
- Unsafe unsafe = null;
-
- try {
- clientLevelDataField = ObfuscationReflectionHelper.findField(ClientLevel.class, "f_104563_");
- isFlatField = ObfuscationReflectionHelper.findField(ClientLevel.ClientLevelData.class, "f_104832_");
-
- // copied from UnsafeHacks
- final Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
- theUnsafe.setAccessible(true);
- unsafe = (Unsafe)theUnsafe.get(null);
- } catch (Exception e) {
- e.printStackTrace();
- ExNihiloReborn.LOGGER.error("Error: Could not patch void renderer. Please open an issue on ExNihiloReborn GitHub!");
- }
- CLIENT_LEVEL_DATA_FIELD = clientLevelDataField;
- IS_FLAT_FIELD = isFlatField;
- UNSAFE = unsafe;
- PATCH_VOID = CLIENT_LEVEL_DATA_FIELD != null && IS_FLAT_FIELD != null && UNSAFE != null;
- }
-
// Removes the black sky/fog that appears when the player is below y=62
public static void disableVoidFogRendering() {
isInVoidWorld = true;
- if (PATCH_VOID) {
- var obj = UnsafeHacks.getField(CLIENT_LEVEL_DATA_FIELD, Minecraft.getInstance().level);
- long offset = UNSAFE.objectFieldOffset(IS_FLAT_FIELD);
- UNSAFE.putBoolean(obj, offset, true);
+ var level = Minecraft.getInstance().level;
+ if (level != null) {
+ level.clientLevelData.isFlat = true;
}
}
}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/recipe/EFinishedRecipe.java b/src/main/java/thedarkcolour/exnihiloreborn/recipe/EFinishedRecipe.java
new file mode 100644
index 00000000..bd3968b1
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/recipe/EFinishedRecipe.java
@@ -0,0 +1,20 @@
+package thedarkcolour.exnihiloreborn.recipe;
+
+import com.google.gson.JsonObject;
+import net.minecraft.data.recipes.FinishedRecipe;
+import net.minecraft.resources.ResourceLocation;
+import org.jetbrains.annotations.Nullable;
+
+public interface EFinishedRecipe extends FinishedRecipe {
+ @Nullable
+ @Override
+ default JsonObject serializeAdvancement() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ default ResourceLocation getAdvancementId() {
+ return null;
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/recipe/ProbabilityRecipe.java b/src/main/java/thedarkcolour/exnihiloreborn/recipe/ProbabilityRecipe.java
new file mode 100644
index 00000000..1ca7f03c
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/recipe/ProbabilityRecipe.java
@@ -0,0 +1,20 @@
+package thedarkcolour.exnihiloreborn.recipe;
+
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.crafting.Ingredient;
+import net.minecraft.world.level.storage.loot.LootContext;
+import net.minecraft.world.level.storage.loot.LootParams;
+import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
+
+public abstract class ProbabilityRecipe extends SingleIngredientRecipe {
+ public final Item result;
+ public final NumberProvider resultAmount;
+
+ public ProbabilityRecipe(ResourceLocation id, Ingredient ingredient, Item result, NumberProvider resultAmount) {
+ super(id, ingredient);
+ this.result = result;
+ this.resultAmount = resultAmount;
+ }
+}
diff --git a/src/main/java/thedarkcolour/exnihiloreborn/recipe/RecipeUtil.java b/src/main/java/thedarkcolour/exnihiloreborn/recipe/RecipeUtil.java
new file mode 100644
index 00000000..a97dfd90
--- /dev/null
+++ b/src/main/java/thedarkcolour/exnihiloreborn/recipe/RecipeUtil.java
@@ -0,0 +1,260 @@
+package thedarkcolour.exnihiloreborn.recipe;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.gson.JsonObject;
+import net.minecraft.network.FriendlyByteBuf;
+import net.minecraft.resources.ResourceLocation;
+import net.minecraft.util.GsonHelper;
+import net.minecraft.world.Container;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.crafting.Ingredient;
+import net.minecraft.world.item.crafting.Recipe;
+import net.minecraft.world.item.crafting.RecipeManager;
+import net.minecraft.world.item.crafting.RecipeType;
+import net.minecraft.world.level.storage.loot.LootDataType;
+import net.minecraft.world.level.storage.loot.providers.number.BinomialDistributionGenerator;
+import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
+import net.minecraft.world.level.storage.loot.providers.number.NumberProvider;
+import net.minecraft.world.level.storage.loot.providers.number.NumberProviders;
+import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
+import net.minecraftforge.common.util.Lazy;
+import net.minecraftforge.fluids.FluidStack;
+import net.minecraftforge.registries.ForgeRegistries;
+import org.jetbrains.annotations.Nullable;
+import thedarkcolour.exnihiloreborn.recipe.barrel.BarrelCompostRecipe;
+import thedarkcolour.exnihiloreborn.recipe.barrel.BarrelMixingRecipe;
+import thedarkcolour.exnihiloreborn.recipe.crucible.CrucibleRecipe;
+import thedarkcolour.exnihiloreborn.recipe.sieve.SieveRecipe;
+import thedarkcolour.exnihiloreborn.registry.ERecipeTypes;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
+public final class RecipeUtil {
+ private static final int CONSTANT_TYPE = 1;
+ private static final int UNIFORM_TYPE = 2;
+ private static final int BINOMIAL_TYPE = 3;
+ private static final int UNKNOWN_TYPE = 99;
+
+ private static final Cache> SIEVE_RECIPE_CACHE = CacheBuilder.newBuilder().expireAfterAccess(Duration.ofMinutes(3)).build();
+ private static Lazy